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.

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