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.

779 lines
30KB

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