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