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.

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