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.

1010 lines
39KB

  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. Initialize();
  34. }
  35. JackNetInterface::JackNetInterface ( const char* multicast_ip, int port ) : fSocket ( multicast_ip, port )
  36. {
  37. strcpy(fMulticastIP, multicast_ip);
  38. Initialize();
  39. }
  40. JackNetInterface::JackNetInterface ( session_params_t& params, JackNetSocket& socket, const char* multicast_ip ) : fSocket ( socket )
  41. {
  42. fParams = params;
  43. strcpy(fMulticastIP, multicast_ip);
  44. Initialize();
  45. }
  46. void JackNetInterface::Initialize()
  47. {
  48. fTxBuffer = NULL;
  49. fRxBuffer = NULL;
  50. fNetAudioCaptureBuffer = NULL;
  51. fNetAudioPlaybackBuffer = NULL;
  52. fNetMidiCaptureBuffer = NULL;
  53. fNetMidiPlaybackBuffer = NULL;
  54. memset(&fSendTransportData, 0, sizeof(net_transport_data_t));
  55. memset(&fReturnTransportData, 0, sizeof(net_transport_data_t));
  56. }
  57. void JackNetInterface::FreeNetworkBuffers()
  58. {
  59. delete fNetMidiCaptureBuffer;
  60. delete fNetMidiPlaybackBuffer;
  61. delete fNetAudioCaptureBuffer;
  62. delete fNetAudioPlaybackBuffer;
  63. fNetMidiCaptureBuffer = NULL;
  64. fNetMidiPlaybackBuffer = NULL;
  65. fNetAudioCaptureBuffer = NULL;
  66. fNetAudioPlaybackBuffer = NULL;
  67. }
  68. JackNetInterface::~JackNetInterface()
  69. {
  70. jack_log ("JackNetInterface::~JackNetInterface");
  71. fSocket.Close();
  72. delete[] fTxBuffer;
  73. delete[] fRxBuffer;
  74. delete fNetAudioCaptureBuffer;
  75. delete fNetAudioPlaybackBuffer;
  76. delete fNetMidiCaptureBuffer;
  77. delete fNetMidiPlaybackBuffer;
  78. }
  79. int JackNetInterface::SetNetBufferSize()
  80. {
  81. //audio
  82. float audio_size = (fNetAudioCaptureBuffer)
  83. ? fNetAudioCaptureBuffer->GetCycleSize()
  84. : (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleSize() : 0;
  85. jack_log ("audio_size %f", audio_size);
  86. //midi
  87. float midi_size = (fNetMidiCaptureBuffer)
  88. ? fNetMidiCaptureBuffer->GetCycleSize()
  89. : (fNetMidiPlaybackBuffer) ? fNetMidiPlaybackBuffer->GetCycleSize() : 0;
  90. jack_log ("midi_size %f", midi_size);
  91. //bufsize = sync + audio + midi
  92. int bufsize = MAX_LATENCY * (fParams.fMtu + (int)audio_size + (int) midi_size);
  93. jack_log("SetNetBufferSize bufsize = %d", bufsize);
  94. //tx buffer
  95. if (fSocket.SetOption(SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)) == SOCKET_ERROR)
  96. return SOCKET_ERROR;
  97. //rx buffer
  98. if (fSocket.SetOption(SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)) == SOCKET_ERROR)
  99. return SOCKET_ERROR;
  100. return 0;
  101. }
  102. bool JackNetInterface::SetParams()
  103. {
  104. //TX header init
  105. strcpy ( fTxHeader.fPacketType, "header" );
  106. fTxHeader.fID = fParams.fID;
  107. fTxHeader.fCycle = 0;
  108. fTxHeader.fSubCycle = 0;
  109. fTxHeader.fBitdepth = fParams.fBitdepth;
  110. fTxHeader.fIsLastPckt = 0;
  111. //RX header init
  112. strcpy ( fRxHeader.fPacketType, "header" );
  113. fRxHeader.fID = fParams.fID;
  114. fRxHeader.fCycle = 0;
  115. fRxHeader.fSubCycle = 0;
  116. fRxHeader.fBitdepth = fParams.fBitdepth;
  117. fRxHeader.fIsLastPckt = 0;
  118. //network buffers
  119. fTxBuffer = new char[fParams.fMtu];
  120. fRxBuffer = new char[fParams.fMtu];
  121. assert ( fTxBuffer );
  122. assert ( fRxBuffer );
  123. //net audio/midi buffers'addresses
  124. fTxData = fTxBuffer + HEADER_SIZE;
  125. fRxData = fRxBuffer + HEADER_SIZE;
  126. return true;
  127. }
  128. // JackNetMasterInterface ************************************************************************************
  129. bool JackNetMasterInterface::Init()
  130. {
  131. jack_log ( "JackNetMasterInterface::Init, ID %u.", fParams.fID );
  132. session_params_t host_params;
  133. uint attempt = 0;
  134. int rx_bytes = 0;
  135. //socket
  136. if ( fSocket.NewSocket() == SOCKET_ERROR ) {
  137. jack_error ( "Can't create socket : %s", StrError ( NET_ERROR_CODE ) );
  138. return false;
  139. }
  140. //timeout on receive (for init)
  141. if ( fSocket.SetTimeOut ( MASTER_INIT_TIMEOUT ) < 0 )
  142. jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) );
  143. //connect
  144. if ( fSocket.Connect() == SOCKET_ERROR ) {
  145. jack_error ( "Can't connect : %s", StrError ( NET_ERROR_CODE ) );
  146. return false;
  147. }
  148. //send 'SLAVE_SETUP' until 'START_MASTER' received
  149. jack_info ( "Sending parameters to %s...", fParams.fSlaveNetName );
  150. do
  151. {
  152. session_params_t net_params;
  153. memset(&net_params, 0, sizeof ( session_params_t ));
  154. SetPacketType ( &fParams, SLAVE_SETUP );
  155. SessionParamsHToN(&fParams, &net_params);
  156. if ( fSocket.Send ( &net_params, sizeof ( session_params_t ), 0 ) == SOCKET_ERROR )
  157. jack_error ( "Error in send : ", StrError ( NET_ERROR_CODE ) );
  158. memset(&net_params, 0, sizeof (session_params_t));
  159. if (((rx_bytes = fSocket.Recv(&net_params, sizeof(session_params_t), 0)) == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA))
  160. {
  161. jack_error ( "Problem with network." );
  162. return false;
  163. }
  164. SessionParamsNToH(&net_params, &host_params);
  165. }
  166. while ( ( GetPacketType ( &host_params ) != START_MASTER ) && ( ++attempt < SLAVE_SETUP_RETRY ) );
  167. if ( attempt == SLAVE_SETUP_RETRY ) {
  168. jack_error ( "Slave doesn't respond, exiting." );
  169. return false;
  170. }
  171. return true;
  172. }
  173. int JackNetMasterInterface::SetRxTimeout()
  174. {
  175. jack_log ( "JackNetMasterInterface::SetRxTimeout" );
  176. float time = 0;
  177. //slow or normal mode, short timeout on recv (2 audio subcycles)
  178. if ((fParams.fNetworkMode == 's') || (fParams.fNetworkMode == 'n')) {
  179. time = 2000000.f * ((fNetAudioCaptureBuffer)
  180. ? fNetAudioCaptureBuffer->GetCycleDuration()
  181. : (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleDuration() : 0);
  182. }
  183. //fast mode, wait for 75% of the entire cycle duration
  184. else if (fParams.fNetworkMode == 'f') {
  185. time = 750000.f * (static_cast<float>(fParams.fPeriodSize) / static_cast<float>(fParams.fSampleRate));
  186. }
  187. return fSocket.SetTimeOut (static_cast<int>(time));
  188. }
  189. bool JackNetMasterInterface::SetParams()
  190. {
  191. jack_log ( "JackNetMasterInterface::SetParams" );
  192. JackNetInterface::SetParams();
  193. fTxHeader.fDataStream = 's';
  194. fRxHeader.fDataStream = 'r';
  195. //midi net buffers
  196. fNetMidiCaptureBuffer = new NetMidiBuffer ( &fParams, fParams.fSendMidiChannels, fTxData );
  197. fNetMidiPlaybackBuffer = new NetMidiBuffer ( &fParams, fParams.fReturnMidiChannels, fRxData );
  198. assert ( fNetMidiCaptureBuffer );
  199. assert ( fNetMidiPlaybackBuffer );
  200. try {
  201. //audio net buffers
  202. #ifdef CELT
  203. if (fParams.fSendAudioChannels)
  204. fNetAudioCaptureBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData );
  205. if (fParams.fReturnAudioChannels)
  206. fNetAudioPlaybackBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData );
  207. //fNetAudioCaptureBuffer = new NetIntAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData );
  208. //fNetAudioPlaybackBuffer = new NetIntAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData );
  209. #else
  210. fNetAudioCaptureBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData );
  211. fNetAudioPlaybackBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData );
  212. #endif
  213. //fNetAudioCaptureBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData );
  214. //fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData );
  215. } catch (exception&) {
  216. jack_error("NetAudioBuffer allocation error...");
  217. return false;
  218. }
  219. //set the new timeout for the socket
  220. if (SetRxTimeout() == SOCKET_ERROR) {
  221. jack_error("Can't set rx timeout : %s", StrError(NET_ERROR_CODE));
  222. goto error;
  223. }
  224. //set the new rx buffer size
  225. if (SetNetBufferSize() == SOCKET_ERROR) {
  226. jack_error("Can't set net buffer sizes : %s", StrError(NET_ERROR_CODE));
  227. goto error;
  228. }
  229. return true;
  230. error:
  231. FreeNetworkBuffers();
  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. /*
  367. if (fCycleOffset < CYCLE_OFFSET_SLOW) {
  368. return 0;
  369. } else {
  370. rx_bytes = Recv ( rx_head->fPacketSize, 0 );
  371. }
  372. */
  373. rx_bytes = Recv ( rx_head->fPacketSize, 0 );
  374. if (fCycleOffset != fLastfCycleOffset)
  375. jack_info("Warning : '%s' runs in slow network mode, but data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
  376. fLastfCycleOffset = fCycleOffset;
  377. break;
  378. case 'n' :
  379. //normal use of the network :
  380. // - extra latency is set to one cycle, what is the time needed to receive streams using full network bandwidth
  381. // - if the network is too fast, just wait the next cycle, the benefit here is the master's cycle is shorter
  382. // - indeed, data is supposed to be on the network rx buffer, so we don't have to wait for it
  383. if (fCycleOffset < CYCLE_OFFSET_NORMAL) {
  384. return 0;
  385. } else {
  386. rx_bytes = Recv ( rx_head->fPacketSize, 0 );
  387. }
  388. if (fCycleOffset > CYCLE_OFFSET_NORMAL) {
  389. jack_info("'%s' can't run in normal network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
  390. }
  391. break;
  392. case 'f' :
  393. //fast mode suppose the network bandwith is larger than required for the transmission (only a few channels for example)
  394. // - packets can be quickly received, quickly is here relative to the cycle duration
  395. // - here, receive data, we can't keep it queued on the rx buffer,
  396. // - but if there is a cycle offset, tell the user, that means we're not in fast mode anymore, network is too slow
  397. rx_bytes = Recv ( rx_head->fPacketSize, 0 );
  398. if (fCycleOffset > CYCLE_OFFSET_FAST) {
  399. jack_info("'%s' can't run in fast network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
  400. }
  401. break;
  402. }
  403. fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
  404. return rx_bytes;
  405. }
  406. int JackNetMasterInterface::DataRecv()
  407. {
  408. int rx_bytes = 0;
  409. uint recvd_midi_pckt = 0;
  410. uint recvd_audio_pckt = 0;
  411. packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
  412. while ( !fRxHeader.fIsLastPckt )
  413. {
  414. //how much data is queued on the rx buffer ?
  415. rx_bytes = Recv(HEADER_SIZE, MSG_PEEK);
  416. //error here, problem with recv, just skip the cycle (return -1)
  417. if ( rx_bytes == SOCKET_ERROR )
  418. return rx_bytes;
  419. if ( rx_bytes && ( rx_head->fDataStream == 'r' ) && ( rx_head->fID == fParams.fID ) )
  420. {
  421. //read data
  422. switch ( rx_head->fDataType )
  423. {
  424. case 'm': //midi
  425. rx_bytes = Recv(rx_head->fPacketSize, 0);
  426. fRxHeader.fCycle = rx_head->fCycle;
  427. fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
  428. fNetMidiPlaybackBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
  429. // Last midi packet is received, so finish rendering...
  430. if (++recvd_midi_pckt == rx_head->fNumPacket)
  431. fNetMidiPlaybackBuffer->RenderToJackPorts();
  432. break;
  433. case 'a': //audio
  434. rx_bytes = Recv(rx_head->fPacketSize, 0);
  435. fRxHeader.fCycle = rx_head->fCycle;
  436. fRxHeader.fSubCycle = rx_head->fSubCycle;
  437. fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
  438. fNetAudioPlaybackBuffer->RenderFromNetwork (rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
  439. // Last audio packet is received, so finish rendering...
  440. if (fRxHeader.fIsLastPckt)
  441. fNetAudioPlaybackBuffer->RenderToJackPorts();
  442. break;
  443. case 's': //sync
  444. jack_info("NetMaster : overloaded, skipping receive from '%s'", fParams.fName);
  445. // TODO : finish midi and audio rendering ?
  446. fNetAudioPlaybackBuffer->RenderToJackPorts();
  447. return 0;
  448. }
  449. }
  450. }
  451. return rx_bytes;
  452. }
  453. void JackNetMasterInterface::EncodeSyncPacket()
  454. {
  455. //this method contains every step of sync packet informations coding
  456. //first of all, reset sync packet
  457. memset ( fTxData, 0, PACKET_AVAILABLE_SIZE );
  458. //then, first step : transport
  459. if (fParams.fTransportSync) {
  460. EncodeTransportData();
  461. TransportDataHToN( &fSendTransportData, &fSendTransportData);
  462. //copy to TxBuffer
  463. memcpy ( fTxData, &fSendTransportData, sizeof ( net_transport_data_t ) );
  464. }
  465. //then others (freewheel etc.)
  466. //...
  467. }
  468. void JackNetMasterInterface::DecodeSyncPacket()
  469. {
  470. //this method contains every step of sync packet informations decoding process
  471. //first : transport
  472. if (fParams.fTransportSync) {
  473. //copy received transport data to transport data structure
  474. memcpy ( &fReturnTransportData, fRxData, sizeof ( net_transport_data_t ) );
  475. TransportDataNToH( &fReturnTransportData, &fReturnTransportData);
  476. DecodeTransportData();
  477. }
  478. //then others
  479. //...
  480. }
  481. // JackNetSlaveInterface ************************************************************************************************
  482. uint JackNetSlaveInterface::fSlaveCounter = 0;
  483. bool JackNetSlaveInterface::Init()
  484. {
  485. jack_log ( "JackNetSlaveInterface::Init()" );
  486. //set the parameters to send
  487. strcpy ( fParams.fPacketType, "params" );
  488. fParams.fProtocolVersion = SLAVE_PROTOCOL;
  489. SetPacketType ( &fParams, SLAVE_AVAILABLE );
  490. //init loop : get a master and start, do it until connection is ok
  491. net_status_t status;
  492. do
  493. {
  494. //first, get a master, do it until a valid connection is running
  495. do
  496. {
  497. status = SendAvailableToMaster();
  498. if ( status == NET_SOCKET_ERROR )
  499. return false;
  500. }
  501. while ( status != NET_CONNECTED );
  502. //then tell the master we are ready
  503. jack_info ( "Initializing connection with %s...", fParams.fMasterNetName );
  504. status = SendStartToMaster();
  505. if ( status == NET_ERROR )
  506. return false;
  507. }
  508. while ( status != NET_ROLLING );
  509. return true;
  510. }
  511. // Separate the connection protocol into two separated step
  512. bool JackNetSlaveInterface::InitConnection(int time_out)
  513. {
  514. jack_log("JackNetSlaveInterface::InitConnection()");
  515. int try_count = (time_out > 0) ? ((1000000 * time_out) / SLAVE_INIT_TIMEOUT) : LONG_MAX;
  516. //set the parameters to send
  517. strcpy (fParams.fPacketType, "params");
  518. fParams.fProtocolVersion = SLAVE_PROTOCOL;
  519. SetPacketType (&fParams, SLAVE_AVAILABLE);
  520. net_status_t status;
  521. do
  522. {
  523. //get a master
  524. status = SendAvailableToMaster(try_count);
  525. if (status == NET_SOCKET_ERROR)
  526. return false;
  527. }
  528. while (status != NET_CONNECTED && --try_count > 0);
  529. return (try_count != 0);
  530. }
  531. bool JackNetSlaveInterface::InitRendering()
  532. {
  533. jack_log("JackNetSlaveInterface::InitRendering()");
  534. net_status_t status;
  535. do
  536. {
  537. //then tell the master we are ready
  538. jack_info("Initializing connection with %s...", fParams.fMasterNetName);
  539. status = SendStartToMaster();
  540. if (status == NET_ERROR)
  541. return false;
  542. }
  543. while (status != NET_ROLLING);
  544. return true;
  545. }
  546. net_status_t JackNetSlaveInterface::SendAvailableToMaster(long try_count)
  547. {
  548. jack_log ( "JackNetSlaveInterface::SendAvailableToMaster()" );
  549. //utility
  550. session_params_t host_params;
  551. int rx_bytes = 0;
  552. //socket
  553. if ( fSocket.NewSocket() == SOCKET_ERROR ) {
  554. jack_error ( "Fatal error : network unreachable - %s", StrError ( NET_ERROR_CODE ) );
  555. return NET_SOCKET_ERROR;
  556. }
  557. //bind the socket
  558. if ( fSocket.Bind() == SOCKET_ERROR ) {
  559. jack_error ( "Can't bind the socket : %s", StrError ( NET_ERROR_CODE ) );
  560. return NET_SOCKET_ERROR;
  561. }
  562. //timeout on receive
  563. if ( fSocket.SetTimeOut ( SLAVE_INIT_TIMEOUT ) == SOCKET_ERROR )
  564. jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) );
  565. //disable local loop
  566. if ( fSocket.SetLocalLoop() == SOCKET_ERROR )
  567. jack_error ( "Can't disable multicast loop : %s", StrError ( NET_ERROR_CODE ) );
  568. //send 'AVAILABLE' until 'SLAVE_SETUP' received
  569. jack_info ( "Waiting for a master..." );
  570. do
  571. {
  572. //send 'available'
  573. session_params_t net_params;
  574. memset(&net_params, 0, sizeof ( session_params_t ));
  575. SessionParamsHToN(&fParams, &net_params);
  576. if ( fSocket.SendTo ( &net_params, sizeof ( session_params_t ), 0, fMulticastIP ) == SOCKET_ERROR )
  577. jack_error ( "Error in data send : %s", StrError ( NET_ERROR_CODE ) );
  578. //filter incoming packets : don't exit while no error is detected
  579. memset(&net_params, 0, sizeof ( session_params_t ));
  580. rx_bytes = fSocket.CatchHost ( &net_params, sizeof ( session_params_t ), 0 );
  581. SessionParamsNToH(&net_params, &host_params);
  582. if ( ( rx_bytes == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) )
  583. {
  584. jack_error ( "Can't receive : %s", StrError ( NET_ERROR_CODE ) );
  585. return NET_RECV_ERROR;
  586. }
  587. }
  588. while (strcmp(host_params.fPacketType, fParams.fPacketType) && (GetPacketType(&host_params) != SLAVE_SETUP) && (--try_count > 0));
  589. // Time out failure..
  590. if (try_count == 0) {
  591. jack_error("Time out error in connect");
  592. return NET_CONNECT_ERROR;
  593. }
  594. //everything is OK, copy parameters
  595. SessionParamsDisplay(&host_params);
  596. fParams = host_params;
  597. //connect the socket
  598. if (fSocket.Connect() == SOCKET_ERROR) {
  599. jack_error("Error in connect : %s", StrError(NET_ERROR_CODE));
  600. return NET_CONNECT_ERROR;
  601. }
  602. return NET_CONNECTED;
  603. }
  604. net_status_t JackNetSlaveInterface::SendStartToMaster()
  605. {
  606. jack_log("JackNetSlaveInterface::SendStartToMaster");
  607. //tell the master to start
  608. session_params_t net_params;
  609. memset(&net_params, 0, sizeof ( session_params_t ));
  610. SetPacketType ( &fParams, START_MASTER );
  611. SessionParamsHToN(&fParams, &net_params);
  612. if (fSocket.Send(&net_params, sizeof(session_params_t), 0) == SOCKET_ERROR)
  613. {
  614. jack_error("Error in send : %s", StrError(NET_ERROR_CODE));
  615. return (fSocket.GetError() == NET_CONN_ERROR) ? NET_ERROR : NET_SEND_ERROR;
  616. }
  617. return NET_ROLLING;
  618. }
  619. bool JackNetSlaveInterface::SetParams()
  620. {
  621. jack_log ( "JackNetSlaveInterface::SetParams" );
  622. JackNetInterface::SetParams();
  623. fTxHeader.fDataStream = 'r';
  624. fRxHeader.fDataStream = 's';
  625. //midi net buffers
  626. fNetMidiCaptureBuffer = new NetMidiBuffer ( &fParams, fParams.fSendMidiChannels, fRxData );
  627. fNetMidiPlaybackBuffer = new NetMidiBuffer ( &fParams, fParams.fReturnMidiChannels, fTxData );
  628. assert ( fNetMidiCaptureBuffer );
  629. assert ( fNetMidiPlaybackBuffer );
  630. //audio net buffers
  631. //fNetAudioCaptureBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData );
  632. //fNetAudioPlaybackBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData );
  633. try {
  634. #ifdef CELT
  635. if (fParams.fSendAudioChannels)
  636. fNetAudioCaptureBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData );
  637. if (fParams.fReturnAudioChannels)
  638. fNetAudioPlaybackBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData );
  639. // fNetAudioCaptureBuffer = new NetIntAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData );
  640. // fNetAudioPlaybackBuffer = new NetIntAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData );
  641. #else
  642. fNetAudioCaptureBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData );
  643. fNetAudioPlaybackBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData );
  644. //fNetAudioCaptureBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData );
  645. //fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData );
  646. #endif
  647. } catch (exception&) {
  648. jack_error("NetAudioBuffer allocation error...");
  649. return false;
  650. }
  651. //set the new buffer sizes
  652. if ( SetNetBufferSize() == SOCKET_ERROR ) {
  653. jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) );
  654. goto error;
  655. }
  656. return true;
  657. error:
  658. FreeNetworkBuffers();
  659. return false;
  660. }
  661. int JackNetSlaveInterface::Recv(size_t size, int flags)
  662. {
  663. int rx_bytes = fSocket.Recv(fRxBuffer, size, flags);
  664. //handle errors
  665. if ( rx_bytes == SOCKET_ERROR )
  666. {
  667. net_error_t error = fSocket.GetError();
  668. //no data isn't really an error in realtime processing, so just return 0
  669. if ( error == NET_NO_DATA ) {
  670. jack_error ( "No data, is the master still running ?" );
  671. //if a network error occurs, this exception will restart the driver
  672. } else if ( error == NET_CONN_ERROR ) {
  673. jack_error ( "Connection lost." );
  674. throw JackNetException();
  675. } else {
  676. jack_error ( "Fatal error in slave receive : %s", StrError ( NET_ERROR_CODE ) );
  677. }
  678. }
  679. packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer);
  680. PacketHeaderNToH(header, header);
  681. return rx_bytes;
  682. }
  683. int JackNetSlaveInterface::Send(size_t size, int flags)
  684. {
  685. packet_header_t* header = reinterpret_cast<packet_header_t*>(fTxBuffer);
  686. PacketHeaderHToN(header, header);
  687. int tx_bytes = fSocket.Send ( fTxBuffer, size, flags );
  688. //handle errors
  689. if ( tx_bytes == SOCKET_ERROR )
  690. {
  691. net_error_t error = fSocket.GetError();
  692. //if a network error occurs, this exception will restart the driver
  693. if ( error == NET_CONN_ERROR ) {
  694. jack_error ( "Connection lost." );
  695. throw JackNetException();
  696. } else {
  697. jack_error ( "Fatal error in slave send : %s", StrError ( NET_ERROR_CODE ) );
  698. }
  699. }
  700. return tx_bytes;
  701. }
  702. int JackNetSlaveInterface::SyncRecv()
  703. {
  704. int rx_bytes = 0;
  705. packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
  706. //receive sync (launch the cycle)
  707. do
  708. {
  709. rx_bytes = Recv(HEADER_SIZE, 0);
  710. //connection issue, send will detect it, so don't skip the cycle (return 0)
  711. if ( rx_bytes == SOCKET_ERROR )
  712. return rx_bytes;
  713. }
  714. while ((strcmp(rx_head->fPacketType, "header") != 0) && (rx_head->fDataType != 's'));
  715. fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
  716. return rx_bytes;
  717. }
  718. int JackNetSlaveInterface::DataRecv()
  719. {
  720. int rx_bytes = 0;
  721. uint recvd_midi_pckt = 0;
  722. uint recvd_audio_pckt = 0;
  723. packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
  724. while ( !fRxHeader.fIsLastPckt )
  725. {
  726. //how much data is queued on the rx buffer ?
  727. rx_bytes = Recv(HEADER_SIZE, MSG_PEEK);
  728. //error here, problem with recv, just skip the cycle (return -1)
  729. if ( rx_bytes == SOCKET_ERROR )
  730. return rx_bytes;
  731. if ( rx_bytes && ( rx_head->fDataStream == 's' ) && ( rx_head->fID == fParams.fID ) )
  732. {
  733. switch ( rx_head->fDataType )
  734. {
  735. case 'm': //midi
  736. rx_bytes = Recv(rx_head->fPacketSize, 0);
  737. fRxHeader.fCycle = rx_head->fCycle;
  738. fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
  739. fNetMidiCaptureBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
  740. // Last midi packet is received, so finish rendering...
  741. if (++recvd_midi_pckt == rx_head->fNumPacket)
  742. fNetMidiCaptureBuffer->RenderToJackPorts();
  743. break;
  744. case 'a': //audio
  745. rx_bytes = Recv(rx_head->fPacketSize, 0);
  746. fRxHeader.fCycle = rx_head->fCycle;
  747. fRxHeader.fSubCycle = rx_head->fSubCycle;
  748. fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
  749. fNetAudioCaptureBuffer->RenderFromNetwork (rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
  750. // Last audio packet is received, so finish rendering...
  751. if (fRxHeader.fIsLastPckt)
  752. fNetAudioCaptureBuffer->RenderToJackPorts();
  753. break;
  754. case 's': //sync
  755. jack_info ( "NetSlave : overloaded, skipping receive." );
  756. // TODO : finish midi and audio rendering ?
  757. fNetAudioCaptureBuffer->RenderToJackPorts();
  758. return 0;
  759. }
  760. }
  761. }
  762. fRxHeader.fCycle = rx_head->fCycle;
  763. return 0;
  764. }
  765. int JackNetSlaveInterface::SyncSend()
  766. {
  767. //tx header
  768. if ( fParams.fSlaveSyncMode ) {
  769. fTxHeader.fCycle = fRxHeader.fCycle;
  770. } else {
  771. fTxHeader.fCycle++;
  772. }
  773. fTxHeader.fSubCycle = 0;
  774. fTxHeader.fDataType = 's';
  775. fTxHeader.fIsLastPckt = (fParams.fReturnMidiChannels == 0 && fParams.fReturnAudioChannels == 0) ? 1 : 0;
  776. fTxHeader.fPacketSize = HEADER_SIZE;
  777. memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
  778. return Send (fTxHeader.fPacketSize, 0);
  779. }
  780. int JackNetSlaveInterface::DataSend()
  781. {
  782. uint subproc;
  783. uint data_size;
  784. //midi
  785. if (fParams.fReturnMidiChannels > 0)
  786. {
  787. //set global header fields and get the number of midi packets
  788. fTxHeader.fDataType = 'm';
  789. data_size = fNetMidiPlaybackBuffer->RenderFromJackPorts();
  790. fTxHeader.fNumPacket = fNetMidiPlaybackBuffer->GetNumPackets();
  791. for ( subproc = 0; subproc < fTxHeader.fNumPacket; subproc++ )
  792. {
  793. fTxHeader.fSubCycle = subproc;
  794. fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && !fParams.fReturnAudioChannels) ? 1 : 0;
  795. fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiPlaybackBuffer->RenderToNetwork(subproc, data_size);
  796. memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
  797. if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
  798. return SOCKET_ERROR;
  799. }
  800. }
  801. //audio
  802. if ( fParams.fReturnAudioChannels > 0)
  803. {
  804. fTxHeader.fDataType = 'a';
  805. data_size = fNetAudioPlaybackBuffer->RenderFromJackPorts();
  806. fTxHeader.fNumPacket = fNetAudioPlaybackBuffer->GetNumPackets();
  807. for ( subproc = 0; subproc < fTxHeader.fNumPacket; subproc++ )
  808. {
  809. fTxHeader.fSubCycle = subproc;
  810. fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0;
  811. fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioPlaybackBuffer->RenderToNetwork(subproc, data_size);
  812. memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
  813. if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
  814. return SOCKET_ERROR;
  815. }
  816. }
  817. return 0;
  818. }
  819. //network sync------------------------------------------------------------------------
  820. void JackNetSlaveInterface::EncodeSyncPacket()
  821. {
  822. //this method contains every step of sync packet informations coding
  823. //first of all, reset sync packet
  824. memset ( fTxData, 0, PACKET_AVAILABLE_SIZE );
  825. //then first step : transport
  826. if (fParams.fTransportSync) {
  827. EncodeTransportData();
  828. TransportDataHToN( &fReturnTransportData, &fReturnTransportData);
  829. //copy to TxBuffer
  830. memcpy ( fTxData, &fReturnTransportData, sizeof ( net_transport_data_t ) );
  831. }
  832. //then others
  833. //...
  834. }
  835. void JackNetSlaveInterface::DecodeSyncPacket()
  836. {
  837. //this method contains every step of sync packet informations decoding process
  838. //first : transport
  839. if (fParams.fTransportSync) {
  840. //copy received transport data to transport data structure
  841. memcpy ( &fSendTransportData, fRxData, sizeof ( net_transport_data_t ) );
  842. TransportDataNToH( &fSendTransportData, &fSendTransportData);
  843. DecodeTransportData();
  844. }
  845. //then others
  846. //...
  847. }
  848. }