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.

652 lines
21KB

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