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.

835 lines
32KB

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