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