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.

833 lines
31KB

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