jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

995 lines
38KB

  1. /*
  2. Copyright (C) 2001 Paul Davis
  3. Copyright (C) 2008 Romain Moret at Grame
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. #include "JackNetInterface.h"
  17. #include "JackException.h"
  18. #include "JackPlatformPlug.h"
  19. #include <assert.h>
  20. using namespace std;
  21. #define PACKET_AVAILABLE_SIZE (fParams.fMtu - sizeof(packet_header_t))
  22. #define HEADER_SIZE (sizeof(packet_header_t))
  23. /*
  24. TODO : since midi buffers now uses up to BUFFER_SIZE_MAX frames,
  25. probably also use BUFFER_SIZE_MAX in everything related to MIDI events
  26. handling (see MidiBufferInit in JackMidiPort.cpp)
  27. */
  28. namespace Jack
  29. {
  30. // JackNetInterface*******************************************
  31. JackNetInterface::JackNetInterface() : fSocket()
  32. {
  33. fTxBuffer = NULL;
  34. fRxBuffer = NULL;
  35. fNetAudioCaptureBuffer = NULL;
  36. fNetAudioPlaybackBuffer = NULL;
  37. fNetMidiCaptureBuffer = NULL;
  38. fNetMidiPlaybackBuffer = NULL;
  39. memset(&fSendTransportData, 0, sizeof(net_transport_data_t));
  40. memset(&fReturnTransportData, 0, sizeof(net_transport_data_t));
  41. }
  42. JackNetInterface::JackNetInterface ( const char* multicast_ip, int port ) : fSocket ( multicast_ip, port )
  43. {
  44. strcpy(fMulticastIP, multicast_ip);
  45. fTxBuffer = NULL;
  46. fRxBuffer = NULL;
  47. fNetAudioCaptureBuffer = NULL;
  48. fNetAudioPlaybackBuffer = NULL;
  49. fNetMidiCaptureBuffer = NULL;
  50. fNetMidiPlaybackBuffer = NULL;
  51. memset(&fSendTransportData, 0, sizeof(net_transport_data_t));
  52. memset(&fReturnTransportData, 0, sizeof(net_transport_data_t));
  53. }
  54. JackNetInterface::JackNetInterface ( session_params_t& params, JackNetSocket& socket, const char* multicast_ip ) : fSocket ( socket )
  55. {
  56. fParams = params;
  57. strcpy(fMulticastIP, multicast_ip);
  58. fTxBuffer = NULL;
  59. fRxBuffer = NULL;
  60. fNetAudioCaptureBuffer = NULL;
  61. fNetAudioPlaybackBuffer = NULL;
  62. fNetMidiCaptureBuffer = NULL;
  63. fNetMidiPlaybackBuffer = NULL;
  64. memset(&fSendTransportData, 0, sizeof(net_transport_data_t));
  65. memset(&fReturnTransportData, 0, sizeof(net_transport_data_t));
  66. }
  67. JackNetInterface::~JackNetInterface()
  68. {
  69. jack_log ( "JackNetInterface::~JackNetInterface" );
  70. fSocket.Close();
  71. delete[] fTxBuffer;
  72. delete[] fRxBuffer;
  73. delete fNetAudioCaptureBuffer;
  74. delete fNetAudioPlaybackBuffer;
  75. delete fNetMidiCaptureBuffer;
  76. delete fNetMidiPlaybackBuffer;
  77. }
  78. int JackNetInterface::SetNetBufferSize()
  79. {
  80. //audio
  81. float audio_size = (fNetAudioCaptureBuffer)
  82. ? fNetAudioCaptureBuffer->GetCycleSize()
  83. : (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleSize() : 0;
  84. jack_log ("audio_size %f", audio_size);
  85. //midi
  86. float midi_size = (fNetMidiCaptureBuffer)
  87. ? fNetMidiCaptureBuffer->GetCycleSize()
  88. : (fNetMidiPlaybackBuffer) ? fNetMidiPlaybackBuffer->GetCycleSize() : 0;
  89. jack_log ("midi_size %f", midi_size);
  90. //bufsize = sync + audio + midi
  91. int bufsize = MAX_LATENCY * (fParams.fMtu + (int)audio_size + (int) midi_size);
  92. jack_log("SetNetBufferSize bufsize = %d", bufsize);
  93. //tx buffer
  94. if (fSocket.SetOption(SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)) == SOCKET_ERROR)
  95. return SOCKET_ERROR;
  96. //rx buffer
  97. if (fSocket.SetOption(SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)) == SOCKET_ERROR)
  98. return SOCKET_ERROR;
  99. return 0;
  100. }
  101. bool JackNetInterface::SetParams()
  102. {
  103. //TX header init
  104. strcpy ( fTxHeader.fPacketType, "header" );
  105. fTxHeader.fID = fParams.fID;
  106. fTxHeader.fCycle = 0;
  107. fTxHeader.fSubCycle = 0;
  108. fTxHeader.fBitdepth = fParams.fBitdepth;
  109. fTxHeader.fIsLastPckt = 0;
  110. //RX header init
  111. strcpy ( fRxHeader.fPacketType, "header" );
  112. fRxHeader.fID = fParams.fID;
  113. fRxHeader.fCycle = 0;
  114. fRxHeader.fSubCycle = 0;
  115. fRxHeader.fBitdepth = fParams.fBitdepth;
  116. fRxHeader.fIsLastPckt = 0;
  117. //network buffers
  118. fTxBuffer = new char[fParams.fMtu];
  119. fRxBuffer = new char[fParams.fMtu];
  120. assert ( fTxBuffer );
  121. assert ( fRxBuffer );
  122. //net audio/midi buffers'addresses
  123. fTxData = fTxBuffer + HEADER_SIZE;
  124. fRxData = fRxBuffer + HEADER_SIZE;
  125. return true;
  126. }
  127. // JackNetMasterInterface ************************************************************************************
  128. bool JackNetMasterInterface::Init()
  129. {
  130. jack_log ( "JackNetMasterInterface::Init, ID %u.", fParams.fID );
  131. session_params_t host_params;
  132. uint attempt = 0;
  133. int rx_bytes = 0;
  134. //socket
  135. if ( fSocket.NewSocket() == SOCKET_ERROR ) {
  136. jack_error ( "Can't create socket : %s", StrError ( NET_ERROR_CODE ) );
  137. return false;
  138. }
  139. //timeout on receive (for init)
  140. if ( fSocket.SetTimeOut ( MASTER_INIT_TIMEOUT ) < 0 )
  141. jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) );
  142. //connect
  143. if ( fSocket.Connect() == SOCKET_ERROR ) {
  144. jack_error ( "Can't connect : %s", StrError ( NET_ERROR_CODE ) );
  145. return false;
  146. }
  147. //send 'SLAVE_SETUP' until 'START_MASTER' received
  148. jack_info ( "Sending parameters to %s...", fParams.fSlaveNetName );
  149. do
  150. {
  151. session_params_t net_params;
  152. memset(&net_params, 0, sizeof ( session_params_t ));
  153. SetPacketType ( &fParams, SLAVE_SETUP );
  154. SessionParamsHToN(&fParams, &net_params);
  155. if ( fSocket.Send ( &net_params, sizeof ( session_params_t ), 0 ) == SOCKET_ERROR )
  156. jack_error ( "Error in send : ", StrError ( NET_ERROR_CODE ) );
  157. memset(&net_params, 0, sizeof ( session_params_t ));
  158. if ( ( ( rx_bytes = fSocket.Recv ( &net_params, sizeof ( session_params_t ), 0 ) ) == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) )
  159. {
  160. jack_error ( "Problem with network." );
  161. return false;
  162. }
  163. SessionParamsNToH(&net_params, &host_params);
  164. }
  165. while ( ( GetPacketType ( &host_params ) != START_MASTER ) && ( ++attempt < SLAVE_SETUP_RETRY ) );
  166. if ( attempt == SLAVE_SETUP_RETRY ) {
  167. jack_error ( "Slave doesn't respond, exiting." );
  168. return false;
  169. }
  170. return true;
  171. }
  172. int JackNetMasterInterface::SetRxTimeout()
  173. {
  174. jack_log ( "JackNetMasterInterface::SetRxTimeout" );
  175. float time = 0;
  176. //slow or normal mode, short timeout on recv (2 audio subcycles)
  177. if ((fParams.fNetworkMode == 's') || (fParams.fNetworkMode == 'n')) {
  178. time = 2000000.f * ((fNetAudioCaptureBuffer)
  179. ? fNetAudioCaptureBuffer->GetCycleDuration()
  180. : (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleDuration() : 0);
  181. }
  182. //fast mode, wait for 75% of the entire cycle duration
  183. else if (fParams.fNetworkMode == 'f') {
  184. time = 750000.f * (static_cast<float>(fParams.fPeriodSize) / static_cast<float>(fParams.fSampleRate));
  185. }
  186. return fSocket.SetTimeOut (static_cast<int>(time));
  187. }
  188. bool JackNetMasterInterface::SetParams()
  189. {
  190. jack_log ( "JackNetMasterInterface::SetParams" );
  191. JackNetInterface::SetParams();
  192. fTxHeader.fDataStream = 's';
  193. fRxHeader.fDataStream = 'r';
  194. //midi net buffers
  195. fNetMidiCaptureBuffer = new NetMidiBuffer ( &fParams, fParams.fSendMidiChannels, fTxData );
  196. fNetMidiPlaybackBuffer = new NetMidiBuffer ( &fParams, fParams.fReturnMidiChannels, fRxData );
  197. assert ( fNetMidiCaptureBuffer );
  198. assert ( fNetMidiPlaybackBuffer );
  199. try {
  200. //audio net buffers
  201. #ifdef CELT
  202. fNetAudioCaptureBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData );
  203. fNetAudioPlaybackBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData );
  204. #else
  205. fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData );
  206. fNetAudioPlaybackBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData );
  207. #endif
  208. } catch (exception&) {
  209. jack_error("NetAudioBuffer allocation error...");
  210. return false;
  211. }
  212. //fNetAudioCaptureBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData );
  213. //fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData );
  214. assert ( fNetAudioCaptureBuffer );
  215. assert ( fNetAudioPlaybackBuffer );
  216. //set the new timeout for the socket
  217. if ( SetRxTimeout() == SOCKET_ERROR ) {
  218. jack_error ( "Can't set rx timeout : %s", StrError ( NET_ERROR_CODE ) );
  219. goto error;
  220. }
  221. //set the new rx buffer size
  222. if ( SetNetBufferSize() == SOCKET_ERROR ) {
  223. jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) );
  224. goto error;
  225. }
  226. return true;
  227. error:
  228. delete fNetMidiCaptureBuffer;
  229. delete fNetMidiPlaybackBuffer;
  230. delete fNetAudioCaptureBuffer;
  231. delete fNetAudioPlaybackBuffer;
  232. return false;
  233. }
  234. void JackNetMasterInterface::Exit()
  235. {
  236. jack_log ( "JackNetMasterInterface::Exit, ID %u", fParams.fID );
  237. //stop process
  238. fRunning = false;
  239. //send a 'multicast euthanasia request' - new socket is required on macosx
  240. jack_info ( "Exiting '%s'", fParams.fName );
  241. SetPacketType ( &fParams, KILL_MASTER );
  242. JackNetSocket mcast_socket ( fMulticastIP, fSocket.GetPort() );
  243. session_params_t net_params;
  244. memset(&net_params, 0, sizeof ( session_params_t ));
  245. SessionParamsHToN(&fParams, &net_params);
  246. if ( mcast_socket.NewSocket() == SOCKET_ERROR )
  247. jack_error ( "Can't create socket : %s", StrError ( NET_ERROR_CODE ) );
  248. if ( mcast_socket.SendTo ( &net_params, sizeof ( session_params_t ), 0, fMulticastIP ) == SOCKET_ERROR )
  249. jack_error ( "Can't send suicide request : %s", StrError ( NET_ERROR_CODE ) );
  250. mcast_socket.Close();
  251. }
  252. int JackNetMasterInterface::Recv ( size_t size, int flags )
  253. {
  254. int rx_bytes;
  255. if ((( rx_bytes = fSocket.Recv(fRxBuffer, size, flags)) == SOCKET_ERROR) && fRunning) {
  256. net_error_t error = fSocket.GetError();
  257. //no data isn't really a network error, so just return 0 available read bytes
  258. if (error == NET_NO_DATA) {
  259. return 0;
  260. } else if (error == NET_CONN_ERROR) {
  261. //fatal connection issue, exit
  262. jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError(NET_ERROR_CODE));
  263. //ask to the manager to properly remove the master
  264. Exit();
  265. // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
  266. ThreadExit();
  267. } else {
  268. jack_error ( "Error in master receive : %s", StrError(NET_ERROR_CODE));
  269. }
  270. }
  271. packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer);
  272. PacketHeaderNToH(header, header);
  273. return rx_bytes;
  274. }
  275. int JackNetMasterInterface::Send ( size_t size, int flags )
  276. {
  277. int tx_bytes;
  278. packet_header_t* header = reinterpret_cast<packet_header_t*>(fTxBuffer);
  279. PacketHeaderHToN(header, header);
  280. if (((tx_bytes = fSocket.Send(fTxBuffer, size, flags)) == SOCKET_ERROR) && fRunning) {
  281. net_error_t error = fSocket.GetError();
  282. if (error == NET_CONN_ERROR) {
  283. //fatal connection issue, exit
  284. jack_error ("'%s' : %s, exiting.", fParams.fName, StrError (NET_ERROR_CODE));
  285. Exit();
  286. // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
  287. ThreadExit();
  288. } else {
  289. jack_error("Error in master send : %s", StrError(NET_ERROR_CODE));
  290. }
  291. }
  292. return tx_bytes;
  293. }
  294. bool JackNetMasterInterface::IsSynched()
  295. {
  296. if (fParams.fNetworkMode == 's') {
  297. return (fCycleOffset < (CYCLE_OFFSET_SLOW + 1));
  298. } else {
  299. return true;
  300. }
  301. }
  302. int JackNetMasterInterface::SyncSend()
  303. {
  304. fTxHeader.fCycle++;
  305. fTxHeader.fSubCycle = 0;
  306. fTxHeader.fDataType = 's';
  307. fTxHeader.fIsLastPckt = ( fParams.fSendMidiChannels == 0 && fParams.fSendAudioChannels == 0) ? 1 : 0;
  308. fTxHeader.fPacketSize = HEADER_SIZE;
  309. memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
  310. return Send(fTxHeader.fPacketSize, 0);
  311. }
  312. int JackNetMasterInterface::DataSend()
  313. {
  314. uint subproc;
  315. uint data_size;
  316. //midi
  317. if ( fParams.fSendMidiChannels > 0)
  318. {
  319. //set global header fields and get the number of midi packets
  320. fTxHeader.fDataType = 'm';
  321. data_size = fNetMidiCaptureBuffer->RenderFromJackPorts();
  322. fTxHeader.fNumPacket = fNetMidiCaptureBuffer->GetNumPackets();
  323. for ( subproc = 0; subproc < fTxHeader.fNumPacket; subproc++ )
  324. {
  325. fTxHeader.fSubCycle = subproc;
  326. fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && (fParams.fSendAudioChannels == 0)) ? 1 : 0;
  327. fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiCaptureBuffer->RenderToNetwork(subproc, data_size);
  328. memcpy ( fTxBuffer, &fTxHeader, HEADER_SIZE);
  329. if (Send (fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
  330. return SOCKET_ERROR;
  331. }
  332. }
  333. //audio
  334. if ( fParams.fSendAudioChannels > 0)
  335. {
  336. fTxHeader.fDataType = 'a';
  337. data_size = fNetAudioCaptureBuffer->RenderFromJackPorts();
  338. fTxHeader.fNumPacket = fNetAudioCaptureBuffer->GetNumPackets();
  339. for (subproc = 0; subproc < fTxHeader.fNumPacket; subproc++)
  340. {
  341. fTxHeader.fSubCycle = subproc;
  342. fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0;
  343. fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioCaptureBuffer->RenderToNetwork(subproc, data_size);
  344. memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
  345. if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
  346. return SOCKET_ERROR;
  347. }
  348. }
  349. return 0;
  350. }
  351. int JackNetMasterInterface::SyncRecv()
  352. {
  353. packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
  354. int rx_bytes = Recv(HEADER_SIZE, MSG_PEEK);
  355. if ( ( rx_bytes == 0 ) || ( rx_bytes == SOCKET_ERROR ) )
  356. return rx_bytes;
  357. fCycleOffset = fTxHeader.fCycle - rx_head->fCycle;
  358. switch ( fParams.fNetworkMode )
  359. {
  360. case 's' :
  361. //slow mode : allow to use full bandwidth and heavy process on the slave
  362. // - extra latency is set to two cycles, one cycle for send/receive operations + one cycle for heavy process on the slave
  363. // - if the network is two fast, just wait the next cycle, this mode allows a shorter cycle duration for the master
  364. // - this mode will skip the two first cycles, thus it lets time for data to be processed and queued on the socket rx buffer
  365. //the slow mode is the safest mode because it wait twice the bandwidth relative time (send/return + process)
  366. if (fCycleOffset < CYCLE_OFFSET_SLOW) {
  367. return 0;
  368. } else {
  369. rx_bytes = Recv ( rx_head->fPacketSize, 0 );
  370. }
  371. if (fCycleOffset > CYCLE_OFFSET_SLOW) {
  372. jack_info("Warning : '%s' runs in slow network mode, but data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
  373. }
  374. break;
  375. case 'n' :
  376. //normal use of the network :
  377. // - extra latency is set to one cycle, what is the time needed to receive streams using full network bandwidth
  378. // - if the network is too fast, just wait the next cycle, the benefit here is the master's cycle is shorter
  379. // - indeed, data is supposed to be on the network rx buffer, so we don't have to wait for it
  380. if (fCycleOffset < CYCLE_OFFSET_NORMAL) {
  381. return 0;
  382. } else {
  383. rx_bytes = Recv ( rx_head->fPacketSize, 0 );
  384. }
  385. if (fCycleOffset > CYCLE_OFFSET_NORMAL) {
  386. jack_info("'%s' can't run in normal network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
  387. }
  388. break;
  389. case 'f' :
  390. //fast mode suppose the network bandwith is larger than required for the transmission (only a few channels for example)
  391. // - packets can be quickly received, quickly is here relative to the cycle duration
  392. // - here, receive data, we can't keep it queued on the rx buffer,
  393. // - but if there is a cycle offset, tell the user, that means we're not in fast mode anymore, network is too slow
  394. rx_bytes = Recv ( rx_head->fPacketSize, 0 );
  395. if (fCycleOffset > CYCLE_OFFSET_FAST) {
  396. jack_info("'%s' can't run in fast network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
  397. }
  398. break;
  399. }
  400. fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
  401. return rx_bytes;
  402. }
  403. int JackNetMasterInterface::DataRecv()
  404. {
  405. int rx_bytes = 0;
  406. uint recvd_midi_pckt = 0;
  407. uint recvd_audio_pckt = 0;
  408. packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
  409. while ( !fRxHeader.fIsLastPckt )
  410. {
  411. //how much data is queued on the rx buffer ?
  412. rx_bytes = Recv(HEADER_SIZE, MSG_PEEK);
  413. //error here, problem with recv, just skip the cycle (return -1)
  414. if ( rx_bytes == SOCKET_ERROR )
  415. return rx_bytes;
  416. if ( rx_bytes && ( rx_head->fDataStream == 'r' ) && ( rx_head->fID == fParams.fID ) )
  417. {
  418. //read data
  419. switch ( rx_head->fDataType )
  420. {
  421. case 'm': //midi
  422. rx_bytes = Recv(rx_head->fPacketSize, 0);
  423. fRxHeader.fCycle = rx_head->fCycle;
  424. fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
  425. fNetMidiPlaybackBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
  426. // Last midi packet is received, so finish rendering...
  427. if (++recvd_midi_pckt == rx_head->fNumPacket)
  428. fNetMidiPlaybackBuffer->RenderToJackPorts();
  429. break;
  430. case 'a': //audio
  431. rx_bytes = Recv(rx_head->fPacketSize, 0);
  432. fRxHeader.fCycle = rx_head->fCycle;
  433. fRxHeader.fSubCycle = rx_head->fSubCycle;
  434. fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
  435. fNetAudioPlaybackBuffer->RenderFromNetwork (rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
  436. // Last audio packet is received, so finish rendering...
  437. if (fRxHeader.fIsLastPckt)
  438. fNetAudioPlaybackBuffer->RenderToJackPorts();
  439. break;
  440. case 's': //sync
  441. jack_info("NetMaster : overloaded, skipping receive from '%s'", fParams.fName);
  442. // TODO : finish midi and audio rendering ?
  443. return 0;
  444. }
  445. }
  446. }
  447. return rx_bytes;
  448. }
  449. void JackNetMasterInterface::EncodeSyncPacket()
  450. {
  451. //this method contains every step of sync packet informations coding
  452. //first of all, reset sync packet
  453. memset ( fTxData, 0, PACKET_AVAILABLE_SIZE );
  454. //then, first step : transport
  455. if (fParams.fTransportSync) {
  456. EncodeTransportData();
  457. TransportDataHToN( &fSendTransportData, &fSendTransportData);
  458. //copy to TxBuffer
  459. memcpy ( fTxData, &fSendTransportData, sizeof ( net_transport_data_t ) );
  460. }
  461. //then others (freewheel etc.)
  462. //...
  463. }
  464. void JackNetMasterInterface::DecodeSyncPacket()
  465. {
  466. //this method contains every step of sync packet informations decoding process
  467. //first : transport
  468. if (fParams.fTransportSync) {
  469. //copy received transport data to transport data structure
  470. memcpy ( &fReturnTransportData, fRxData, sizeof ( net_transport_data_t ) );
  471. TransportDataNToH( &fReturnTransportData, &fReturnTransportData);
  472. DecodeTransportData();
  473. }
  474. //then others
  475. //...
  476. }
  477. // JackNetSlaveInterface ************************************************************************************************
  478. uint JackNetSlaveInterface::fSlaveCounter = 0;
  479. bool JackNetSlaveInterface::Init()
  480. {
  481. jack_log ( "JackNetSlaveInterface::Init()" );
  482. //set the parameters to send
  483. strcpy ( fParams.fPacketType, "params" );
  484. fParams.fProtocolVersion = SLAVE_PROTOCOL;
  485. SetPacketType ( &fParams, SLAVE_AVAILABLE );
  486. //init loop : get a master and start, do it until connection is ok
  487. net_status_t status;
  488. do
  489. {
  490. //first, get a master, do it until a valid connection is running
  491. do
  492. {
  493. status = SendAvailableToMaster();
  494. if ( status == NET_SOCKET_ERROR )
  495. return false;
  496. }
  497. while ( status != NET_CONNECTED );
  498. //then tell the master we are ready
  499. jack_info ( "Initializing connection with %s...", fParams.fMasterNetName );
  500. status = SendStartToMaster();
  501. if ( status == NET_ERROR )
  502. return false;
  503. }
  504. while ( status != NET_ROLLING );
  505. return true;
  506. }
  507. // Separate the connection protocol into two separated step
  508. bool JackNetSlaveInterface::InitConnection()
  509. {
  510. jack_log ( "JackNetSlaveInterface::InitConnection()" );
  511. //set the parameters to send
  512. strcpy (fParams.fPacketType, "params");
  513. fParams.fProtocolVersion = SLAVE_PROTOCOL;
  514. SetPacketType (&fParams, SLAVE_AVAILABLE);
  515. net_status_t status;
  516. do
  517. {
  518. //get a master
  519. status = SendAvailableToMaster();
  520. if (status == NET_SOCKET_ERROR)
  521. return false;
  522. }
  523. while (status != NET_CONNECTED);
  524. return true;
  525. }
  526. bool JackNetSlaveInterface::InitRendering()
  527. {
  528. jack_log("JackNetSlaveInterface::InitRendering()");
  529. net_status_t status;
  530. do
  531. {
  532. //then tell the master we are ready
  533. jack_info("Initializing connection with %s...", fParams.fMasterNetName);
  534. status = SendStartToMaster();
  535. if (status == NET_ERROR)
  536. return false;
  537. }
  538. while (status != NET_ROLLING);
  539. return true;
  540. }
  541. net_status_t JackNetSlaveInterface::SendAvailableToMaster()
  542. {
  543. jack_log ( "JackNetSlaveInterface::SendAvailableToMaster()" );
  544. //utility
  545. session_params_t host_params;
  546. int rx_bytes = 0;
  547. //socket
  548. if ( fSocket.NewSocket() == SOCKET_ERROR ) {
  549. jack_error ( "Fatal error : network unreachable - %s", StrError ( NET_ERROR_CODE ) );
  550. return NET_SOCKET_ERROR;
  551. }
  552. //bind the socket
  553. if ( fSocket.Bind() == SOCKET_ERROR ) {
  554. jack_error ( "Can't bind the socket : %s", StrError ( NET_ERROR_CODE ) );
  555. return NET_SOCKET_ERROR;
  556. }
  557. //timeout on receive
  558. if ( fSocket.SetTimeOut ( SLAVE_INIT_TIMEOUT ) == SOCKET_ERROR )
  559. jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) );
  560. //disable local loop
  561. if ( fSocket.SetLocalLoop() == SOCKET_ERROR )
  562. jack_error ( "Can't disable multicast loop : %s", StrError ( NET_ERROR_CODE ) );
  563. //send 'AVAILABLE' until 'SLAVE_SETUP' received
  564. jack_info ( "Waiting for a master..." );
  565. do
  566. {
  567. //send 'available'
  568. session_params_t net_params;
  569. memset(&net_params, 0, sizeof ( session_params_t ));
  570. SessionParamsHToN(&fParams, &net_params);
  571. if ( fSocket.SendTo ( &net_params, sizeof ( session_params_t ), 0, fMulticastIP ) == SOCKET_ERROR )
  572. jack_error ( "Error in data send : %s", StrError ( NET_ERROR_CODE ) );
  573. //filter incoming packets : don't exit while no error is detected
  574. memset(&net_params, 0, sizeof ( session_params_t ));
  575. rx_bytes = fSocket.CatchHost ( &net_params, sizeof ( session_params_t ), 0 );
  576. SessionParamsNToH(&net_params, &host_params);
  577. if ( ( rx_bytes == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) )
  578. {
  579. jack_error ( "Can't receive : %s", StrError ( NET_ERROR_CODE ) );
  580. return NET_RECV_ERROR;
  581. }
  582. }
  583. while ( strcmp ( host_params.fPacketType, fParams.fPacketType ) && ( GetPacketType ( &host_params ) != SLAVE_SETUP ) );
  584. //everything is OK, copy parameters
  585. SessionParamsDisplay(&host_params);
  586. fParams = host_params;
  587. //connect the socket
  588. if ( fSocket.Connect() == SOCKET_ERROR ) {
  589. jack_error ( "Error in connect : %s", StrError ( NET_ERROR_CODE ) );
  590. return NET_CONNECT_ERROR;
  591. }
  592. return NET_CONNECTED;
  593. }
  594. net_status_t JackNetSlaveInterface::SendStartToMaster()
  595. {
  596. jack_log ( "JackNetSlaveInterface::SendStartToMaster" );
  597. //tell the master to start
  598. session_params_t net_params;
  599. memset(&net_params, 0, sizeof ( session_params_t ));
  600. SetPacketType ( &fParams, START_MASTER );
  601. SessionParamsHToN(&fParams, &net_params);
  602. if ( fSocket.Send ( &net_params, sizeof ( session_params_t ), 0 ) == SOCKET_ERROR )
  603. {
  604. jack_error ( "Error in send : %s", StrError ( NET_ERROR_CODE ) );
  605. return ( fSocket.GetError() == NET_CONN_ERROR ) ? NET_ERROR : NET_SEND_ERROR;
  606. }
  607. return NET_ROLLING;
  608. }
  609. bool JackNetSlaveInterface::SetParams()
  610. {
  611. jack_log ( "JackNetSlaveInterface::SetParams" );
  612. JackNetInterface::SetParams();
  613. fTxHeader.fDataStream = 'r';
  614. fRxHeader.fDataStream = 's';
  615. //midi net buffers
  616. fNetMidiCaptureBuffer = new NetMidiBuffer ( &fParams, fParams.fSendMidiChannels, fRxData );
  617. fNetMidiPlaybackBuffer = new NetMidiBuffer ( &fParams, fParams.fReturnMidiChannels, fTxData );
  618. assert ( fNetMidiCaptureBuffer );
  619. assert ( fNetMidiPlaybackBuffer );
  620. //audio net buffers
  621. //fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData );
  622. //fNetAudioPlaybackBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData );
  623. try {
  624. #ifdef CELT
  625. fNetAudioCaptureBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData );
  626. fNetAudioPlaybackBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData );
  627. #else
  628. fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData );
  629. fNetAudioPlaybackBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData );
  630. //fNetAudioCaptureBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData );
  631. //fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData );
  632. #endif
  633. } catch (exception&) {
  634. jack_error("NetAudioBuffer allocation error...");
  635. return false;
  636. }
  637. assert ( fNetAudioCaptureBuffer );
  638. assert ( fNetAudioPlaybackBuffer );
  639. //set the new buffer sizes
  640. if ( SetNetBufferSize() == SOCKET_ERROR ) {
  641. jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) );
  642. goto error;
  643. }
  644. return true;
  645. error:
  646. delete fNetMidiCaptureBuffer;
  647. delete fNetMidiPlaybackBuffer;
  648. delete fNetAudioCaptureBuffer;
  649. delete fNetAudioPlaybackBuffer;
  650. return false;
  651. }
  652. int JackNetSlaveInterface::Recv ( size_t size, int flags )
  653. {
  654. int rx_bytes = fSocket.Recv ( fRxBuffer, size, flags );
  655. //handle errors
  656. if ( rx_bytes == SOCKET_ERROR )
  657. {
  658. net_error_t error = fSocket.GetError();
  659. //no data isn't really an error in realtime processing, so just return 0
  660. if ( error == NET_NO_DATA ) {
  661. jack_error ( "No data, is the master still running ?" );
  662. //if a network error occurs, this exception will restart the driver
  663. } else if ( error == NET_CONN_ERROR ) {
  664. jack_error ( "Connection lost." );
  665. throw JackNetException();
  666. } else {
  667. jack_error ( "Fatal error in slave receive : %s", StrError ( NET_ERROR_CODE ) );
  668. }
  669. }
  670. packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer);
  671. PacketHeaderNToH(header, header);
  672. return rx_bytes;
  673. }
  674. int JackNetSlaveInterface::Send ( size_t size, int flags )
  675. {
  676. packet_header_t* header = reinterpret_cast<packet_header_t*>(fTxBuffer);
  677. PacketHeaderHToN(header, header);
  678. int tx_bytes = fSocket.Send ( fTxBuffer, size, flags );
  679. //handle errors
  680. if ( tx_bytes == SOCKET_ERROR )
  681. {
  682. net_error_t error = fSocket.GetError();
  683. //if a network error occurs, this exception will restart the driver
  684. if ( error == NET_CONN_ERROR ) {
  685. jack_error ( "Connection lost." );
  686. throw JackNetException();
  687. } else {
  688. jack_error ( "Fatal error in slave send : %s", StrError ( NET_ERROR_CODE ) );
  689. }
  690. }
  691. return tx_bytes;
  692. }
  693. int JackNetSlaveInterface::SyncRecv()
  694. {
  695. int rx_bytes = 0;
  696. packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
  697. //receive sync (launch the cycle)
  698. do
  699. {
  700. rx_bytes = Recv(HEADER_SIZE, 0);
  701. //connection issue, send will detect it, so don't skip the cycle (return 0)
  702. if ( rx_bytes == SOCKET_ERROR )
  703. return rx_bytes;
  704. }
  705. while ((strcmp(rx_head->fPacketType, "header") != 0) && (rx_head->fDataType != 's'));
  706. fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
  707. return rx_bytes;
  708. }
  709. int JackNetSlaveInterface::DataRecv()
  710. {
  711. int rx_bytes = 0;
  712. uint recvd_midi_pckt = 0;
  713. uint recvd_audio_pckt = 0;
  714. packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
  715. while ( !fRxHeader.fIsLastPckt )
  716. {
  717. //how much data is queued on the rx buffer ?
  718. rx_bytes = Recv(HEADER_SIZE, MSG_PEEK);
  719. //error here, problem with recv, just skip the cycle (return -1)
  720. if ( rx_bytes == SOCKET_ERROR )
  721. return rx_bytes;
  722. if ( rx_bytes && ( rx_head->fDataStream == 's' ) && ( rx_head->fID == fParams.fID ) )
  723. {
  724. switch ( rx_head->fDataType )
  725. {
  726. case 'm': //midi
  727. rx_bytes = Recv(rx_head->fPacketSize, 0);
  728. fRxHeader.fCycle = rx_head->fCycle;
  729. fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
  730. fNetMidiCaptureBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
  731. // Last midi packet is received, so finish rendering...
  732. if (++recvd_midi_pckt == rx_head->fNumPacket)
  733. fNetMidiCaptureBuffer->RenderToJackPorts();
  734. break;
  735. case 'a': //audio
  736. rx_bytes = Recv(rx_head->fPacketSize, 0);
  737. fRxHeader.fCycle = rx_head->fCycle;
  738. fRxHeader.fSubCycle = rx_head->fSubCycle;
  739. fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
  740. fNetAudioCaptureBuffer->RenderFromNetwork (rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
  741. // Last audio packet is received, so finish rendering...
  742. if (fRxHeader.fIsLastPckt)
  743. fNetAudioCaptureBuffer->RenderToJackPorts();
  744. break;
  745. case 's': //sync
  746. jack_info ( "NetSlave : overloaded, skipping receive." );
  747. // TODO : finish midi and audio rendering ?
  748. return 0;
  749. }
  750. }
  751. }
  752. fRxHeader.fCycle = rx_head->fCycle;
  753. return 0;
  754. }
  755. int JackNetSlaveInterface::SyncSend()
  756. {
  757. //tx header
  758. if ( fParams.fSlaveSyncMode ) {
  759. fTxHeader.fCycle = fRxHeader.fCycle;
  760. } else {
  761. fTxHeader.fCycle++;
  762. }
  763. fTxHeader.fSubCycle = 0;
  764. fTxHeader.fDataType = 's';
  765. fTxHeader.fIsLastPckt = (fParams.fReturnMidiChannels == 0 && fParams.fReturnAudioChannels == 0) ? 1 : 0;
  766. fTxHeader.fPacketSize = HEADER_SIZE;
  767. memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
  768. return Send (fTxHeader.fPacketSize, 0);
  769. }
  770. int JackNetSlaveInterface::DataSend()
  771. {
  772. uint subproc;
  773. uint data_size;
  774. //midi
  775. if (fParams.fReturnMidiChannels > 0)
  776. {
  777. //set global header fields and get the number of midi packets
  778. fTxHeader.fDataType = 'm';
  779. data_size = fNetMidiPlaybackBuffer->RenderFromJackPorts();
  780. fTxHeader.fNumPacket = fNetMidiPlaybackBuffer->GetNumPackets();
  781. for ( subproc = 0; subproc < fTxHeader.fNumPacket; subproc++ )
  782. {
  783. fTxHeader.fSubCycle = subproc;
  784. fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && !fParams.fReturnAudioChannels) ? 1 : 0;
  785. fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiPlaybackBuffer->RenderToNetwork(subproc, data_size);
  786. memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
  787. if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
  788. return SOCKET_ERROR;
  789. }
  790. }
  791. //audio
  792. if ( fParams.fReturnAudioChannels > 0)
  793. {
  794. fTxHeader.fDataType = 'a';
  795. data_size = fNetAudioPlaybackBuffer->RenderFromJackPorts();
  796. fTxHeader.fNumPacket = fNetAudioPlaybackBuffer->GetNumPackets();
  797. for ( subproc = 0; subproc < fTxHeader.fNumPacket; subproc++ )
  798. {
  799. fTxHeader.fSubCycle = subproc;
  800. fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0;
  801. fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioPlaybackBuffer->RenderToNetwork(subproc, data_size);
  802. memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
  803. if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
  804. return SOCKET_ERROR;
  805. }
  806. }
  807. return 0;
  808. }
  809. //network sync------------------------------------------------------------------------
  810. void JackNetSlaveInterface::EncodeSyncPacket()
  811. {
  812. //this method contains every step of sync packet informations coding
  813. //first of all, reset sync packet
  814. memset ( fTxData, 0, PACKET_AVAILABLE_SIZE );
  815. //then first step : transport
  816. if (fParams.fTransportSync) {
  817. EncodeTransportData();
  818. TransportDataHToN( &fReturnTransportData, &fReturnTransportData);
  819. //copy to TxBuffer
  820. memcpy ( fTxData, &fReturnTransportData, sizeof ( net_transport_data_t ) );
  821. }
  822. //then others
  823. //...
  824. }
  825. void JackNetSlaveInterface::DecodeSyncPacket()
  826. {
  827. //this method contains every step of sync packet informations decoding process
  828. //first : transport
  829. if (fParams.fTransportSync) {
  830. //copy received transport data to transport data structure
  831. memcpy ( &fSendTransportData, fRxData, sizeof ( net_transport_data_t ) );
  832. TransportDataNToH( &fSendTransportData, &fSendTransportData);
  833. DecodeTransportData();
  834. }
  835. //then others
  836. //...
  837. }
  838. }