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.

976 lines
37KB

  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. //audio net buffers
  200. fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData );
  201. fNetAudioPlaybackBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData );
  202. //fNetAudioCaptureBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData );
  203. //fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData );
  204. assert ( fNetAudioCaptureBuffer );
  205. assert ( fNetAudioPlaybackBuffer );
  206. //set the new timeout for the socket
  207. if ( SetRxTimeout() == SOCKET_ERROR ) {
  208. jack_error ( "Can't set rx timeout : %s", StrError ( NET_ERROR_CODE ) );
  209. goto error;
  210. }
  211. //set the new rx buffer size
  212. if ( SetNetBufferSize() == SOCKET_ERROR ) {
  213. jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) );
  214. goto error;
  215. }
  216. return true;
  217. error:
  218. delete fNetMidiCaptureBuffer;
  219. delete fNetMidiPlaybackBuffer;
  220. delete fNetAudioCaptureBuffer;
  221. delete fNetAudioPlaybackBuffer;
  222. return false;
  223. }
  224. void JackNetMasterInterface::Exit()
  225. {
  226. jack_log ( "JackNetMasterInterface::Exit, ID %u", fParams.fID );
  227. //stop process
  228. fRunning = false;
  229. //send a 'multicast euthanasia request' - new socket is required on macosx
  230. jack_info ( "Exiting '%s'", fParams.fName );
  231. SetPacketType ( &fParams, KILL_MASTER );
  232. JackNetSocket mcast_socket ( fMulticastIP, fSocket.GetPort() );
  233. session_params_t net_params;
  234. memset(&net_params, 0, sizeof ( session_params_t ));
  235. SessionParamsHToN(&fParams, &net_params);
  236. if ( mcast_socket.NewSocket() == SOCKET_ERROR )
  237. jack_error ( "Can't create socket : %s", StrError ( NET_ERROR_CODE ) );
  238. if ( mcast_socket.SendTo ( &net_params, sizeof ( session_params_t ), 0, fMulticastIP ) == SOCKET_ERROR )
  239. jack_error ( "Can't send suicide request : %s", StrError ( NET_ERROR_CODE ) );
  240. mcast_socket.Close();
  241. }
  242. int JackNetMasterInterface::Recv ( size_t size, int flags )
  243. {
  244. int rx_bytes;
  245. if ((( rx_bytes = fSocket.Recv(fRxBuffer, size, flags)) == SOCKET_ERROR) && fRunning) {
  246. net_error_t error = fSocket.GetError();
  247. //no data isn't really a network error, so just return 0 available read bytes
  248. if (error == NET_NO_DATA) {
  249. return 0;
  250. } else if (error == NET_CONN_ERROR) {
  251. //fatal connection issue, exit
  252. jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError(NET_ERROR_CODE));
  253. //ask to the manager to properly remove the master
  254. Exit();
  255. // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
  256. ThreadExit();
  257. } else {
  258. jack_error ( "Error in master receive : %s", StrError(NET_ERROR_CODE));
  259. }
  260. }
  261. packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer);
  262. PacketHeaderNToH(header, header);
  263. return rx_bytes;
  264. }
  265. int JackNetMasterInterface::Send ( size_t size, int flags )
  266. {
  267. int tx_bytes;
  268. packet_header_t* header = reinterpret_cast<packet_header_t*>(fTxBuffer);
  269. PacketHeaderHToN(header, header);
  270. if (((tx_bytes = fSocket.Send(fTxBuffer, size, flags)) == SOCKET_ERROR) && fRunning) {
  271. net_error_t error = fSocket.GetError();
  272. if (error == NET_CONN_ERROR) {
  273. //fatal connection issue, exit
  274. jack_error ("'%s' : %s, exiting.", fParams.fName, StrError (NET_ERROR_CODE));
  275. Exit();
  276. // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
  277. ThreadExit();
  278. } else {
  279. jack_error("Error in master send : %s", StrError(NET_ERROR_CODE));
  280. }
  281. }
  282. return tx_bytes;
  283. }
  284. bool JackNetMasterInterface::IsSynched()
  285. {
  286. if (fParams.fNetworkMode == 's') {
  287. return (fCycleOffset < (CYCLE_OFFSET_SLOW + 1));
  288. } else {
  289. return true;
  290. }
  291. }
  292. int JackNetMasterInterface::SyncSend()
  293. {
  294. fTxHeader.fCycle++;
  295. fTxHeader.fSubCycle = 0;
  296. fTxHeader.fDataType = 's';
  297. fTxHeader.fIsLastPckt = ( fParams.fSendMidiChannels == 0 && fParams.fSendAudioChannels == 0) ? 1 : 0;
  298. fTxHeader.fPacketSize = HEADER_SIZE;
  299. memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
  300. return Send(fTxHeader.fPacketSize, 0);
  301. }
  302. int JackNetMasterInterface::DataSend()
  303. {
  304. uint subproc;
  305. uint data_size;
  306. //midi
  307. if ( fParams.fSendMidiChannels > 0)
  308. {
  309. //set global header fields and get the number of midi packets
  310. fTxHeader.fDataType = 'm';
  311. data_size = fNetMidiCaptureBuffer->RenderFromJackPorts();
  312. fTxHeader.fNumPacket = fNetMidiCaptureBuffer->GetNumPackets();
  313. for ( subproc = 0; subproc < fTxHeader.fNumPacket; subproc++ )
  314. {
  315. fTxHeader.fSubCycle = subproc;
  316. fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && (fParams.fSendAudioChannels == 0)) ? 1 : 0;
  317. fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiCaptureBuffer->RenderToNetwork(subproc, data_size);
  318. memcpy ( fTxBuffer, &fTxHeader, HEADER_SIZE);
  319. if (Send (fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
  320. return SOCKET_ERROR;
  321. }
  322. }
  323. //audio
  324. if ( fParams.fSendAudioChannels > 0)
  325. {
  326. fTxHeader.fDataType = 'a';
  327. data_size = fNetAudioCaptureBuffer->RenderFromJackPorts();
  328. fTxHeader.fNumPacket = fNetAudioCaptureBuffer->GetNumPackets();
  329. for (subproc = 0; subproc < fTxHeader.fNumPacket; subproc++)
  330. {
  331. fTxHeader.fSubCycle = subproc;
  332. fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0;
  333. fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioCaptureBuffer->RenderToNetwork(subproc, data_size);
  334. memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
  335. if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
  336. return SOCKET_ERROR;
  337. }
  338. }
  339. return 0;
  340. }
  341. int JackNetMasterInterface::SyncRecv()
  342. {
  343. packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
  344. int rx_bytes = Recv(HEADER_SIZE, MSG_PEEK);
  345. if ( ( rx_bytes == 0 ) || ( rx_bytes == SOCKET_ERROR ) )
  346. return rx_bytes;
  347. fCycleOffset = fTxHeader.fCycle - rx_head->fCycle;
  348. switch ( fParams.fNetworkMode )
  349. {
  350. case 's' :
  351. //slow mode : allow to use full bandwidth and heavy process on the slave
  352. // - extra latency is set to two cycles, one cycle for send/receive operations + one cycle for heavy process on the slave
  353. // - if the network is two fast, just wait the next cycle, this mode allows a shorter cycle duration for the master
  354. // - this mode will skip the two first cycles, thus it lets time for data to be processed and queued on the socket rx buffer
  355. //the slow mode is the safest mode because it wait twice the bandwidth relative time (send/return + process)
  356. if (fCycleOffset < CYCLE_OFFSET_SLOW) {
  357. return 0;
  358. } else {
  359. rx_bytes = Recv ( rx_head->fPacketSize, 0 );
  360. }
  361. if (fCycleOffset > CYCLE_OFFSET_SLOW) {
  362. jack_info("Warning : '%s' runs in slow network mode, but data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
  363. }
  364. break;
  365. case 'n' :
  366. //normal use of the network :
  367. // - extra latency is set to one cycle, what is the time needed to receive streams using full network bandwidth
  368. // - if the network is too fast, just wait the next cycle, the benefit here is the master's cycle is shorter
  369. // - indeed, data is supposed to be on the network rx buffer, so we don't have to wait for it
  370. if (fCycleOffset < CYCLE_OFFSET_NORMAL) {
  371. return 0;
  372. } else {
  373. rx_bytes = Recv ( rx_head->fPacketSize, 0 );
  374. }
  375. if (fCycleOffset > CYCLE_OFFSET_NORMAL) {
  376. jack_info("'%s' can't run in normal network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
  377. }
  378. break;
  379. case 'f' :
  380. //fast mode suppose the network bandwith is larger than required for the transmission (only a few channels for example)
  381. // - packets can be quickly received, quickly is here relative to the cycle duration
  382. // - here, receive data, we can't keep it queued on the rx buffer,
  383. // - but if there is a cycle offset, tell the user, that means we're not in fast mode anymore, network is too slow
  384. rx_bytes = Recv ( rx_head->fPacketSize, 0 );
  385. if (fCycleOffset > CYCLE_OFFSET_FAST) {
  386. jack_info("'%s' can't run in fast network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
  387. }
  388. break;
  389. }
  390. fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
  391. return rx_bytes;
  392. }
  393. int JackNetMasterInterface::DataRecv()
  394. {
  395. int rx_bytes = 0;
  396. uint recvd_midi_pckt = 0;
  397. uint recvd_audio_pckt = 0;
  398. packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
  399. while ( !fRxHeader.fIsLastPckt )
  400. {
  401. //how much data is queued on the rx buffer ?
  402. rx_bytes = Recv(HEADER_SIZE, MSG_PEEK);
  403. //error here, problem with recv, just skip the cycle (return -1)
  404. if ( rx_bytes == SOCKET_ERROR )
  405. return rx_bytes;
  406. if ( rx_bytes && ( rx_head->fDataStream == 'r' ) && ( rx_head->fID == fParams.fID ) )
  407. {
  408. //read data
  409. switch ( rx_head->fDataType )
  410. {
  411. case 'm': //midi
  412. rx_bytes = Recv ( rx_head->fPacketSize, 0 );
  413. fRxHeader.fCycle = rx_head->fCycle;
  414. fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
  415. fNetMidiPlaybackBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
  416. // Last midi packet is received, so finish rendering...
  417. if (++recvd_midi_pckt == rx_head->fNumPacket)
  418. fNetMidiPlaybackBuffer->RenderToJackPorts();
  419. break;
  420. case 'a': //audio
  421. rx_bytes = Recv ( rx_head->fPacketSize, 0 );
  422. fRxHeader.fCycle = rx_head->fCycle;
  423. fRxHeader.fSubCycle = rx_head->fSubCycle;
  424. fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
  425. fNetAudioPlaybackBuffer->RenderFromNetwork (rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
  426. // Last audio packet is received, so finish rendering...
  427. if (fRxHeader.fIsLastPckt)
  428. fNetAudioPlaybackBuffer->RenderToJackPorts();
  429. break;
  430. case 's': //sync
  431. jack_info("NetMaster : overloaded, skipping receive from '%s'", fParams.fName);
  432. // TODO : finish midi and audio rendering ?
  433. return 0;
  434. }
  435. }
  436. }
  437. return rx_bytes;
  438. }
  439. void JackNetMasterInterface::EncodeSyncPacket()
  440. {
  441. //this method contains every step of sync packet informations coding
  442. //first of all, reset sync packet
  443. memset ( fTxData, 0, PACKET_AVAILABLE_SIZE );
  444. //then, first step : transport
  445. if (fParams.fTransportSync) {
  446. EncodeTransportData();
  447. TransportDataHToN( &fSendTransportData, &fSendTransportData);
  448. //copy to TxBuffer
  449. memcpy ( fTxData, &fSendTransportData, sizeof ( net_transport_data_t ) );
  450. }
  451. //then others (freewheel etc.)
  452. //...
  453. }
  454. void JackNetMasterInterface::DecodeSyncPacket()
  455. {
  456. //this method contains every step of sync packet informations decoding process
  457. //first : transport
  458. if (fParams.fTransportSync) {
  459. //copy received transport data to transport data structure
  460. memcpy ( &fReturnTransportData, fRxData, sizeof ( net_transport_data_t ) );
  461. TransportDataNToH( &fReturnTransportData, &fReturnTransportData);
  462. DecodeTransportData();
  463. }
  464. //then others
  465. //...
  466. }
  467. // JackNetSlaveInterface ************************************************************************************************
  468. uint JackNetSlaveInterface::fSlaveCounter = 0;
  469. bool JackNetSlaveInterface::Init()
  470. {
  471. jack_log ( "JackNetSlaveInterface::Init()" );
  472. //set the parameters to send
  473. strcpy ( fParams.fPacketType, "params" );
  474. fParams.fProtocolVersion = SLAVE_PROTOCOL;
  475. SetPacketType ( &fParams, SLAVE_AVAILABLE );
  476. //init loop : get a master and start, do it until connection is ok
  477. net_status_t status;
  478. do
  479. {
  480. //first, get a master, do it until a valid connection is running
  481. do
  482. {
  483. status = SendAvailableToMaster();
  484. if ( status == NET_SOCKET_ERROR )
  485. return false;
  486. }
  487. while ( status != NET_CONNECTED );
  488. //then tell the master we are ready
  489. jack_info ( "Initializing connection with %s...", fParams.fMasterNetName );
  490. status = SendStartToMaster();
  491. if ( status == NET_ERROR )
  492. return false;
  493. }
  494. while ( status != NET_ROLLING );
  495. return true;
  496. }
  497. // Separate the connection protocol into two separated step
  498. bool JackNetSlaveInterface::InitConnection()
  499. {
  500. jack_log ( "JackNetSlaveInterface::InitConnection()" );
  501. //set the parameters to send
  502. strcpy (fParams.fPacketType, "params");
  503. fParams.fProtocolVersion = SLAVE_PROTOCOL;
  504. SetPacketType (&fParams, SLAVE_AVAILABLE);
  505. net_status_t status;
  506. do
  507. {
  508. //get a master
  509. status = SendAvailableToMaster();
  510. if (status == NET_SOCKET_ERROR)
  511. return false;
  512. }
  513. while (status != NET_CONNECTED);
  514. return true;
  515. }
  516. bool JackNetSlaveInterface::InitRendering()
  517. {
  518. jack_log("JackNetSlaveInterface::InitRendering()");
  519. net_status_t status;
  520. do
  521. {
  522. //then tell the master we are ready
  523. jack_info("Initializing connection with %s...", fParams.fMasterNetName);
  524. status = SendStartToMaster();
  525. if (status == NET_ERROR)
  526. return false;
  527. }
  528. while (status != NET_ROLLING);
  529. return true;
  530. }
  531. net_status_t JackNetSlaveInterface::SendAvailableToMaster()
  532. {
  533. jack_log ( "JackNetSlaveInterface::SendAvailableToMaster()" );
  534. //utility
  535. session_params_t host_params;
  536. int rx_bytes = 0;
  537. jack_log ( "sizeof (session_params_t) %d", sizeof (session_params_t) );
  538. //socket
  539. if ( fSocket.NewSocket() == SOCKET_ERROR ) {
  540. jack_error ( "Fatal error : network unreachable - %s", StrError ( NET_ERROR_CODE ) );
  541. return NET_SOCKET_ERROR;
  542. }
  543. //bind the socket
  544. if ( fSocket.Bind() == SOCKET_ERROR ) {
  545. jack_error ( "Can't bind the socket : %s", StrError ( NET_ERROR_CODE ) );
  546. return NET_SOCKET_ERROR;
  547. }
  548. //timeout on receive
  549. if ( fSocket.SetTimeOut ( SLAVE_INIT_TIMEOUT ) == SOCKET_ERROR )
  550. jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) );
  551. //disable local loop
  552. if ( fSocket.SetLocalLoop() == SOCKET_ERROR )
  553. jack_error ( "Can't disable multicast loop : %s", StrError ( NET_ERROR_CODE ) );
  554. //send 'AVAILABLE' until 'SLAVE_SETUP' received
  555. jack_info ( "Waiting for a master..." );
  556. do
  557. {
  558. //send 'available'
  559. session_params_t net_params;
  560. memset(&net_params, 0, sizeof ( session_params_t ));
  561. SessionParamsHToN(&fParams, &net_params);
  562. if ( fSocket.SendTo ( &net_params, sizeof ( session_params_t ), 0, fMulticastIP ) == SOCKET_ERROR )
  563. jack_error ( "Error in data send : %s", StrError ( NET_ERROR_CODE ) );
  564. //filter incoming packets : don't exit while no error is detected
  565. memset(&net_params, 0, sizeof ( session_params_t ));
  566. rx_bytes = fSocket.CatchHost ( &net_params, sizeof ( session_params_t ), 0 );
  567. SessionParamsNToH(&net_params, &host_params);
  568. if ( ( rx_bytes == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) )
  569. {
  570. jack_error ( "Can't receive : %s", StrError ( NET_ERROR_CODE ) );
  571. return NET_RECV_ERROR;
  572. }
  573. }
  574. while ( strcmp ( host_params.fPacketType, fParams.fPacketType ) && ( GetPacketType ( &host_params ) != SLAVE_SETUP ) );
  575. //everything is OK, copy parameters
  576. SessionParamsDisplay(&host_params);
  577. fParams = host_params;
  578. //connect the socket
  579. if ( fSocket.Connect() == SOCKET_ERROR ) {
  580. jack_error ( "Error in connect : %s", StrError ( NET_ERROR_CODE ) );
  581. return NET_CONNECT_ERROR;
  582. }
  583. return NET_CONNECTED;
  584. }
  585. net_status_t JackNetSlaveInterface::SendStartToMaster()
  586. {
  587. jack_log ( "JackNetSlaveInterface::SendStartToMaster" );
  588. //tell the master to start
  589. session_params_t net_params;
  590. memset(&net_params, 0, sizeof ( session_params_t ));
  591. SetPacketType ( &fParams, START_MASTER );
  592. SessionParamsHToN(&fParams, &net_params);
  593. if ( fSocket.Send ( &net_params, sizeof ( session_params_t ), 0 ) == SOCKET_ERROR )
  594. {
  595. jack_error ( "Error in send : %s", StrError ( NET_ERROR_CODE ) );
  596. return ( fSocket.GetError() == NET_CONN_ERROR ) ? NET_ERROR : NET_SEND_ERROR;
  597. }
  598. return NET_ROLLING;
  599. }
  600. bool JackNetSlaveInterface::SetParams()
  601. {
  602. jack_log ( "JackNetSlaveInterface::SetParams" );
  603. JackNetInterface::SetParams();
  604. fTxHeader.fDataStream = 'r';
  605. fRxHeader.fDataStream = 's';
  606. //midi net buffers
  607. fNetMidiCaptureBuffer = new NetMidiBuffer ( &fParams, fParams.fSendMidiChannels, fRxData );
  608. fNetMidiPlaybackBuffer = new NetMidiBuffer ( &fParams, fParams.fReturnMidiChannels, fTxData );
  609. assert ( fNetMidiCaptureBuffer );
  610. assert ( fNetMidiPlaybackBuffer );
  611. //audio net buffers
  612. fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData );
  613. fNetAudioPlaybackBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData );
  614. //fNetAudioCaptureBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData );
  615. //fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData );
  616. assert ( fNetAudioCaptureBuffer );
  617. assert ( fNetAudioPlaybackBuffer );
  618. //set the new buffer sizes
  619. if ( SetNetBufferSize() == SOCKET_ERROR ) {
  620. jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) );
  621. goto error;
  622. }
  623. return true;
  624. error:
  625. delete fNetMidiCaptureBuffer;
  626. delete fNetMidiPlaybackBuffer;
  627. delete fNetAudioCaptureBuffer;
  628. delete fNetAudioPlaybackBuffer;
  629. return false;
  630. }
  631. int JackNetSlaveInterface::Recv ( size_t size, int flags )
  632. {
  633. int rx_bytes = fSocket.Recv ( fRxBuffer, size, flags );
  634. //handle errors
  635. if ( rx_bytes == SOCKET_ERROR )
  636. {
  637. net_error_t error = fSocket.GetError();
  638. //no data isn't really an error in realtime processing, so just return 0
  639. if ( error == NET_NO_DATA ) {
  640. jack_error ( "No data, is the master still running ?" );
  641. //if a network error occurs, this exception will restart the driver
  642. } else if ( error == NET_CONN_ERROR ) {
  643. jack_error ( "Connection lost." );
  644. throw JackNetException();
  645. } else {
  646. jack_error ( "Fatal error in slave receive : %s", StrError ( NET_ERROR_CODE ) );
  647. }
  648. }
  649. packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer);
  650. PacketHeaderNToH(header, header);
  651. return rx_bytes;
  652. }
  653. int JackNetSlaveInterface::Send ( size_t size, int flags )
  654. {
  655. packet_header_t* header = reinterpret_cast<packet_header_t*>(fTxBuffer);
  656. PacketHeaderHToN(header, header);
  657. int tx_bytes = fSocket.Send ( fTxBuffer, size, flags );
  658. //handle errors
  659. if ( tx_bytes == SOCKET_ERROR )
  660. {
  661. net_error_t error = fSocket.GetError();
  662. //if a network error occurs, this exception will restart the driver
  663. if ( error == NET_CONN_ERROR ) {
  664. jack_error ( "Connection lost." );
  665. throw JackNetException();
  666. } else {
  667. jack_error ( "Fatal error in slave send : %s", StrError ( NET_ERROR_CODE ) );
  668. }
  669. }
  670. return tx_bytes;
  671. }
  672. int JackNetSlaveInterface::SyncRecv()
  673. {
  674. int rx_bytes = 0;
  675. packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
  676. //receive sync (launch the cycle)
  677. do
  678. {
  679. rx_bytes = Recv(HEADER_SIZE, 0);
  680. //connection issue, send will detect it, so don't skip the cycle (return 0)
  681. if ( rx_bytes == SOCKET_ERROR )
  682. return rx_bytes;
  683. }
  684. while ((strcmp(rx_head->fPacketType, "header") != 0) && (rx_head->fDataType != 's'));
  685. fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
  686. return rx_bytes;
  687. }
  688. int JackNetSlaveInterface::DataRecv()
  689. {
  690. int rx_bytes = 0;
  691. //int last_cycle = 0;
  692. uint recvd_midi_pckt = 0;
  693. uint recvd_audio_pckt = 0;
  694. packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
  695. while ( !fRxHeader.fIsLastPckt )
  696. {
  697. //how much data is queued on the rx buffer ?
  698. rx_bytes = Recv(HEADER_SIZE, MSG_PEEK);
  699. //error here, problem with recv, just skip the cycle (return -1)
  700. if ( rx_bytes == SOCKET_ERROR )
  701. return rx_bytes;
  702. if ( rx_bytes && ( rx_head->fDataStream == 's' ) && ( rx_head->fID == fParams.fID ) )
  703. {
  704. switch ( rx_head->fDataType )
  705. {
  706. case 'm': //midi
  707. rx_bytes = Recv ( rx_head->fPacketSize, 0 );
  708. fRxHeader.fCycle = rx_head->fCycle;
  709. fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
  710. fNetMidiCaptureBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
  711. // Last midi packet is received, so finish rendering...
  712. if ( ++recvd_midi_pckt == rx_head->fNumPacket )
  713. fNetMidiCaptureBuffer->RenderToJackPorts();
  714. break;
  715. case 'a': //audio
  716. rx_bytes = Recv ( rx_head->fPacketSize, 0 );
  717. fRxHeader.fCycle = rx_head->fCycle;
  718. fRxHeader.fSubCycle = rx_head->fSubCycle;
  719. fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
  720. fNetAudioCaptureBuffer->RenderFromNetwork (rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
  721. if (fRxHeader.fIsLastPckt) {
  722. fNetAudioCaptureBuffer->RenderToJackPorts();
  723. }
  724. break;
  725. case 's': //sync
  726. jack_info ( "NetSlave : overloaded, skipping receive." );
  727. // TODO : finish midi and audio rendering ?
  728. return 0;
  729. }
  730. }
  731. }
  732. fRxHeader.fCycle = rx_head->fCycle;
  733. return 0;
  734. }
  735. int JackNetSlaveInterface::SyncSend()
  736. {
  737. //tx header
  738. if ( fParams.fSlaveSyncMode ) {
  739. fTxHeader.fCycle = fRxHeader.fCycle;
  740. } else {
  741. fTxHeader.fCycle++;
  742. }
  743. fTxHeader.fSubCycle = 0;
  744. fTxHeader.fDataType = 's';
  745. fTxHeader.fIsLastPckt = (fParams.fReturnMidiChannels == 0 && fParams.fReturnAudioChannels == 0) ? 1 : 0;
  746. fTxHeader.fPacketSize = HEADER_SIZE;
  747. memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
  748. return Send (fTxHeader.fPacketSize, 0);
  749. }
  750. int JackNetSlaveInterface::DataSend()
  751. {
  752. uint subproc;
  753. uint data_size;
  754. //midi
  755. if (fParams.fReturnMidiChannels > 0)
  756. {
  757. //set global header fields and get the number of midi packets
  758. fTxHeader.fDataType = 'm';
  759. data_size = fNetMidiPlaybackBuffer->RenderFromJackPorts();
  760. fTxHeader.fNumPacket = fNetMidiPlaybackBuffer->GetNumPackets();
  761. for ( subproc = 0; subproc < fTxHeader.fNumPacket; subproc++ )
  762. {
  763. fTxHeader.fSubCycle = subproc;
  764. fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && !fParams.fReturnAudioChannels) ? 1 : 0;
  765. fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiPlaybackBuffer->RenderToNetwork(subproc, data_size);
  766. memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
  767. if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
  768. return SOCKET_ERROR;
  769. }
  770. }
  771. //audio
  772. if ( fParams.fReturnAudioChannels > 0)
  773. {
  774. fTxHeader.fDataType = 'a';
  775. data_size = fNetAudioPlaybackBuffer->RenderFromJackPorts();
  776. fTxHeader.fNumPacket = fNetAudioPlaybackBuffer->GetNumPackets();
  777. for ( subproc = 0; subproc < fTxHeader.fNumPacket; subproc++ )
  778. {
  779. fTxHeader.fSubCycle = subproc;
  780. fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0;
  781. fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioPlaybackBuffer->RenderToNetwork(subproc, data_size);
  782. memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
  783. if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
  784. return SOCKET_ERROR;
  785. }
  786. }
  787. return 0;
  788. }
  789. //network sync------------------------------------------------------------------------
  790. void JackNetSlaveInterface::EncodeSyncPacket()
  791. {
  792. //this method contains every step of sync packet informations coding
  793. //first of all, reset sync packet
  794. memset ( fTxData, 0, PACKET_AVAILABLE_SIZE );
  795. //then first step : transport
  796. if (fParams.fTransportSync) {
  797. EncodeTransportData();
  798. TransportDataHToN( &fReturnTransportData, &fReturnTransportData);
  799. //copy to TxBuffer
  800. memcpy ( fTxData, &fReturnTransportData, sizeof ( net_transport_data_t ) );
  801. }
  802. //then others
  803. //...
  804. }
  805. void JackNetSlaveInterface::DecodeSyncPacket()
  806. {
  807. //this method contains every step of sync packet informations decoding process
  808. //first : transport
  809. if (fParams.fTransportSync) {
  810. //copy received transport data to transport data structure
  811. memcpy ( &fSendTransportData, fRxData, sizeof ( net_transport_data_t ) );
  812. TransportDataNToH( &fSendTransportData, &fSendTransportData);
  813. DecodeTransportData();
  814. }
  815. //then others
  816. //...
  817. }
  818. }