Jack2 1.9.6
|
00001 /* 00002 Copyright (C) 2001 Paul Davis 00003 Copyright (C) 2008 Romain Moret at Grame 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program; if not, write to the Free Software 00017 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00018 */ 00019 00020 #include "JackNetInterface.h" 00021 #include "JackException.h" 00022 #include "JackPlatformPlug.h" 00023 #include <assert.h> 00024 00025 using namespace std; 00026 00027 /* 00028 TODO : since midi buffers now uses up to BUFFER_SIZE_MAX frames, 00029 probably also use BUFFER_SIZE_MAX in everything related to MIDI events 00030 handling (see MidiBufferInit in JackMidiPort.cpp) 00031 */ 00032 00033 namespace Jack 00034 { 00035 // JackNetInterface******************************************* 00036 00037 JackNetInterface::JackNetInterface() : fSocket() 00038 { 00039 fTxBuffer = NULL; 00040 fRxBuffer = NULL; 00041 fNetAudioCaptureBuffer = NULL; 00042 fNetAudioPlaybackBuffer = NULL; 00043 fNetMidiCaptureBuffer = NULL; 00044 fNetMidiPlaybackBuffer = NULL; 00045 memset(&fSendTransportData, 0, sizeof(net_transport_data_t)); 00046 memset(&fReturnTransportData, 0, sizeof(net_transport_data_t)); 00047 } 00048 00049 JackNetInterface::JackNetInterface ( const char* multicast_ip, int port ) : fSocket ( multicast_ip, port ) 00050 { 00051 strcpy(fMulticastIP, multicast_ip); 00052 fTxBuffer = NULL; 00053 fRxBuffer = NULL; 00054 fNetAudioCaptureBuffer = NULL; 00055 fNetAudioPlaybackBuffer = NULL; 00056 fNetMidiCaptureBuffer = NULL; 00057 fNetMidiPlaybackBuffer = NULL; 00058 memset(&fSendTransportData, 0, sizeof(net_transport_data_t)); 00059 memset(&fReturnTransportData, 0, sizeof(net_transport_data_t)); 00060 } 00061 00062 JackNetInterface::JackNetInterface ( session_params_t& params, JackNetSocket& socket, const char* multicast_ip ) : fSocket ( socket ) 00063 { 00064 fParams = params; 00065 strcpy(fMulticastIP, multicast_ip); 00066 fTxBuffer = NULL; 00067 fRxBuffer = NULL; 00068 fNetAudioCaptureBuffer = NULL; 00069 fNetAudioPlaybackBuffer = NULL; 00070 fNetMidiCaptureBuffer = NULL; 00071 fNetMidiPlaybackBuffer = NULL; 00072 memset(&fSendTransportData, 0, sizeof(net_transport_data_t)); 00073 memset(&fReturnTransportData, 0, sizeof(net_transport_data_t)); 00074 } 00075 00076 JackNetInterface::~JackNetInterface() 00077 { 00078 jack_log ( "JackNetInterface::~JackNetInterface" ); 00079 00080 fSocket.Close(); 00081 delete[] fTxBuffer; 00082 delete[] fRxBuffer; 00083 delete fNetAudioCaptureBuffer; 00084 delete fNetAudioPlaybackBuffer; 00085 delete fNetMidiCaptureBuffer; 00086 delete fNetMidiPlaybackBuffer; 00087 } 00088 00089 void JackNetInterface::SetFramesPerPacket() 00090 { 00091 jack_log ( "JackNetInterface::SetFramesPerPacket" ); 00092 00093 if (fParams.fSendAudioChannels == 0 && fParams.fReturnAudioChannels == 0) { 00094 fParams.fFramesPerPacket = fParams.fPeriodSize; 00095 } else { 00096 jack_nframes_t period = ( int ) powf ( 2.f, ( int ) ( log (float ( fParams.fMtu - sizeof ( packet_header_t ) ) 00097 / ( max ( fParams.fReturnAudioChannels, fParams.fSendAudioChannels ) * sizeof ( sample_t ) ) ) / log ( 2. ) ) ); 00098 fParams.fFramesPerPacket = ( period > fParams.fPeriodSize ) ? fParams.fPeriodSize : period; 00099 } 00100 } 00101 00102 int JackNetInterface::SetNetBufferSize() 00103 { 00104 jack_log ( "JackNetInterface::SetNetBufferSize" ); 00105 00106 float audio_size, midi_size; 00107 int bufsize; 00108 //audio 00109 audio_size = fParams.fMtu * ( fParams.fPeriodSize / fParams.fFramesPerPacket ); 00110 //midi 00111 midi_size = fParams.fMtu * ( max ( fParams.fSendMidiChannels, fParams.fReturnMidiChannels ) * 00112 fParams.fPeriodSize * sizeof ( sample_t ) / ( fParams.fMtu - sizeof ( packet_header_t ) ) ); 00113 //bufsize = sync + audio + midi 00114 bufsize = MAX_LATENCY * (fParams.fMtu + ( int ) audio_size + ( int ) midi_size); 00115 00116 //tx buffer 00117 if ( fSocket.SetOption ( SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof ( bufsize ) ) == SOCKET_ERROR ) 00118 return SOCKET_ERROR; 00119 00120 //rx buffer 00121 if ( fSocket.SetOption ( SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof ( bufsize ) ) == SOCKET_ERROR ) 00122 return SOCKET_ERROR; 00123 00124 return 0; 00125 } 00126 00127 int JackNetInterface::GetNMidiPckt() 00128 { 00129 //even if there is no midi data, jack need an empty buffer to know there is no event to read 00130 //99% of the cases : all data in one packet 00131 if ( fTxHeader.fMidiDataSize <= ( fParams.fMtu - sizeof ( packet_header_t ) ) ) 00132 return 1; 00133 //else, get the number of needed packets (simply slice the biiig buffer) 00134 int npckt = fTxHeader.fMidiDataSize / ( fParams.fMtu - sizeof ( packet_header_t ) ); 00135 if ( fTxHeader.fMidiDataSize % ( fParams.fMtu - sizeof ( packet_header_t ) ) ) 00136 return ++npckt; 00137 return npckt; 00138 } 00139 00140 bool JackNetInterface::IsNextPacket() 00141 { 00142 packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer ); 00143 //ignore first cycle 00144 if ( fRxHeader.fCycle <= 1 ) { 00145 return true; 00146 } 00147 //same PcktID (cycle), next SubPcktID (subcycle) 00148 if ( ( fRxHeader.fSubCycle < ( fNSubProcess - 1 ) ) && ( rx_head->fCycle == fRxHeader.fCycle ) && ( rx_head->fSubCycle == ( fRxHeader.fSubCycle + 1 ) ) ) { 00149 return true; 00150 } 00151 //next PcktID (cycle), SubPcktID reset to 0 (first subcyle) 00152 if ( ( rx_head->fCycle == ( fRxHeader.fCycle + 1 ) ) && ( fRxHeader.fSubCycle == ( fNSubProcess - 1 ) ) && ( rx_head->fSubCycle == 0 ) ) { 00153 return true; 00154 } 00155 //else, packet(s) missing, return false 00156 return false; 00157 } 00158 00159 void JackNetInterface::SetParams() 00160 { 00161 //number of audio subcycles (packets) 00162 fNSubProcess = fParams.fPeriodSize / fParams.fFramesPerPacket; 00163 00164 //payload size 00165 fPayloadSize = fParams.fMtu - sizeof ( packet_header_t ); 00166 00167 //TX header init 00168 strcpy ( fTxHeader.fPacketType, "header" ); 00169 fTxHeader.fID = fParams.fID; 00170 fTxHeader.fCycle = 0; 00171 fTxHeader.fSubCycle = 0; 00172 fTxHeader.fMidiDataSize = 0; 00173 fTxHeader.fBitdepth = fParams.fBitdepth; 00174 fTxHeader.fIsLastPckt = 0; 00175 00176 //RX header init 00177 strcpy ( fRxHeader.fPacketType, "header" ); 00178 fRxHeader.fID = fParams.fID; 00179 fRxHeader.fCycle = 0; 00180 fRxHeader.fSubCycle = 0; 00181 fRxHeader.fMidiDataSize = 0; 00182 fRxHeader.fBitdepth = fParams.fBitdepth; 00183 fRxHeader.fIsLastPckt = 0; 00184 00185 //network buffers 00186 fTxBuffer = new char[fParams.fMtu]; 00187 fRxBuffer = new char[fParams.fMtu]; 00188 assert ( fTxBuffer ); 00189 assert ( fRxBuffer ); 00190 00191 //net audio/midi buffers'addresses 00192 fTxData = fTxBuffer + sizeof ( packet_header_t ); 00193 fRxData = fRxBuffer + sizeof ( packet_header_t ); 00194 } 00195 00196 // JackNetMasterInterface ************************************************************************************ 00197 00198 bool JackNetMasterInterface::Init() 00199 { 00200 jack_log ( "JackNetMasterInterface::Init, ID %u.", fParams.fID ); 00201 00202 session_params_t host_params; 00203 uint attempt = 0; 00204 int rx_bytes = 0; 00205 00206 //socket 00207 if ( fSocket.NewSocket() == SOCKET_ERROR ) { 00208 jack_error ( "Can't create socket : %s", StrError ( NET_ERROR_CODE ) ); 00209 return false; 00210 } 00211 00212 //timeout on receive (for init) 00213 if ( fSocket.SetTimeOut ( MASTER_INIT_TIMEOUT ) < 0 ) 00214 jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) ); 00215 00216 //connect 00217 if ( fSocket.Connect() == SOCKET_ERROR ) { 00218 jack_error ( "Can't connect : %s", StrError ( NET_ERROR_CODE ) ); 00219 return false; 00220 } 00221 00222 //set the number of complete audio frames we can put in a packet 00223 SetFramesPerPacket(); 00224 00225 //send 'SLAVE_SETUP' until 'START_MASTER' received 00226 jack_info ( "Sending parameters to %s ...", fParams.fSlaveNetName ); 00227 do 00228 { 00229 session_params_t net_params; 00230 memset(&net_params, 0, sizeof ( session_params_t )); 00231 SetPacketType ( &fParams, SLAVE_SETUP ); 00232 SessionParamsHToN(&fParams, &net_params); 00233 00234 if ( fSocket.Send ( &net_params, sizeof ( session_params_t ), 0 ) == SOCKET_ERROR ) 00235 jack_error ( "Error in send : ", StrError ( NET_ERROR_CODE ) ); 00236 00237 memset(&net_params, 0, sizeof ( session_params_t )); 00238 if ( ( ( rx_bytes = fSocket.Recv ( &net_params, sizeof ( session_params_t ), 0 ) ) == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) ) 00239 { 00240 jack_error ( "Problem with network." ); 00241 return false; 00242 } 00243 00244 SessionParamsNToH(&net_params, &host_params); 00245 } 00246 while ( ( GetPacketType ( &host_params ) != START_MASTER ) && ( ++attempt < SLAVE_SETUP_RETRY ) ); 00247 if ( attempt == SLAVE_SETUP_RETRY ) { 00248 jack_error ( "Slave doesn't respond, exiting." ); 00249 return false; 00250 } 00251 00252 //set the new timeout for the socket 00253 if ( SetRxTimeout() == SOCKET_ERROR ) { 00254 jack_error ( "Can't set rx timeout : %s", StrError ( NET_ERROR_CODE ) ); 00255 return false; 00256 } 00257 00258 //set the new rx buffer size 00259 if ( SetNetBufferSize() == SOCKET_ERROR ) { 00260 jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) ); 00261 return false; 00262 } 00263 00264 return true; 00265 } 00266 00267 int JackNetMasterInterface::SetRxTimeout() 00268 { 00269 jack_log ( "JackNetMasterInterface::SetRxTimeout" ); 00270 00271 float time = 0; 00272 //slow or normal mode, short timeout on recv (2 audio subcycles) 00273 if ( ( fParams.fNetworkMode == 's' ) || ( fParams.fNetworkMode == 'n' ) ) 00274 time = 2000000.f * ( static_cast<float> ( fParams.fFramesPerPacket ) / static_cast<float> ( fParams.fSampleRate ) ); 00275 //fast mode, wait for 75% of the entire cycle duration 00276 else if ( fParams.fNetworkMode == 'f' ) 00277 time = 750000.f * ( static_cast<float> ( fParams.fPeriodSize ) / static_cast<float> ( fParams.fSampleRate ) ); 00278 return fSocket.SetTimeOut ( static_cast<int> ( time ) ); 00279 } 00280 00281 void JackNetMasterInterface::SetParams() 00282 { 00283 jack_log ( "JackNetMasterInterface::SetParams" ); 00284 00285 JackNetInterface::SetParams(); 00286 00287 fTxHeader.fDataStream = 's'; 00288 fRxHeader.fDataStream = 'r'; 00289 00290 //midi net buffers 00291 fNetMidiCaptureBuffer = new NetMidiBuffer ( &fParams, fParams.fSendMidiChannels, fTxData ); 00292 fNetMidiPlaybackBuffer = new NetMidiBuffer ( &fParams, fParams.fReturnMidiChannels, fRxData ); 00293 assert ( fNetMidiCaptureBuffer ); 00294 assert ( fNetMidiPlaybackBuffer ); 00295 00296 //audio net buffers 00297 fNetAudioCaptureBuffer = new NetAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); 00298 fNetAudioPlaybackBuffer = new NetAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); 00299 assert ( fNetAudioCaptureBuffer ); 00300 assert ( fNetAudioPlaybackBuffer ); 00301 00302 //audio netbuffer length 00303 fAudioTxLen = sizeof ( packet_header_t ) + fNetAudioCaptureBuffer->GetSize(); 00304 fAudioRxLen = sizeof ( packet_header_t ) + fNetAudioPlaybackBuffer->GetSize(); 00305 } 00306 00307 void JackNetMasterInterface::Exit() 00308 { 00309 jack_log ( "JackNetMasterInterface::Exit, ID %u", fParams.fID ); 00310 00311 //stop process 00312 fRunning = false; 00313 00314 //send a 'multicast euthanasia request' - new socket is required on macosx 00315 jack_info ( "Exiting '%s'", fParams.fName ); 00316 SetPacketType ( &fParams, KILL_MASTER ); 00317 JackNetSocket mcast_socket ( fMulticastIP, fSocket.GetPort() ); 00318 00319 session_params_t net_params; 00320 memset(&net_params, 0, sizeof ( session_params_t )); 00321 SessionParamsHToN(&fParams, &net_params); 00322 00323 if ( mcast_socket.NewSocket() == SOCKET_ERROR ) 00324 jack_error ( "Can't create socket : %s", StrError ( NET_ERROR_CODE ) ); 00325 if ( mcast_socket.SendTo ( &net_params, sizeof ( session_params_t ), 0, fMulticastIP ) == SOCKET_ERROR ) 00326 jack_error ( "Can't send suicide request : %s", StrError ( NET_ERROR_CODE ) ); 00327 00328 mcast_socket.Close(); 00329 } 00330 00331 int JackNetMasterInterface::Recv ( size_t size, int flags ) 00332 { 00333 int rx_bytes; 00334 if ( ( ( rx_bytes = fSocket.Recv ( fRxBuffer, size, flags ) ) == SOCKET_ERROR ) && fRunning ) 00335 { 00336 net_error_t error = fSocket.GetError(); 00337 //no data isn't really a network error, so just return 0 avalaible read bytes 00338 if ( error == NET_NO_DATA ) 00339 return 0; 00340 else if ( error == NET_CONN_ERROR ) 00341 { 00342 //fatal connection issue, exit 00343 jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError ( NET_ERROR_CODE ) ); 00344 //ask to the manager to properly remove the master 00345 Exit(); 00346 00347 // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine. 00348 ThreadExit(); 00349 } 00350 else 00351 jack_error ( "Error in master receive : %s", StrError ( NET_ERROR_CODE ) ); 00352 } 00353 00354 packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer); 00355 PacketHeaderNToH(header, header); 00356 return rx_bytes; 00357 } 00358 00359 int JackNetMasterInterface::Send ( size_t size, int flags ) 00360 { 00361 int tx_bytes; 00362 packet_header_t* header = reinterpret_cast<packet_header_t*>(fTxBuffer); 00363 PacketHeaderHToN(header, header); 00364 00365 if ( ( ( tx_bytes = fSocket.Send ( fTxBuffer, size, flags ) ) == SOCKET_ERROR ) && fRunning ) 00366 { 00367 net_error_t error = fSocket.GetError(); 00368 if ( error == NET_CONN_ERROR ) 00369 { 00370 //fatal connection issue, exit 00371 jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError ( NET_ERROR_CODE ) ); 00372 Exit(); 00373 00374 // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine. 00375 ThreadExit(); 00376 } 00377 else 00378 jack_error ( "Error in master send : %s", StrError ( NET_ERROR_CODE ) ); 00379 } 00380 return tx_bytes; 00381 } 00382 00383 bool JackNetMasterInterface::IsSynched() 00384 { 00385 if (fParams.fNetworkMode == 's') { 00386 return (fCycleOffset < 3); 00387 } else { 00388 return true; 00389 } 00390 } 00391 00392 int JackNetMasterInterface::SyncSend() 00393 { 00394 fTxHeader.fCycle++; 00395 fTxHeader.fSubCycle = 0; 00396 fTxHeader.fDataType = 's'; 00397 fTxHeader.fIsLastPckt = ( fParams.fSendMidiChannels == 0 && fParams.fSendAudioChannels == 0) ? 1 : 0; 00398 fTxHeader.fPacketSize = fParams.fMtu; 00399 memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) ); 00400 return Send ( fTxHeader.fPacketSize, 0 ); 00401 } 00402 00403 int JackNetMasterInterface::DataSend() 00404 { 00405 uint subproc; 00406 //midi 00407 if ( fParams.fSendMidiChannels > 0) 00408 { 00409 //set global header fields and get the number of midi packets 00410 fTxHeader.fDataType = 'm'; 00411 fTxHeader.fMidiDataSize = fNetMidiCaptureBuffer->RenderFromJackPorts(); 00412 fTxHeader.fNMidiPckt = GetNMidiPckt(); 00413 for ( subproc = 0; subproc < fTxHeader.fNMidiPckt; subproc++ ) 00414 { 00415 fTxHeader.fSubCycle = subproc; 00416 fTxHeader.fIsLastPckt = ( ( subproc == ( fTxHeader.fNMidiPckt - 1 ) ) && (fParams.fSendAudioChannels == 0)) ? 1 : 0; 00417 fTxHeader.fPacketSize = sizeof ( packet_header_t ) + fNetMidiCaptureBuffer->RenderToNetwork ( subproc, fTxHeader.fMidiDataSize ); 00418 memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) ); 00419 if ( Send ( fTxHeader.fPacketSize, 0 ) == SOCKET_ERROR ) 00420 return SOCKET_ERROR; 00421 } 00422 } 00423 00424 //audio 00425 if ( fParams.fSendAudioChannels > 0) 00426 { 00427 fTxHeader.fDataType = 'a'; 00428 fTxHeader.fMidiDataSize = 0; 00429 fTxHeader.fNMidiPckt = 0; 00430 for ( subproc = 0; subproc < fNSubProcess; subproc++ ) 00431 { 00432 fTxHeader.fSubCycle = subproc; 00433 fTxHeader.fIsLastPckt = ( subproc == ( fNSubProcess - 1 ) ) ? 1 : 0; 00434 fTxHeader.fPacketSize = fAudioTxLen; 00435 memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) ); 00436 fNetAudioCaptureBuffer->RenderFromJackPorts ( subproc ); 00437 if ( Send ( fTxHeader.fPacketSize, 0 ) == SOCKET_ERROR ) 00438 return SOCKET_ERROR; 00439 } 00440 } 00441 00442 return 0; 00443 } 00444 00445 int JackNetMasterInterface::SyncRecv() 00446 { 00447 packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer ); 00448 int rx_bytes = Recv ( fParams.fMtu, MSG_PEEK ); 00449 00450 if ( ( rx_bytes == 0 ) || ( rx_bytes == SOCKET_ERROR ) ) 00451 return rx_bytes; 00452 00453 fCycleOffset = fTxHeader.fCycle - rx_head->fCycle; 00454 00455 switch ( fParams.fNetworkMode ) 00456 { 00457 case 's' : 00458 //slow mode : allow to use full bandwidth and heavy process on the slave 00459 // - extra latency is set to two cycles, one cycle for send/receive operations + one cycle for heavy process on the slave 00460 // - if the network is two fast, just wait the next cycle, this mode allows a shorter cycle duration for the master 00461 // - this mode will skip the two first cycles, thus it lets time for data to be processed and queued on the socket rx buffer 00462 //the slow mode is the safest mode because it wait twice the bandwidth relative time (send/return + process) 00463 if (fCycleOffset < 2) 00464 return 0; 00465 else 00466 rx_bytes = Recv ( rx_head->fPacketSize, 0 ); 00467 00468 if (fCycleOffset > 2) { 00469 jack_info("Warning : '%s' runs in slow network mode, but data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset); 00470 } 00471 break; 00472 00473 case 'n' : 00474 //normal use of the network : 00475 // - extra latency is set to one cycle, what is the time needed to receive streams using full network bandwidth 00476 // - if the network is too fast, just wait the next cycle, the benefit here is the master's cycle is shorter 00477 // - indeed, data is supposed to be on the network rx buffer, so we don't have to wait for it 00478 if (fCycleOffset < 1) 00479 return 0; 00480 else 00481 rx_bytes = Recv ( rx_head->fPacketSize, 0 ); 00482 00483 if (fCycleOffset != 1) 00484 jack_info("'%s' can't run in normal network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset); 00485 break; 00486 00487 case 'f' : 00488 //fast mode suppose the network bandwith is larger than required for the transmission (only a few channels for example) 00489 // - packets can be quickly received, quickly is here relative to the cycle duration 00490 // - here, receive data, we can't keep it queued on the rx buffer, 00491 // - but if there is a cycle offset, tell the user, that means we're not in fast mode anymore, network is too slow 00492 rx_bytes = Recv ( rx_head->fPacketSize, 0 ); 00493 00494 if (fCycleOffset != 0) 00495 jack_info("'%s' can't run in fast network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset); 00496 break; 00497 } 00498 00499 fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; 00500 return rx_bytes; 00501 } 00502 00503 int JackNetMasterInterface::DataRecv() 00504 { 00505 int rx_bytes = 0; 00506 uint jumpcnt = 0; 00507 uint recvd_midi_pckt = 0; 00508 uint recvd_audio_pckt = 0; 00509 packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer ); 00510 00511 while ( !fRxHeader.fIsLastPckt ) 00512 { 00513 //how much data is queued on the rx buffer ? 00514 rx_bytes = Recv ( fParams.fMtu, MSG_PEEK ); 00515 00516 if ( rx_bytes == SOCKET_ERROR ) 00517 return rx_bytes; 00518 //if no data 00519 if ( ( rx_bytes == 0 ) && ( ++jumpcnt == fNSubProcess ) ) 00520 { 00521 jack_error ( "No data from %s...", fParams.fName ); 00522 jumpcnt = 0; 00523 } 00524 //else if data is valid, 00525 if ( rx_bytes && ( rx_head->fDataStream == 'r' ) && ( rx_head->fID == fParams.fID ) ) 00526 { 00527 //read data 00528 switch ( rx_head->fDataType ) 00529 { 00530 case 'm': //midi 00531 rx_bytes = Recv ( rx_head->fPacketSize, 0 ); 00532 fRxHeader.fCycle = rx_head->fCycle; 00533 fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; 00534 fNetMidiPlaybackBuffer->RenderFromNetwork ( rx_head->fSubCycle, rx_bytes - sizeof ( packet_header_t ) ); 00535 if ( ++recvd_midi_pckt == rx_head->fNMidiPckt ) 00536 fNetMidiPlaybackBuffer->RenderToJackPorts(); 00537 jumpcnt = 0; 00538 break; 00539 00540 case 'a': //audio 00541 rx_bytes = Recv ( rx_head->fPacketSize, 0 ); 00542 // SL: 25/01/09 00543 // if ( !IsNextPacket() ) 00544 // jack_error ( "Packet(s) missing from '%s'...", fParams.fName ); 00545 if (recvd_audio_pckt++ != rx_head->fSubCycle) { 00546 jack_error("Packet(s) missing from '%s'...", fParams.fSlaveNetName); 00547 } 00548 fRxHeader.fCycle = rx_head->fCycle; 00549 fRxHeader.fSubCycle = rx_head->fSubCycle; 00550 fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; 00551 fNetAudioPlaybackBuffer->RenderToJackPorts ( rx_head->fSubCycle ); 00552 jumpcnt = 0; 00553 break; 00554 00555 case 's': //sync 00556 /* SL: 25/01/09 00557 if ( rx_head->fCycle == fTxHeader.fCycle ) 00558 return 0; 00559 */ 00560 jack_info("NetMaster : overloaded, skipping receive from '%s'", fParams.fName); 00561 return 0; 00562 } 00563 } 00564 } 00565 return rx_bytes; 00566 } 00567 00568 void JackNetMasterInterface::EncodeSyncPacket() 00569 { 00570 //this method contains every step of sync packet informations coding 00571 //first of all, reset sync packet 00572 memset ( fTxData, 0, fPayloadSize ); 00573 00574 //then, first step : transport 00575 if (fParams.fTransportSync) { 00576 EncodeTransportData(); 00577 TransportDataHToN( &fSendTransportData, &fSendTransportData); 00578 //copy to TxBuffer 00579 memcpy ( fTxData, &fSendTransportData, sizeof ( net_transport_data_t ) ); 00580 } 00581 //then others (freewheel etc.) 00582 //... 00583 } 00584 00585 void JackNetMasterInterface::DecodeSyncPacket() 00586 { 00587 //this method contains every step of sync packet informations decoding process 00588 //first : transport 00589 if (fParams.fTransportSync) { 00590 //copy received transport data to transport data structure 00591 memcpy ( &fReturnTransportData, fRxData, sizeof ( net_transport_data_t ) ); 00592 TransportDataNToH( &fReturnTransportData, &fReturnTransportData); 00593 DecodeTransportData(); 00594 } 00595 //then others 00596 //... 00597 } 00598 00599 // JackNetSlaveInterface ************************************************************************************************ 00600 00601 uint JackNetSlaveInterface::fSlaveCounter = 0; 00602 00603 bool JackNetSlaveInterface::Init() 00604 { 00605 jack_log ( "JackNetSlaveInterface::Init()" ); 00606 00607 //set the parameters to send 00608 strcpy ( fParams.fPacketType, "params" ); 00609 fParams.fProtocolVersion = SLAVE_PROTOCOL; 00610 SetPacketType ( &fParams, SLAVE_AVAILABLE ); 00611 00612 //init loop : get a master and start, do it until connection is ok 00613 net_status_t status; 00614 do 00615 { 00616 //first, get a master, do it until a valid connection is running 00617 do 00618 { 00619 status = SendAvailableToMaster(); 00620 if ( status == NET_SOCKET_ERROR ) 00621 return false; 00622 } 00623 while ( status != NET_CONNECTED ); 00624 00625 //then tell the master we are ready 00626 jack_info ( "Initializing connection with %s...", fParams.fMasterNetName ); 00627 status = SendStartToMaster(); 00628 if ( status == NET_ERROR ) 00629 return false; 00630 } 00631 while ( status != NET_ROLLING ); 00632 00633 return true; 00634 } 00635 00636 // Separate the connection protocol into two separated step 00637 00638 bool JackNetSlaveInterface::InitConnection() 00639 { 00640 jack_log ( "JackNetSlaveInterface::InitConnection()" ); 00641 00642 //set the parameters to send 00643 strcpy (fParams.fPacketType, "params"); 00644 fParams.fProtocolVersion = SLAVE_PROTOCOL; 00645 SetPacketType (&fParams, SLAVE_AVAILABLE); 00646 00647 net_status_t status; 00648 do 00649 { 00650 //get a master 00651 status = SendAvailableToMaster(); 00652 if (status == NET_SOCKET_ERROR) 00653 return false; 00654 } 00655 while (status != NET_CONNECTED); 00656 00657 return true; 00658 } 00659 00660 bool JackNetSlaveInterface::InitRendering() 00661 { 00662 jack_log("JackNetSlaveInterface::InitRendering()"); 00663 00664 net_status_t status; 00665 do 00666 { 00667 //then tell the master we are ready 00668 jack_info("Initializing connection with %s...", fParams.fMasterNetName); 00669 status = SendStartToMaster(); 00670 if (status == NET_ERROR) 00671 return false; 00672 } 00673 while (status != NET_ROLLING); 00674 00675 return true; 00676 } 00677 00678 net_status_t JackNetSlaveInterface::SendAvailableToMaster() 00679 { 00680 jack_log ( "JackNetSlaveInterface::SendAvailableToMaster()" ); 00681 //utility 00682 session_params_t host_params; 00683 int rx_bytes = 0; 00684 00685 //socket 00686 if ( fSocket.NewSocket() == SOCKET_ERROR ) { 00687 jack_error ( "Fatal error : network unreachable - %s", StrError ( NET_ERROR_CODE ) ); 00688 return NET_SOCKET_ERROR; 00689 } 00690 00691 //bind the socket 00692 if ( fSocket.Bind() == SOCKET_ERROR ) { 00693 jack_error ( "Can't bind the socket : %s", StrError ( NET_ERROR_CODE ) ); 00694 return NET_SOCKET_ERROR; 00695 } 00696 00697 //timeout on receive 00698 if ( fSocket.SetTimeOut ( SLAVE_INIT_TIMEOUT ) == SOCKET_ERROR ) 00699 jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) ); 00700 00701 //disable local loop 00702 if ( fSocket.SetLocalLoop() == SOCKET_ERROR ) 00703 jack_error ( "Can't disable multicast loop : %s", StrError ( NET_ERROR_CODE ) ); 00704 00705 //send 'AVAILABLE' until 'SLAVE_SETUP' received 00706 jack_info ( "Waiting for a master..." ); 00707 do 00708 { 00709 //send 'available' 00710 session_params_t net_params; 00711 memset(&net_params, 0, sizeof ( session_params_t )); 00712 SessionParamsHToN(&fParams, &net_params); 00713 if ( fSocket.SendTo ( &net_params, sizeof ( session_params_t ), 0, fMulticastIP ) == SOCKET_ERROR ) 00714 jack_error ( "Error in data send : %s", StrError ( NET_ERROR_CODE ) ); 00715 00716 //filter incoming packets : don't exit while no error is detected 00717 memset(&net_params, 0, sizeof ( session_params_t )); 00718 rx_bytes = fSocket.CatchHost ( &net_params, sizeof ( session_params_t ), 0 ); 00719 SessionParamsNToH(&net_params, &host_params); 00720 if ( ( rx_bytes == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) ) 00721 { 00722 jack_error ( "Can't receive : %s", StrError ( NET_ERROR_CODE ) ); 00723 return NET_RECV_ERROR; 00724 } 00725 } 00726 while ( strcmp ( host_params.fPacketType, fParams.fPacketType ) && ( GetPacketType ( &host_params ) != SLAVE_SETUP ) ); 00727 00728 //everything is OK, copy parameters 00729 fParams = host_params; 00730 00731 //set the new buffer sizes 00732 if ( SetNetBufferSize() == SOCKET_ERROR ) { 00733 jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) ); 00734 return NET_SOCKET_ERROR; 00735 } 00736 00737 //connect the socket 00738 if ( fSocket.Connect() == SOCKET_ERROR ) { 00739 jack_error ( "Error in connect : %s", StrError ( NET_ERROR_CODE ) ); 00740 return NET_CONNECT_ERROR; 00741 } 00742 00743 return NET_CONNECTED; 00744 } 00745 00746 net_status_t JackNetSlaveInterface::SendStartToMaster() 00747 { 00748 jack_log ( "JackNetSlaveInterface::SendStartToMaster" ); 00749 00750 //tell the master to start 00751 session_params_t net_params; 00752 memset(&net_params, 0, sizeof ( session_params_t )); 00753 SetPacketType ( &fParams, START_MASTER ); 00754 SessionParamsHToN(&fParams, &net_params); 00755 if ( fSocket.Send ( &net_params, sizeof ( session_params_t ), 0 ) == SOCKET_ERROR ) 00756 { 00757 jack_error ( "Error in send : %s", StrError ( NET_ERROR_CODE ) ); 00758 return ( fSocket.GetError() == NET_CONN_ERROR ) ? NET_ERROR : NET_SEND_ERROR; 00759 } 00760 return NET_ROLLING; 00761 } 00762 00763 void JackNetSlaveInterface::SetParams() 00764 { 00765 jack_log ( "JackNetSlaveInterface::SetParams" ); 00766 00767 JackNetInterface::SetParams(); 00768 00769 fTxHeader.fDataStream = 'r'; 00770 fRxHeader.fDataStream = 's'; 00771 00772 //midi net buffers 00773 fNetMidiCaptureBuffer = new NetMidiBuffer ( &fParams, fParams.fSendMidiChannels, fRxData ); 00774 fNetMidiPlaybackBuffer = new NetMidiBuffer ( &fParams, fParams.fReturnMidiChannels, fTxData ); 00775 00776 //audio net buffers 00777 fNetAudioCaptureBuffer = new NetAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); 00778 fNetAudioPlaybackBuffer = new NetAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); 00779 00780 //audio netbuffer length 00781 fAudioTxLen = sizeof ( packet_header_t ) + fNetAudioPlaybackBuffer->GetSize(); 00782 fAudioRxLen = sizeof ( packet_header_t ) + fNetAudioCaptureBuffer->GetSize(); 00783 } 00784 00785 int JackNetSlaveInterface::Recv ( size_t size, int flags ) 00786 { 00787 int rx_bytes = fSocket.Recv ( fRxBuffer, size, flags ); 00788 //handle errors 00789 if ( rx_bytes == SOCKET_ERROR ) 00790 { 00791 net_error_t error = fSocket.GetError(); 00792 //no data isn't really an error in realtime processing, so just return 0 00793 if ( error == NET_NO_DATA ) 00794 jack_error ( "No data, is the master still running ?" ); 00795 //if a network error occurs, this exception will restart the driver 00796 else if ( error == NET_CONN_ERROR ) 00797 { 00798 jack_error ( "Connection lost." ); 00799 throw JackNetException(); 00800 } 00801 else 00802 jack_error ( "Fatal error in slave receive : %s", StrError ( NET_ERROR_CODE ) ); 00803 } 00804 00805 packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer); 00806 PacketHeaderNToH(header, header); 00807 return rx_bytes; 00808 } 00809 00810 int JackNetSlaveInterface::Send ( size_t size, int flags ) 00811 { 00812 packet_header_t* header = reinterpret_cast<packet_header_t*>(fTxBuffer); 00813 PacketHeaderHToN(header, header); 00814 int tx_bytes = fSocket.Send ( fTxBuffer, size, flags ); 00815 00816 //handle errors 00817 if ( tx_bytes == SOCKET_ERROR ) 00818 { 00819 net_error_t error = fSocket.GetError(); 00820 //if a network error occurs, this exception will restart the driver 00821 if ( error == NET_CONN_ERROR ) 00822 { 00823 jack_error ( "Connection lost." ); 00824 throw JackNetException(); 00825 } 00826 else 00827 jack_error ( "Fatal error in slave send : %s", StrError ( NET_ERROR_CODE ) ); 00828 } 00829 return tx_bytes; 00830 } 00831 00832 int JackNetSlaveInterface::SyncRecv() 00833 { 00834 int rx_bytes = 0; 00835 packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer ); 00836 //receive sync (launch the cycle) 00837 do 00838 { 00839 rx_bytes = Recv ( fParams.fMtu, 0 ); 00840 //connection issue, send will detect it, so don't skip the cycle (return 0) 00841 if ( rx_bytes == SOCKET_ERROR ) 00842 return rx_bytes; 00843 } 00844 while ((strcmp(rx_head->fPacketType, "header") != 0) && (rx_head->fDataType != 's')); 00845 00846 fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; 00847 return rx_bytes; 00848 } 00849 00850 int JackNetSlaveInterface::DataRecv() 00851 { 00852 uint recvd_midi_pckt = 0; 00853 uint recvd_audio_pckt = 0; 00854 int rx_bytes = 0; 00855 packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer ); 00856 00857 while ( !fRxHeader.fIsLastPckt ) 00858 { 00859 rx_bytes = Recv ( fParams.fMtu, MSG_PEEK ); 00860 //error here, problem with recv, just skip the cycle (return -1) 00861 00862 if ( rx_bytes == SOCKET_ERROR ) 00863 return rx_bytes; 00864 if ( rx_bytes && ( rx_head->fDataStream == 's' ) && ( rx_head->fID == fParams.fID ) ) 00865 { 00866 switch ( rx_head->fDataType ) 00867 { 00868 case 'm': //midi 00869 rx_bytes = Recv ( rx_head->fPacketSize, 0 ); 00870 fRxHeader.fCycle = rx_head->fCycle; 00871 fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; 00872 fNetMidiCaptureBuffer->RenderFromNetwork ( rx_head->fSubCycle, rx_bytes - sizeof ( packet_header_t ) ); 00873 if ( ++recvd_midi_pckt == rx_head->fNMidiPckt ) 00874 fNetMidiCaptureBuffer->RenderToJackPorts(); 00875 break; 00876 00877 case 'a': //audio 00878 rx_bytes = Recv ( rx_head->fPacketSize, 0 ); 00879 //SL: 25/01/09 00880 // if ( !IsNextPacket() ) 00881 // jack_error ( "Packet(s) missing..." ); 00882 if (recvd_audio_pckt++ != rx_head->fSubCycle) { 00883 jack_error("Packet(s) missing from '%s'...", fParams.fMasterNetName); 00884 } 00885 fRxHeader.fCycle = rx_head->fCycle; 00886 fRxHeader.fSubCycle = rx_head->fSubCycle; 00887 fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; 00888 fNetAudioCaptureBuffer->RenderToJackPorts ( rx_head->fSubCycle ); 00889 break; 00890 00891 case 's': //sync 00892 jack_info ( "NetSlave : overloaded, skipping receive." ); 00893 return 0; 00894 } 00895 } 00896 } 00897 fRxHeader.fCycle = rx_head->fCycle; 00898 return 0; 00899 } 00900 00901 int JackNetSlaveInterface::SyncSend() 00902 { 00903 //tx header 00904 if ( fParams.fSlaveSyncMode ) 00905 fTxHeader.fCycle = fRxHeader.fCycle; 00906 else 00907 fTxHeader.fCycle++; 00908 fTxHeader.fSubCycle = 0; 00909 fTxHeader.fDataType = 's'; 00910 fTxHeader.fIsLastPckt = ( fParams.fReturnMidiChannels == 0 && fParams.fReturnAudioChannels == 0) ? 1 : 0; 00911 fTxHeader.fPacketSize = fParams.fMtu; 00912 memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) ); 00913 return Send ( fTxHeader.fPacketSize, 0 ); 00914 } 00915 00916 int JackNetSlaveInterface::DataSend() 00917 { 00918 uint subproc; 00919 00920 //midi 00921 if ( fParams.fReturnMidiChannels > 0) 00922 { 00923 fTxHeader.fDataType = 'm'; 00924 fTxHeader.fMidiDataSize = fNetMidiPlaybackBuffer->RenderFromJackPorts(); 00925 fTxHeader.fNMidiPckt = GetNMidiPckt(); 00926 for ( subproc = 0; subproc < fTxHeader.fNMidiPckt; subproc++ ) 00927 { 00928 fTxHeader.fSubCycle = subproc; 00929 fTxHeader.fIsLastPckt = ( ( subproc == ( fTxHeader.fNMidiPckt - 1 ) ) && !fParams.fReturnAudioChannels ) ? 1 : 0; 00930 fTxHeader.fPacketSize = sizeof ( packet_header_t ) + fNetMidiPlaybackBuffer->RenderToNetwork ( subproc, fTxHeader.fMidiDataSize ); 00931 memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) ); 00932 if ( Send ( fTxHeader.fPacketSize, 0 ) == SOCKET_ERROR ) 00933 return SOCKET_ERROR; 00934 } 00935 } 00936 00937 //audio 00938 if ( fParams.fReturnAudioChannels > 0) 00939 { 00940 fTxHeader.fDataType = 'a'; 00941 fTxHeader.fMidiDataSize = 0; 00942 fTxHeader.fNMidiPckt = 0; 00943 for ( subproc = 0; subproc < fNSubProcess; subproc++ ) 00944 { 00945 fTxHeader.fSubCycle = subproc; 00946 fTxHeader.fIsLastPckt = ( subproc == ( fNSubProcess - 1 ) ) ? 1 : 0; 00947 fTxHeader.fPacketSize = fAudioTxLen; 00948 memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) ); 00949 fNetAudioPlaybackBuffer->RenderFromJackPorts ( subproc ); 00950 if ( Send ( fTxHeader.fPacketSize, 0 ) == SOCKET_ERROR ) 00951 return SOCKET_ERROR; 00952 } 00953 } 00954 return 0; 00955 } 00956 00957 //network sync------------------------------------------------------------------------ 00958 void JackNetSlaveInterface::EncodeSyncPacket() 00959 { 00960 //this method contains every step of sync packet informations coding 00961 //first of all, reset sync packet 00962 memset ( fTxData, 0, fPayloadSize ); 00963 //then first step : transport 00964 if (fParams.fTransportSync) { 00965 EncodeTransportData(); 00966 TransportDataHToN( &fReturnTransportData, &fReturnTransportData); 00967 //copy to TxBuffer 00968 memcpy ( fTxData, &fReturnTransportData, sizeof ( net_transport_data_t ) ); 00969 } 00970 //then others 00971 //... 00972 } 00973 00974 void JackNetSlaveInterface::DecodeSyncPacket() 00975 { 00976 //this method contains every step of sync packet informations decoding process 00977 //first : transport 00978 if (fParams.fTransportSync) { 00979 //copy received transport data to transport data structure 00980 memcpy ( &fSendTransportData, fRxData, sizeof ( net_transport_data_t ) ); 00981 TransportDataNToH( &fSendTransportData, &fSendTransportData); 00982 DecodeTransportData(); 00983 } 00984 //then others 00985 //... 00986 } 00987 00988 }