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.

888 lines
35KB

  1. /*
  2. Copyright (C) 2008 Romain Moret at Grame
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. */
  15. #if defined(HAVE_CONFIG_H)
  16. #include "config.h"
  17. #endif
  18. #include "JackNetManager.h"
  19. #define DEFAULT_MULTICAST_IP "225.3.19.154"
  20. #define DEFAULT_PORT 19000
  21. using namespace std;
  22. namespace Jack
  23. {
  24. //JackNetMaster******************************************************************************************************
  25. #ifdef JACK_MONITOR
  26. uint JackNetMaster::fMeasureCnt = 128;
  27. uint JackNetMaster::fMeasurePoints = 4;
  28. string JackNetMaster::fMonitorFieldNames[] =
  29. {
  30. string ( "sync send" ),
  31. string ( "end of send" ),
  32. string ( "sync recv" ),
  33. string ( "end of cycle" )
  34. };
  35. uint JackNetMaster::fMonitorPlotOptionsCnt = 2;
  36. string JackNetMaster::fMonitorPlotOptions[] =
  37. {
  38. string ( "set xlabel \"audio cycles\"" ),
  39. string ( "set ylabel \"% of audio cycle\"" )
  40. };
  41. #endif
  42. JackNetMaster::JackNetMaster ( JackNetMasterManager* manager, session_params_t& params ) : fSocket()
  43. {
  44. jack_log ( "JackNetMaster::JackNetMaster" );
  45. //settings
  46. fMasterManager = manager;
  47. fParams = params;
  48. fSocket.CopyParams ( &fMasterManager->fSocket );
  49. fNSubProcess = fParams.fPeriodSize / fParams.fFramesPerPacket;
  50. fClientName = const_cast<char*> ( fParams.fName );
  51. fJackClient = NULL;
  52. fRunning = false;
  53. fSyncState = 1;
  54. uint port_index;
  55. //jack audio ports
  56. fAudioCapturePorts = new jack_port_t* [fParams.fSendAudioChannels];
  57. for ( port_index = 0; port_index < fParams.fSendAudioChannels; port_index++ )
  58. fAudioCapturePorts[port_index] = NULL;
  59. fAudioPlaybackPorts = new jack_port_t* [fParams.fReturnAudioChannels];
  60. for ( port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++ )
  61. fAudioPlaybackPorts[port_index] = NULL;
  62. //jack midi ports
  63. fMidiCapturePorts = new jack_port_t* [fParams.fSendMidiChannels];
  64. for ( port_index = 0; port_index < fParams.fSendMidiChannels; port_index++ )
  65. fMidiCapturePorts[port_index] = NULL;
  66. fMidiPlaybackPorts = new jack_port_t* [fParams.fReturnMidiChannels];
  67. for ( port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++ )
  68. fMidiPlaybackPorts[port_index] = NULL;
  69. //TX header init
  70. strcpy ( fTxHeader.fPacketType, "header" );
  71. fTxHeader.fDataStream = 's';
  72. fTxHeader.fID = fParams.fID;
  73. fTxHeader.fCycle = 0;
  74. fTxHeader.fSubCycle = 0;
  75. fTxHeader.fMidiDataSize = 0;
  76. fTxHeader.fBitdepth = fParams.fBitdepth;
  77. //RX header init
  78. strcpy ( fRxHeader.fPacketType, "header" );
  79. fRxHeader.fDataStream = 'r';
  80. fRxHeader.fID = fParams.fID;
  81. fRxHeader.fCycle = 0;
  82. fRxHeader.fSubCycle = 0;
  83. fRxHeader.fMidiDataSize = 0;
  84. fRxHeader.fBitdepth = fParams.fBitdepth;
  85. //network buffers
  86. fTxBuffer = new char [fParams.fMtu];
  87. fRxBuffer = new char [fParams.fMtu];
  88. //net audio buffers
  89. fTxData = fTxBuffer + sizeof ( packet_header_t );
  90. fRxData = fRxBuffer + sizeof ( packet_header_t );
  91. //midi net buffers
  92. fNetMidiCaptureBuffer = new NetMidiBuffer ( &fParams, fParams.fSendMidiChannels, fTxData );
  93. fNetMidiPlaybackBuffer = new NetMidiBuffer ( &fParams, fParams.fReturnMidiChannels, fRxData );
  94. //audio net buffers
  95. fNetAudioCaptureBuffer = new NetAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData );
  96. fNetAudioPlaybackBuffer = new NetAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData );
  97. //audio netbuffer length
  98. fAudioTxLen = sizeof ( packet_header_t ) + fNetAudioCaptureBuffer->GetSize();
  99. fAudioRxLen = sizeof ( packet_header_t ) + fNetAudioPlaybackBuffer->GetSize();
  100. //payload size
  101. fPayloadSize = fParams.fMtu - sizeof ( packet_header_t );
  102. //monitor
  103. #ifdef JACK_MONITOR
  104. fPeriodUsecs = ( int ) ( 1000000.f * ( ( float ) fParams.fPeriodSize / ( float ) fParams.fSampleRate ) );
  105. string plot_name = string ( fParams.fName );
  106. plot_name += string ( "_master" );
  107. plot_name += string ( ( fParams.fSlaveSyncMode ) ? "_sync" : "_async" );
  108. plot_name += ( fParams.fNetworkMode == 'f' ) ? string ( "_fast-network" ) : string ( "" );
  109. fMonitor = new JackGnuPlotMonitor<float> ( JackNetMaster::fMeasureCnt, JackNetMaster::fMeasurePoints, plot_name );
  110. fMeasure = new float[JackNetMaster::fMeasurePoints];
  111. fMonitor->SetPlotFile ( JackNetMaster::fMonitorPlotOptions, JackNetMaster::fMonitorPlotOptionsCnt,
  112. JackNetMaster::fMonitorFieldNames, JackNetMaster::fMeasurePoints );
  113. #endif
  114. }
  115. JackNetMaster::~JackNetMaster()
  116. {
  117. jack_log ( "JackNetMaster::~JackNetMaster, ID %u.", fParams.fID );
  118. if ( fJackClient )
  119. {
  120. jack_deactivate ( fJackClient );
  121. FreePorts();
  122. jack_client_close ( fJackClient );
  123. }
  124. fSocket.Close();
  125. delete fNetAudioCaptureBuffer;
  126. delete fNetAudioPlaybackBuffer;
  127. delete fNetMidiCaptureBuffer;
  128. delete fNetMidiPlaybackBuffer;
  129. delete[] fAudioCapturePorts;
  130. delete[] fAudioPlaybackPorts;
  131. delete[] fMidiCapturePorts;
  132. delete[] fMidiPlaybackPorts;
  133. delete[] fTxBuffer;
  134. delete[] fRxBuffer;
  135. #ifdef JACK_MONITOR
  136. fMonitor->Save();
  137. delete[] fMeasure;
  138. delete fMonitor;
  139. #endif
  140. }
  141. bool JackNetMaster::Init()
  142. {
  143. jack_log ( "JackNetMaster::Init, ID %u.", fParams.fID );
  144. session_params_t params;
  145. int usec_timeout = 1000000;
  146. uint attempt = 0;
  147. int rx_bytes = 0;
  148. int rx_bufsize = 0;
  149. //socket
  150. if ( fSocket.NewSocket() == SOCKET_ERROR )
  151. {
  152. jack_error ( "Can't create socket : %s", StrError ( NET_ERROR_CODE ) );
  153. return false;
  154. }
  155. //timeout on receive (for init)
  156. if ( fSocket.SetTimeOut ( usec_timeout ) < 0 )
  157. jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) );
  158. //connect
  159. if ( fSocket.Connect() == SOCKET_ERROR )
  160. {
  161. jack_error ( "Can't connect : %s", StrError ( NET_ERROR_CODE ) );
  162. return false;
  163. }
  164. //send 'SLAVE_SETUP' until 'START_MASTER' received
  165. jack_info ( "Sending parameters to %s ...", fParams.fSlaveNetName );
  166. do
  167. {
  168. SetPacketType ( &fParams, SLAVE_SETUP );
  169. if ( fSocket.Send ( &fParams, sizeof ( session_params_t ), 0 ) == SOCKET_ERROR )
  170. jack_error ( "Error in send : ", StrError ( NET_ERROR_CODE ) );
  171. if ( ( ( rx_bytes = fSocket.Recv ( &params, sizeof ( session_params_t ), 0 ) ) == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) )
  172. {
  173. jack_error ( "Problem with network." );
  174. return false;
  175. }
  176. }
  177. while ( ( GetPacketType ( &params ) != START_MASTER ) && ( ++attempt < 5 ) );
  178. if ( attempt == 5 )
  179. {
  180. jack_error ( "Slave doesn't respond, exiting." );
  181. return false;
  182. }
  183. //set the new timeout for the socket
  184. if ( SetRxTimeout ( &fSocket, &fParams ) == SOCKET_ERROR )
  185. {
  186. jack_error ( "Can't set rx timeout : %s", StrError ( NET_ERROR_CODE ) );
  187. return false;
  188. }
  189. //set the new rx buffer size
  190. rx_bufsize = GetNetBufferSize ( &fParams );
  191. if ( fSocket.SetOption ( SOL_SOCKET, SO_RCVBUF, &rx_bufsize, sizeof ( rx_bufsize ) ) == SOCKET_ERROR )
  192. {
  193. jack_error ( "Can't set rx buffer size : %s", StrError ( NET_ERROR_CODE ) );
  194. return false;
  195. }
  196. //jack client and process
  197. jack_status_t status;
  198. jack_options_t options = JackNullOption;
  199. if ( ( fJackClient = jack_client_open ( fClientName, options, &status, NULL ) ) == NULL )
  200. {
  201. jack_error ( "Can't open a new jack client." );
  202. return false;
  203. }
  204. jack_set_process_callback ( fJackClient, SetProcess, this );
  205. //port registering
  206. uint i;
  207. char name[24];
  208. jack_nframes_t port_latency = jack_get_buffer_size ( fJackClient );
  209. unsigned long port_flags;
  210. //audio
  211. port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
  212. for ( i = 0; i < fParams.fSendAudioChannels; i++ )
  213. {
  214. sprintf ( name, "to_slave_%d", i+1 );
  215. if ( ( fAudioCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0 ) ) == NULL )
  216. goto fail;
  217. jack_port_set_latency ( fAudioCapturePorts[i], 0 );
  218. }
  219. port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
  220. for ( i = 0; i < fParams.fReturnAudioChannels; i++ )
  221. {
  222. sprintf ( name, "from_slave_%d", i+1 );
  223. if ( ( fAudioPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0 ) ) == NULL )
  224. goto fail;
  225. jack_port_set_latency ( fAudioPlaybackPorts[i], ( fParams.fNetworkMode == 'f' ) ? 0 : port_latency + ( fParams.fSlaveSyncMode ) ? 0 : port_latency );
  226. }
  227. //midi
  228. port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
  229. for ( i = 0; i < fParams.fSendMidiChannels; i++ )
  230. {
  231. sprintf ( name, "midi_to_slave_%d", i+1 );
  232. if ( ( fMidiCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, port_flags, 0 ) ) == NULL )
  233. goto fail;
  234. jack_port_set_latency ( fMidiCapturePorts[i], 0 );
  235. }
  236. port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
  237. for ( i = 0; i < fParams.fReturnMidiChannels; i++ )
  238. {
  239. sprintf ( name, "midi_from_slave_%d", i+1 );
  240. if ( ( fMidiPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, port_flags, 0 ) ) == NULL )
  241. goto fail;
  242. jack_port_set_latency ( fMidiPlaybackPorts[i], ( fParams.fNetworkMode == 'f' ) ? 0 : port_latency + ( fParams.fSlaveSyncMode ) ? 0 : port_latency );
  243. }
  244. fRunning = true;
  245. //finally activate jack client
  246. if ( jack_activate ( fJackClient ) != 0 )
  247. {
  248. jack_error ( "Can't activate jack client." );
  249. goto fail;
  250. }
  251. jack_info ( "NetJack new master started." );
  252. return true;
  253. fail:
  254. FreePorts();
  255. jack_client_close ( fJackClient );
  256. fJackClient = NULL;
  257. return false;
  258. }
  259. void JackNetMaster::FreePorts()
  260. {
  261. jack_log ( "JackNetMaster::FreePorts, ID %u", fParams.fID );
  262. uint port_index;
  263. for ( port_index = 0; port_index < fParams.fSendAudioChannels; port_index++ )
  264. if ( fAudioCapturePorts[port_index] )
  265. jack_port_unregister ( fJackClient, fAudioCapturePorts[port_index] );
  266. for ( port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++ )
  267. if ( fAudioPlaybackPorts[port_index] )
  268. jack_port_unregister ( fJackClient, fAudioPlaybackPorts[port_index] );
  269. for ( port_index = 0; port_index < fParams.fSendMidiChannels; port_index++ )
  270. if ( fMidiCapturePorts[port_index] )
  271. jack_port_unregister ( fJackClient, fMidiCapturePorts[port_index] );
  272. for ( port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++ )
  273. if ( fMidiPlaybackPorts[port_index] )
  274. jack_port_unregister ( fJackClient, fMidiPlaybackPorts[port_index] );
  275. }
  276. void JackNetMaster::Exit()
  277. {
  278. jack_log ( "JackNetMaster::Exit, ID %u", fParams.fID );
  279. //stop process
  280. fRunning = false;
  281. //send a 'multicast euthanasia request' - new socket is required on macosx
  282. jack_info ( "Exiting '%s'", fParams.fName );
  283. SetPacketType ( &fParams, KILL_MASTER );
  284. JackNetSocket mcast_socket ( fMasterManager->fMulticastIP, fSocket.GetPort() );
  285. if ( mcast_socket.NewSocket() == SOCKET_ERROR )
  286. jack_error ( "Can't create socket : %s", StrError ( NET_ERROR_CODE ) );
  287. if ( mcast_socket.SendTo ( &fParams, sizeof ( session_params_t ), 0, fMasterManager->fMulticastIP ) == SOCKET_ERROR )
  288. jack_error ( "Can't send suicide request : %s", StrError ( NET_ERROR_CODE ) );
  289. mcast_socket.Close();
  290. }
  291. int JackNetMaster::SetSyncPacket()
  292. {
  293. if ( fParams.fTransportSync )
  294. {
  295. //TODO : set the TransportData
  296. //copy to TxBuffer
  297. memcpy ( fTxData, &fTransportData, sizeof ( net_transport_data_t ) );
  298. }
  299. return 0;
  300. }
  301. int JackNetMaster::Send ( char* buffer, size_t size, int flags )
  302. {
  303. int tx_bytes;
  304. if ( ( tx_bytes = fSocket.Send ( buffer, size, flags ) ) == SOCKET_ERROR )
  305. {
  306. net_error_t error = fSocket.GetError();
  307. if ( fRunning && ( error == NET_CONN_ERROR ) )
  308. {
  309. //fatal connection issue, exit
  310. jack_error ( "'%s' : %s, please check network connection with '%s'.",
  311. fParams.fName, StrError ( NET_ERROR_CODE ), fParams.fSlaveNetName );
  312. Exit();
  313. }
  314. else if ( fRunning )
  315. jack_error ( "Error in send : %s", StrError ( NET_ERROR_CODE ) );
  316. }
  317. return tx_bytes;
  318. }
  319. int JackNetMaster::Recv ( size_t size, int flags )
  320. {
  321. int rx_bytes;
  322. if ( ( rx_bytes = fSocket.Recv ( fRxBuffer, size, flags ) ) == SOCKET_ERROR )
  323. {
  324. net_error_t error = fSocket.GetError();
  325. //no data isn't really a network error, so just return 0 avalaible read bytes
  326. if ( error == NET_NO_DATA )
  327. return 0;
  328. else if ( fRunning && ( error == NET_CONN_ERROR ) )
  329. {
  330. //fatal connection issue, exit
  331. jack_error ( "'%s' : %s, network connection with '%s' broken, exiting.",
  332. fParams.fName, StrError ( NET_ERROR_CODE ), fParams.fSlaveNetName );
  333. //ask to the manager to properly remove the master
  334. Exit();
  335. }
  336. else if ( fRunning )
  337. jack_error ( "Error in receive : %s", StrError ( NET_ERROR_CODE ) );
  338. }
  339. return rx_bytes;
  340. }
  341. int JackNetMaster::SetProcess ( jack_nframes_t nframes, void* arg )
  342. {
  343. JackNetMaster* master = static_cast<JackNetMaster*> ( arg );
  344. return master->Process();
  345. }
  346. int JackNetMaster::Process()
  347. {
  348. if ( !fRunning )
  349. return 0;
  350. int tx_bytes = 0;
  351. int rx_bytes = 0;
  352. uint midi_recvd_pckt = 0;
  353. uint jumpcnt = 0;
  354. fTxHeader.fCycle++;
  355. fTxHeader.fSubCycle = 0;
  356. fTxHeader.fIsLastPckt = 'n';
  357. packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
  358. #ifdef JACK_MONITOR
  359. jack_time_t begin_time = jack_get_time();
  360. fMeasureId = 0;
  361. #endif
  362. //buffers
  363. uint port_index;
  364. for ( port_index = 0; port_index < fParams.fSendMidiChannels; port_index++ )
  365. fNetMidiCaptureBuffer->SetBuffer ( port_index,
  366. static_cast<JackMidiBuffer*> ( jack_port_get_buffer ( fMidiCapturePorts[port_index],
  367. fParams.fPeriodSize ) ) );
  368. for ( port_index = 0; port_index < fParams.fSendAudioChannels; port_index++ )
  369. fNetAudioCaptureBuffer->SetBuffer ( port_index,
  370. static_cast<sample_t*> ( jack_port_get_buffer ( fAudioCapturePorts[port_index],
  371. fParams.fPeriodSize ) ) );
  372. for ( port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++ )
  373. fNetMidiPlaybackBuffer->SetBuffer ( port_index,
  374. static_cast<JackMidiBuffer*> ( jack_port_get_buffer ( fMidiPlaybackPorts[port_index],
  375. fParams.fPeriodSize ) ) );
  376. for ( port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++ )
  377. fNetAudioPlaybackBuffer->SetBuffer ( port_index,
  378. static_cast<sample_t*> ( jack_port_get_buffer ( fAudioPlaybackPorts[port_index],
  379. fParams.fPeriodSize ) ) );
  380. //send ------------------------------------------------------------------------------------------------------------------
  381. //sync : first set header
  382. fTxHeader.fDataType = 's';
  383. if ( !fParams.fSendMidiChannels && !fParams.fSendAudioChannels )
  384. fTxHeader.fIsLastPckt = 'y';
  385. fTxHeader.fPacketSize = fParams.fMtu;
  386. memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) );
  387. //sync : then fill auxiliary data
  388. memset ( fTxData, 0, fPayloadSize );
  389. SetSyncPacket();
  390. //sync : and send
  391. tx_bytes = Send ( fTxBuffer, fTxHeader.fPacketSize, 0 );
  392. if ( tx_bytes == SOCKET_ERROR )
  393. return tx_bytes;
  394. #ifdef JACK_MONITOR
  395. fMeasure[fMeasureId++] = ( ( ( float ) ( jack_get_time() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f;
  396. #endif
  397. //midi
  398. if ( fParams.fSendMidiChannels )
  399. {
  400. //set global header fields and get the number of midi packets
  401. fTxHeader.fDataType = 'm';
  402. fTxHeader.fMidiDataSize = fNetMidiCaptureBuffer->RenderFromJackPorts();
  403. fTxHeader.fNMidiPckt = GetNMidiPckt ( &fParams, fTxHeader.fMidiDataSize );
  404. for ( uint subproc = 0; subproc < fTxHeader.fNMidiPckt; subproc++ )
  405. {
  406. //fill the packet header fields
  407. fTxHeader.fSubCycle = subproc;
  408. if ( ( subproc == ( fTxHeader.fNMidiPckt - 1 ) ) && !fParams.fSendAudioChannels )
  409. fTxHeader.fIsLastPckt = 'y';
  410. //get the data from buffer
  411. fTxHeader.fPacketSize = fNetMidiCaptureBuffer->RenderToNetwork ( subproc, fTxHeader.fMidiDataSize );
  412. fTxHeader.fPacketSize += sizeof ( packet_header_t );
  413. memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) );
  414. //and send
  415. tx_bytes = Send ( fTxBuffer, fTxHeader.fPacketSize, 0 );
  416. if ( tx_bytes == SOCKET_ERROR )
  417. return tx_bytes;
  418. }
  419. }
  420. //audio
  421. if ( fParams.fSendAudioChannels )
  422. {
  423. fTxHeader.fDataType = 'a';
  424. for ( uint subproc = 0; subproc < fNSubProcess; subproc++ )
  425. {
  426. //set the header
  427. fTxHeader.fSubCycle = subproc;
  428. if ( subproc == ( fNSubProcess - 1 ) )
  429. fTxHeader.fIsLastPckt = 'y';
  430. fTxHeader.fPacketSize = fAudioTxLen;
  431. memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) );
  432. //get the data
  433. fNetAudioCaptureBuffer->RenderFromJackPorts ( subproc );
  434. //and send
  435. tx_bytes = Send ( fTxBuffer, fTxHeader.fPacketSize, 0 );
  436. if ( tx_bytes == SOCKET_ERROR )
  437. return tx_bytes;
  438. }
  439. }
  440. #ifdef JACK_MONITOR
  441. fMeasure[fMeasureId++] = ( ( ( float ) ( jack_get_time() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f;
  442. #endif
  443. //receive --------------------------------------------------------------------------------------------------------------------
  444. //sync : how much data is available ?
  445. rx_bytes = Recv ( fParams.fMtu, MSG_PEEK );
  446. if ( ( rx_bytes == 0 ) || ( rx_bytes == SOCKET_ERROR ) )
  447. return rx_bytes;
  448. switch ( fParams.fNetworkMode )
  449. {
  450. case 'n' : //normal mode
  451. //normal use of the network : allow to use full bandwith
  452. // - extra latency is set to one cycle, what corresponds to the time needed to receive streams using full network bandwith
  453. // - if the network is too fast, just wait the next cycle, the benefit here is the master's cycle is shorter
  454. // - indeed, data is supposed to be on the network rx buffer, so we don't have to wait for it
  455. if ( rx_head->fCycle == fTxHeader.fCycle )
  456. return 0;
  457. else
  458. {
  459. rx_bytes = Recv ( rx_head->fPacketSize, 0 );
  460. }
  461. break;
  462. case 'f' : //fast mode
  463. //fast mode suppose the network bandwith is larger than required for the transmission (only a few channels for example)
  464. // - packets can be quickly received, quickly is here relative to the cycle duration
  465. // - here, receive data, we can't keep it queued on the rx buffer,
  466. // - but if there is a cycle offset, tell the user, that means we're not in fast mode anymore, network is too slow
  467. rx_bytes = Recv ( rx_head->fPacketSize, 0 );
  468. if ( rx_head->fCycle != fTxHeader.fCycle )
  469. jack_error ( "%s, can't stay in fast network mode, data received too late (%d cycle(s) offset)", fParams.fName, fTxHeader.fCycle - rx_head->fCycle );
  470. break;
  471. }
  472. #ifdef JACK_MONITOR
  473. fMeasure[fMeasureId++] = ( ( ( float ) ( jack_get_time() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f;
  474. #endif
  475. if ( fParams.fReturnMidiChannels || fParams.fReturnAudioChannels )
  476. {
  477. do
  478. {
  479. //how much data is queued on the rx buffer ?
  480. rx_bytes = Recv ( fParams.fMtu, MSG_PEEK );
  481. if ( rx_bytes == SOCKET_ERROR )
  482. return rx_bytes;
  483. //if no data,
  484. if ( ( rx_bytes == 0 ) && ( ++jumpcnt == fNSubProcess ) )
  485. {
  486. jack_error ( "No data from %s...", fParams.fName );
  487. jumpcnt = 0;
  488. }
  489. //else if data is valid,
  490. if ( rx_bytes && ( rx_head->fDataStream == 'r' ) && ( rx_head->fID == fParams.fID ) )
  491. {
  492. //read data
  493. switch ( rx_head->fDataType )
  494. {
  495. case 'm': //midi
  496. Recv ( rx_head->fPacketSize, 0 );
  497. fRxHeader.fCycle = rx_head->fCycle;
  498. fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
  499. fNetMidiPlaybackBuffer->RenderFromNetwork ( rx_head->fSubCycle, rx_bytes - sizeof ( packet_header_t ) );
  500. if ( ++midi_recvd_pckt == rx_head->fNMidiPckt )
  501. fNetMidiPlaybackBuffer->RenderToJackPorts();
  502. jumpcnt = 0;
  503. break;
  504. case 'a': //audio
  505. Recv ( rx_head->fPacketSize, 0 );
  506. if ( !IsNextPacket ( &fRxHeader, rx_head, fNSubProcess ) )
  507. jack_error ( "Packet(s) missing from '%s'...", fParams.fName );
  508. fRxHeader.fCycle = rx_head->fCycle;
  509. fRxHeader.fSubCycle = rx_head->fSubCycle;
  510. fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
  511. fNetAudioPlaybackBuffer->RenderToJackPorts ( rx_head->fSubCycle );
  512. jumpcnt = 0;
  513. break;
  514. case 's': //sync
  515. if ( rx_head->fCycle == fTxHeader.fCycle )
  516. return 0;
  517. }
  518. }
  519. }
  520. while ( fRxHeader.fIsLastPckt != 'y' );
  521. }
  522. #ifdef JACK_MONITOR
  523. fMeasure[fMeasureId++] = ( ( ( float ) ( jack_get_time() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f;
  524. fMonitor->Write ( fMeasure );
  525. #endif
  526. return 0;
  527. }
  528. //JackNetMasterManager***********************************************************************************************
  529. JackNetMasterManager::JackNetMasterManager ( jack_client_t* client, const JSList* params ) : fSocket()
  530. {
  531. jack_log ( "JackNetMasterManager::JackNetMasterManager" );
  532. fManagerClient = client;
  533. fManagerName = jack_get_client_name ( fManagerClient );
  534. fMulticastIP = DEFAULT_MULTICAST_IP;
  535. fSocket.SetPort ( DEFAULT_PORT );
  536. fGlobalID = 0;
  537. fRunning = true;
  538. const JSList* node;
  539. const jack_driver_param_t* param;
  540. for ( node = params; node; node = jack_slist_next ( node ) )
  541. {
  542. param = ( const jack_driver_param_t* ) node->data;
  543. switch ( param->character )
  544. {
  545. case 'a' :
  546. fMulticastIP = strdup ( param->value.str );
  547. break;
  548. case 'p':
  549. fSocket.SetPort ( param->value.ui );
  550. }
  551. }
  552. //set sync callback
  553. jack_set_sync_callback ( fManagerClient, SetSyncCallback, this );
  554. //activate the client (for sync callback)
  555. if ( jack_activate ( fManagerClient ) != 0 )
  556. jack_error ( "Can't activate the network manager client, transport disabled." );
  557. //launch the manager thread
  558. if ( jack_client_create_thread ( fManagerClient, &fManagerThread, 0, 0, NetManagerThread, this ) )
  559. jack_error ( "Can't create the network manager control thread." );
  560. }
  561. JackNetMasterManager::~JackNetMasterManager()
  562. {
  563. jack_log ( "JackNetMasterManager::~JackNetMasterManager" );
  564. Exit();
  565. master_list_t::iterator it;
  566. for ( it = fMasterList.begin(); it != fMasterList.end(); it++ )
  567. delete ( *it );
  568. fSocket.Close();
  569. SocketAPIEnd();
  570. }
  571. int JackNetMasterManager::SetSyncCallback ( jack_transport_state_t state, jack_position_t* pos, void* arg )
  572. {
  573. JackNetMasterManager* master_manager = static_cast<JackNetMasterManager*> ( arg );
  574. return master_manager->SyncCallback ( state, pos );
  575. }
  576. int JackNetMasterManager::SyncCallback ( jack_transport_state_t state, jack_position_t* pos )
  577. {
  578. //check sync state for every master in the list
  579. int ret = 1;
  580. master_list_it_t it;
  581. for ( it = fMasterList.begin(); it != fMasterList.end(); it++ )
  582. if ( ( *it )->fSyncState == 0 )
  583. ret = 0;
  584. jack_log ( "JackNetMasterManager::SyncCallback returns '%s'", ( ret ) ? "true" : "false" );
  585. return ret;
  586. }
  587. void* JackNetMasterManager::NetManagerThread ( void* arg )
  588. {
  589. JackNetMasterManager* master_manager = static_cast<JackNetMasterManager*> ( arg );
  590. jack_info ( "Starting Jack Network Manager." );
  591. jack_info ( "Listening on '%s:%d'", master_manager->fMulticastIP, master_manager->fSocket.GetPort() );
  592. master_manager->Run();
  593. return NULL;
  594. }
  595. void JackNetMasterManager::Run()
  596. {
  597. jack_log ( "JackNetMasterManager::Run" );
  598. //utility variables
  599. int usec_timeout = 2000000;
  600. int attempt = 0;
  601. //data
  602. session_params_t params;
  603. int rx_bytes = 0;
  604. JackNetMaster* net_master;
  605. //init socket API (win32)
  606. if ( SocketAPIInit() < 0 )
  607. {
  608. jack_error ( "Can't init Socket API, exiting..." );
  609. return;
  610. }
  611. //socket
  612. if ( fSocket.NewSocket() == SOCKET_ERROR )
  613. {
  614. jack_error ( "Can't create the network management input socket : %s", StrError ( NET_ERROR_CODE ) );
  615. return;
  616. }
  617. //bind the socket to the local port
  618. if ( fSocket.Bind () == SOCKET_ERROR )
  619. {
  620. jack_error ( "Can't bind the network manager socket : %s", StrError ( NET_ERROR_CODE ) );
  621. fSocket.Close();
  622. return;
  623. }
  624. //join multicast group
  625. if ( fSocket.JoinMCastGroup ( fMulticastIP ) == SOCKET_ERROR )
  626. jack_error ( "Can't join multicast group : %s", StrError ( NET_ERROR_CODE ) );
  627. //local loop
  628. if ( fSocket.SetLocalLoop() == SOCKET_ERROR )
  629. jack_error ( "Can't set local loop : %s", StrError ( NET_ERROR_CODE ) );
  630. //set a timeout on the multicast receive (the thread can now be cancelled)
  631. if ( fSocket.SetTimeOut ( usec_timeout ) == SOCKET_ERROR )
  632. jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) );
  633. jack_info ( "Waiting for a slave..." );
  634. //main loop, wait for data, deal with it and wait again
  635. do
  636. {
  637. rx_bytes = fSocket.CatchHost ( &params, sizeof ( session_params_t ), 0 );
  638. if ( ( rx_bytes == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) )
  639. {
  640. jack_error ( "Error in receive : %s", StrError ( NET_ERROR_CODE ) );
  641. if ( ++attempt == 10 )
  642. {
  643. jack_error ( "Can't receive on the socket, exiting net manager." );
  644. return;
  645. }
  646. }
  647. if ( rx_bytes == sizeof ( session_params_t ) )
  648. {
  649. switch ( GetPacketType ( &params ) )
  650. {
  651. case SLAVE_AVAILABLE:
  652. if ( ( net_master = MasterInit ( params ) ) )
  653. SessionParamsDisplay ( &net_master->fParams );
  654. else
  655. jack_error ( "Can't init new net master..." );
  656. jack_info ( "Waiting for a slave..." );
  657. break;
  658. case KILL_MASTER:
  659. if ( KillMaster ( &params ) )
  660. jack_info ( "Waiting for a slave..." );
  661. break;
  662. default:
  663. break;
  664. }
  665. }
  666. }
  667. while ( fRunning );
  668. }
  669. void JackNetMasterManager::Exit()
  670. {
  671. jack_log ( "JackNetMasterManager::Exit" );
  672. fRunning = false;
  673. jack_client_stop_thread ( fManagerClient, fManagerThread );
  674. jack_info ( "Exiting net manager..." );
  675. }
  676. JackNetMaster* JackNetMasterManager::MasterInit ( session_params_t& params )
  677. {
  678. jack_log ( "JackNetMasterManager::MasterInit, Slave : %s", params.fName );
  679. //settings
  680. fSocket.GetName ( params.fMasterNetName );
  681. params.fID = ++fGlobalID;
  682. params.fSampleRate = jack_get_sample_rate ( fManagerClient );
  683. params.fPeriodSize = jack_get_buffer_size ( fManagerClient );
  684. params.fBitdepth = 0;
  685. SetFramesPerPacket ( &params );
  686. SetSlaveName ( params );
  687. //create a new master and add it to the list
  688. JackNetMaster* master = new JackNetMaster ( this, params );
  689. if ( master->Init() )
  690. {
  691. fMasterList.push_back ( master );
  692. return master;
  693. }
  694. delete master;
  695. return NULL;
  696. }
  697. void JackNetMasterManager::SetSlaveName ( session_params_t& params )
  698. {
  699. jack_log ( "JackNetMasterManager::SetSlaveName" );
  700. master_list_it_t it;
  701. for ( it = fMasterList.begin(); it != fMasterList.end(); it++ )
  702. if ( strcmp ( ( *it )->fParams.fName, params.fName ) == 0 )
  703. sprintf ( params.fName, "%s-%u", params.fName, params.fID );
  704. }
  705. master_list_it_t JackNetMasterManager::FindMaster ( uint32_t id )
  706. {
  707. jack_log ( "JackNetMasterManager::FindMaster, ID %u.", id );
  708. master_list_it_t it;
  709. for ( it = fMasterList.begin(); it != fMasterList.end(); it++ )
  710. if ( ( *it )->fParams.fID == id )
  711. return it;
  712. return it;
  713. }
  714. int JackNetMasterManager::KillMaster ( session_params_t* params )
  715. {
  716. jack_log ( "JackNetMasterManager::KillMaster, ID %u.", params->fID );
  717. master_list_it_t master = FindMaster ( params->fID );
  718. if ( master != fMasterList.end() )
  719. {
  720. fMasterList.erase ( master );
  721. delete *master;
  722. return 1;
  723. }
  724. return 0;
  725. }
  726. }//namespace
  727. static Jack::JackNetMasterManager* master_manager = NULL;
  728. #ifdef __cplusplus
  729. extern "C"
  730. {
  731. #endif
  732. EXPORT jack_driver_desc_t* jack_get_descriptor()
  733. {
  734. jack_driver_desc_t *desc;
  735. desc = ( jack_driver_desc_t* ) calloc ( 1, sizeof ( jack_driver_desc_t ) );
  736. strcpy ( desc->name, "netmanager" );
  737. desc->nparams = 2;
  738. desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) );
  739. int i = 0;
  740. strcpy ( desc->params[i].name, "multicast_ip" );
  741. desc->params[i].character = 'a';
  742. desc->params[i].type = JackDriverParamString;
  743. strcpy ( desc->params[i].value.str, DEFAULT_MULTICAST_IP );
  744. strcpy ( desc->params[i].short_desc, "Multicast Address" );
  745. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  746. i++;
  747. strcpy ( desc->params[i].name, "udp_net_port" );
  748. desc->params[i].character = 'p';
  749. desc->params[i].type = JackDriverParamInt;
  750. desc->params[i].value.i = DEFAULT_PORT;
  751. strcpy ( desc->params[i].short_desc, "UDP port" );
  752. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  753. return desc;
  754. }
  755. EXPORT int jack_internal_initialize ( jack_client_t* jack_client, const JSList* params )
  756. {
  757. if ( master_manager )
  758. {
  759. jack_error ( "Master Manager already loaded" );
  760. return 1;
  761. }
  762. else
  763. {
  764. jack_log ( "Loading Master Manager" );
  765. master_manager = new Jack::JackNetMasterManager ( jack_client, params );
  766. return ( master_manager ) ? 0 : 1;
  767. }
  768. }
  769. EXPORT int jack_initialize ( jack_client_t* jack_client, const char* load_init )
  770. {
  771. JSList* params = NULL;
  772. jack_driver_desc_t* desc = jack_get_descriptor();
  773. Jack::JackArgParser parser ( load_init );
  774. if ( parser.GetArgc() > 0 )
  775. {
  776. if ( parser.ParseParams ( desc, &params ) < 0 )
  777. jack_error ( "Internal client JackArgParser::ParseParams error." );
  778. }
  779. return jack_internal_initialize ( jack_client, params );
  780. }
  781. EXPORT void jack_finish ( void* arg )
  782. {
  783. if ( master_manager )
  784. {
  785. jack_log ( "Unloading Master Manager" );
  786. delete master_manager;
  787. master_manager = NULL;
  788. }
  789. }
  790. #ifdef __cplusplus
  791. }
  792. #endif