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.

740 lines
27KB

  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. #if defined(HAVE_CONFIG_H)
  16. #include "config.h"
  17. #endif
  18. #include "JackNetManager.h"
  19. #define DEFAULT_MULTICAST_IP "225.3.19.154"
  20. #define DEFAULT_PORT 19000
  21. using namespace std;
  22. namespace Jack
  23. {
  24. //JackNetMaster******************************************************************************************************
  25. JackNetMaster::JackNetMaster ( JackNetSocket& socket, session_params_t& params, const char* multicast_ip )
  26. : JackNetMasterInterface ( params, socket, multicast_ip )
  27. {
  28. jack_log ( "JackNetMaster::JackNetMaster" );
  29. //settings
  30. fClientName = const_cast<char*> ( fParams.fName );
  31. fJackClient = NULL;
  32. uint port_index;
  33. //jack audio ports
  34. fAudioCapturePorts = new jack_port_t* [fParams.fSendAudioChannels];
  35. for ( port_index = 0; port_index < fParams.fSendAudioChannels; port_index++ )
  36. fAudioCapturePorts[port_index] = NULL;
  37. fAudioPlaybackPorts = new jack_port_t* [fParams.fReturnAudioChannels];
  38. for ( port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++ )
  39. fAudioPlaybackPorts[port_index] = NULL;
  40. //jack midi ports
  41. fMidiCapturePorts = new jack_port_t* [fParams.fSendMidiChannels];
  42. for ( port_index = 0; port_index < fParams.fSendMidiChannels; port_index++ )
  43. fMidiCapturePorts[port_index] = NULL;
  44. fMidiPlaybackPorts = new jack_port_t* [fParams.fReturnMidiChannels];
  45. for ( port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++ )
  46. fMidiPlaybackPorts[port_index] = NULL;
  47. //monitor
  48. #ifdef JACK_MONITOR
  49. fPeriodUsecs = ( int ) ( 1000000.f * ( ( float ) fParams.fPeriodSize / ( float ) fParams.fSampleRate ) );
  50. string plot_name;
  51. plot_name = string ( fParams.fName );
  52. plot_name += string ( "_master" );
  53. plot_name += string ( ( fParams.fSlaveSyncMode ) ? "_sync" : "_async" );
  54. switch ( fParams.fNetworkMode )
  55. {
  56. case 's' :
  57. plot_name += string ( "_slow" );
  58. break;
  59. case 'n' :
  60. plot_name += string ( "_normal" );
  61. break;
  62. case 'f' :
  63. plot_name += string ( "_fast" );
  64. break;
  65. }
  66. fNetTimeMon = new JackGnuPlotMonitor<float> ( 128, 4, plot_name );
  67. string net_time_mon_fields[] =
  68. {
  69. string ( "sync send" ),
  70. string ( "end of send" ),
  71. string ( "sync recv" ),
  72. string ( "end of cycle" )
  73. };
  74. string net_time_mon_options[] =
  75. {
  76. string ( "set xlabel \"audio cycles\"" ),
  77. string ( "set ylabel \"% of audio cycle\"" )
  78. };
  79. fNetTimeMon->SetPlotFile ( net_time_mon_options, 2, net_time_mon_fields, 4 );
  80. #endif
  81. }
  82. JackNetMaster::~JackNetMaster()
  83. {
  84. jack_log ( "JackNetMaster::~JackNetMaster, ID %u.", fParams.fID );
  85. if ( fJackClient )
  86. {
  87. jack_deactivate ( fJackClient );
  88. FreePorts();
  89. jack_client_close ( fJackClient );
  90. }
  91. delete[] fAudioCapturePorts;
  92. delete[] fAudioPlaybackPorts;
  93. delete[] fMidiCapturePorts;
  94. delete[] fMidiPlaybackPorts;
  95. #ifdef JACK_MONITOR
  96. fNetTimeMon->Save();
  97. delete fNetTimeMon;
  98. #endif
  99. }
  100. //init--------------------------------------------------------------------------------
  101. bool JackNetMaster::Init()
  102. {
  103. //network init
  104. if ( !JackNetMasterInterface::Init() )
  105. return false;
  106. //set global parameters
  107. SetParams();
  108. //jack client and process
  109. jack_status_t status;
  110. if ( ( fJackClient = jack_client_open ( fClientName, JackNullOption, &status, NULL ) ) == NULL )
  111. {
  112. jack_error ( "Can't open a new jack client." );
  113. return false;
  114. }
  115. jack_set_process_callback ( fJackClient, SetProcess, this );
  116. if ( AllocPorts() != 0 )
  117. {
  118. jack_error ( "Can't allocate jack ports." );
  119. goto fail;
  120. }
  121. //process can now run
  122. fRunning = true;
  123. //finally activate jack client
  124. if ( jack_activate ( fJackClient ) != 0 )
  125. {
  126. jack_error ( "Can't activate jack client." );
  127. goto fail;
  128. }
  129. jack_info ( "NetJack new master started." );
  130. return true;
  131. fail:
  132. FreePorts();
  133. jack_client_close ( fJackClient );
  134. fJackClient = NULL;
  135. return false;
  136. }
  137. //jack ports--------------------------------------------------------------------------
  138. int JackNetMaster::AllocPorts()
  139. {
  140. jack_log ( "JackNetMaster::AllocPorts" );
  141. uint i;
  142. char name[24];
  143. jack_nframes_t port_latency = jack_get_buffer_size ( fJackClient );
  144. unsigned long port_flags;
  145. //audio
  146. port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
  147. for ( i = 0; i < fParams.fSendAudioChannels; i++ )
  148. {
  149. sprintf ( name, "to_slave_%d", i+1 );
  150. if ( ( fAudioCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0 ) ) == NULL )
  151. return -1;
  152. jack_port_set_latency ( fAudioCapturePorts[i], 0 );
  153. }
  154. port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
  155. for ( i = 0; i < fParams.fReturnAudioChannels; i++ )
  156. {
  157. sprintf ( name, "from_slave_%d", i+1 );
  158. if ( ( fAudioPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0 ) ) == NULL )
  159. return -1;
  160. jack_port_set_latency ( fAudioPlaybackPorts[i], ( fParams.fNetworkMode == 'f' ) ? 0 : port_latency + ( fParams.fSlaveSyncMode ) ? 0 : port_latency );
  161. }
  162. //midi
  163. port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
  164. for ( i = 0; i < fParams.fSendMidiChannels; i++ )
  165. {
  166. sprintf ( name, "midi_to_slave_%d", i+1 );
  167. if ( ( fMidiCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, port_flags, 0 ) ) == NULL )
  168. return -1;
  169. jack_port_set_latency ( fMidiCapturePorts[i], 0 );
  170. }
  171. port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
  172. for ( i = 0; i < fParams.fReturnMidiChannels; i++ )
  173. {
  174. sprintf ( name, "midi_from_slave_%d", i+1 );
  175. if ( ( fMidiPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, port_flags, 0 ) ) == NULL )
  176. return -1;
  177. jack_port_set_latency ( fMidiPlaybackPorts[i], ( fParams.fNetworkMode == 'f' ) ? 0 : port_latency + ( fParams.fSlaveSyncMode ) ? 0 : port_latency );
  178. }
  179. return 0;
  180. }
  181. void JackNetMaster::FreePorts()
  182. {
  183. jack_log ( "JackNetMaster::FreePorts, ID %u", fParams.fID );
  184. uint port_index;
  185. for ( port_index = 0; port_index < fParams.fSendAudioChannels; port_index++ )
  186. if ( fAudioCapturePorts[port_index] )
  187. jack_port_unregister ( fJackClient, fAudioCapturePorts[port_index] );
  188. for ( port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++ )
  189. if ( fAudioPlaybackPorts[port_index] )
  190. jack_port_unregister ( fJackClient, fAudioPlaybackPorts[port_index] );
  191. for ( port_index = 0; port_index < fParams.fSendMidiChannels; port_index++ )
  192. if ( fMidiCapturePorts[port_index] )
  193. jack_port_unregister ( fJackClient, fMidiCapturePorts[port_index] );
  194. for ( port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++ )
  195. if ( fMidiPlaybackPorts[port_index] )
  196. jack_port_unregister ( fJackClient, fMidiPlaybackPorts[port_index] );
  197. }
  198. //transport---------------------------------------------------------------------------
  199. int JackNetMaster::EncodeTransportData()
  200. {
  201. //is there a new timebase master ?
  202. //TODO : check if any timebase callback has been called (and if it's conditional or not) and set correct value...
  203. fTransportData.fTimebaseMaster = NO_CHANGE;
  204. //update state and position
  205. fTransportData.fState = static_cast<uint> ( jack_transport_query ( fJackClient, &fTransportData.fPosition ) );
  206. //is it a new state ?
  207. fTransportData.fNewState = ( fTransportData.fState != fLastTransportState );
  208. if ( fTransportData.fNewState )
  209. jack_info ( "'%s' : sending transport state '%s'.", fParams.fName, GetTransportState ( fTransportData.fState ) );
  210. fLastTransportState = fTransportData.fState;
  211. return 0;
  212. }
  213. int JackNetMaster::DecodeTransportData()
  214. {
  215. //is there timebase master change ?
  216. if ( fTransportData.fTimebaseMaster != NO_CHANGE )
  217. {
  218. int timebase = 0;
  219. switch ( fTransportData.fTimebaseMaster )
  220. {
  221. case RELEASE_TIMEBASEMASTER :
  222. timebase = jack_release_timebase ( fJackClient );
  223. if ( timebase < 0 )
  224. jack_error ( "Can't release timebase master." );
  225. else
  226. jack_info ( "'%s' isn't the timebase master anymore.", fParams.fName );
  227. break;
  228. case TIMEBASEMASTER :
  229. timebase = jack_set_timebase_callback ( fJackClient, 0, SetTimebaseCallback, this );
  230. if ( timebase < 0 )
  231. jack_error ( "Can't set a new timebase master." );
  232. else
  233. jack_info ( "'%s' is the new timebase master.", fParams.fName );
  234. break;
  235. case CONDITIONAL_TIMEBASEMASTER :
  236. timebase = jack_set_timebase_callback ( fJackClient, 1, SetTimebaseCallback, this );
  237. if ( timebase != EBUSY )
  238. {
  239. if ( timebase < 0 )
  240. jack_error ( "Can't set a new timebase master." );
  241. else
  242. jack_info ( "'%s' is the new timebase master.", fParams.fName );
  243. }
  244. break;
  245. }
  246. }
  247. //is the slave in a new transport state and is this state different from master's ?
  248. if ( fTransportData.fNewState && ( fTransportData.fState != ( uint ) jack_transport_query ( fJackClient, NULL ) ) )
  249. {
  250. switch ( fTransportData.fState )
  251. {
  252. case JackTransportStopped :
  253. jack_transport_stop ( fJackClient );
  254. jack_info ( "'%s' : transport stops.", fParams.fName );
  255. break;
  256. case JackTransportStarting :
  257. if ( jack_transport_reposition ( fJackClient, &fTransportData.fPosition ) < 0 )
  258. jack_error ( "Can't set new position." );
  259. jack_transport_start ( fJackClient );
  260. jack_info ( "'%s' : transport starts.", fParams.fName );
  261. break;
  262. case JackTransportNetStarting :
  263. jack_info ( "'%s' : transport is ready to roll.", fParams.fName );
  264. case JackTransportRolling :
  265. jack_info ( "'%s' : transport is rolling.", fParams.fName );
  266. break;
  267. }
  268. }
  269. return 0;
  270. }
  271. void JackNetMaster::SetTimebaseCallback ( jack_transport_state_t state, jack_nframes_t nframes, jack_position_t* pos, int new_pos, void* arg )
  272. {
  273. static_cast<JackNetMaster*> ( arg )->TimebaseCallback ( pos );
  274. }
  275. void JackNetMaster::TimebaseCallback ( jack_position_t* pos )
  276. {
  277. pos->bar = fTransportData.fPosition.bar;
  278. pos->beat = fTransportData.fPosition.beat;
  279. pos->tick = fTransportData.fPosition.tick;
  280. pos->bar_start_tick = fTransportData.fPosition.bar_start_tick;
  281. pos->beats_per_bar = fTransportData.fPosition.beats_per_bar;
  282. pos->beat_type = fTransportData.fPosition.beat_type;
  283. pos->ticks_per_beat = fTransportData.fPosition.ticks_per_beat;
  284. pos->beats_per_minute = fTransportData.fPosition.beats_per_minute;
  285. }
  286. //sync--------------------------------------------------------------------------------
  287. int JackNetMaster::EncodeSyncPacket()
  288. {
  289. //this method contains every step of sync packet informations coding
  290. //first of all, reset sync packet
  291. memset ( fTxData, 0, fPayloadSize );
  292. //then, first step : transport
  293. if ( fParams.fTransportSync )
  294. {
  295. if ( EncodeTransportData() < 0 )
  296. return -1;
  297. //copy to TxBuffer
  298. memcpy ( fTxData, &fTransportData, sizeof ( net_transport_data_t ) );
  299. }
  300. //then others
  301. //...
  302. return 0;
  303. }
  304. int JackNetMaster::DecodeSyncPacket()
  305. {
  306. //this method contains every step of sync packet informations decoding process
  307. //first : transport
  308. if ( fParams.fTransportSync )
  309. {
  310. //copy received transport data to transport data structure
  311. memcpy ( &fTransportData, fRxData, sizeof ( net_transport_data_t ) );
  312. if ( DecodeTransportData() < 0 )
  313. return -1;
  314. }
  315. //then others
  316. //...
  317. return 0;
  318. }
  319. bool JackNetMaster::IsSlaveReadyToRoll()
  320. {
  321. return ( fTransportData.fState == JackTransportNetStarting );
  322. }
  323. //process-----------------------------------------------------------------------------
  324. int JackNetMaster::SetProcess ( jack_nframes_t nframes, void* arg )
  325. {
  326. return static_cast<JackNetMaster*> ( arg )->Process();
  327. }
  328. int JackNetMaster::Process()
  329. {
  330. if ( !fRunning )
  331. return 0;
  332. uint port_index;
  333. int res = 0;
  334. #ifdef JACK_MONITOR
  335. jack_time_t begin_time = jack_get_time();
  336. fNetTimeMon->New();
  337. #endif
  338. //buffers
  339. for ( port_index = 0; port_index < fParams.fSendMidiChannels; port_index++ )
  340. fNetMidiCaptureBuffer->SetBuffer ( port_index, static_cast<JackMidiBuffer*> ( jack_port_get_buffer ( fMidiCapturePorts[port_index],
  341. fParams.fPeriodSize ) ) );
  342. for ( port_index = 0; port_index < fParams.fSendAudioChannels; port_index++ )
  343. fNetAudioCaptureBuffer->SetBuffer ( port_index, static_cast<sample_t*> ( jack_port_get_buffer ( fAudioCapturePorts[port_index],
  344. fParams.fPeriodSize ) ) );
  345. for ( port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++ )
  346. fNetMidiPlaybackBuffer->SetBuffer ( port_index, static_cast<JackMidiBuffer*> ( jack_port_get_buffer ( fMidiPlaybackPorts[port_index],
  347. fParams.fPeriodSize ) ) );
  348. for ( port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++ )
  349. fNetAudioPlaybackBuffer->SetBuffer ( port_index, static_cast<sample_t*> ( jack_port_get_buffer ( fAudioPlaybackPorts[port_index],
  350. fParams.fPeriodSize ) ) );
  351. //encode the first packet
  352. if ( EncodeSyncPacket() < 0 )
  353. return 0;
  354. //send sync
  355. if ( SyncSend() == SOCKET_ERROR )
  356. return SOCKET_ERROR;
  357. #ifdef JACK_MONITOR
  358. fNetTimeMon->Add ( ( ( ( float ) ( jack_get_time() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f );
  359. #endif
  360. //send data
  361. if ( DataSend() == SOCKET_ERROR )
  362. return SOCKET_ERROR;
  363. #ifdef JACK_MONITOR
  364. fNetTimeMon->Add ( ( ( ( float ) ( jack_get_time() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f );
  365. #endif
  366. //receive sync
  367. res = SyncRecv();
  368. if ( ( res == 0 ) || ( res == SOCKET_ERROR ) )
  369. return res;
  370. #ifdef JACK_MONITOR
  371. fNetTimeMon->Add ( ( ( ( float ) ( jack_get_time() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f );
  372. #endif
  373. //decode sync
  374. if ( DecodeSyncPacket() < 0 )
  375. return 0;
  376. //receive data
  377. res = DataRecv();
  378. if ( ( res == 0 ) || ( res == SOCKET_ERROR ) )
  379. return res;
  380. #ifdef JACK_MONITOR
  381. fNetTimeMon->AddLast ( ( ( ( float ) ( jack_get_time() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f );
  382. #endif
  383. return 0;
  384. }
  385. //JackNetMasterManager***********************************************************************************************
  386. JackNetMasterManager::JackNetMasterManager ( jack_client_t* client, const JSList* params ) : fSocket()
  387. {
  388. jack_log ( "JackNetMasterManager::JackNetMasterManager" );
  389. fManagerClient = client;
  390. fManagerName = jack_get_client_name ( fManagerClient );
  391. fMulticastIP = DEFAULT_MULTICAST_IP;
  392. fSocket.SetPort ( DEFAULT_PORT );
  393. fGlobalID = 0;
  394. fRunning = true;
  395. const JSList* node;
  396. const jack_driver_param_t* param;
  397. for ( node = params; node; node = jack_slist_next ( node ) )
  398. {
  399. param = ( const jack_driver_param_t* ) node->data;
  400. switch ( param->character )
  401. {
  402. case 'a' :
  403. fMulticastIP = strdup ( param->value.str );
  404. break;
  405. case 'p':
  406. fSocket.SetPort ( param->value.ui );
  407. }
  408. }
  409. //set sync callback
  410. jack_set_sync_callback ( fManagerClient, SetSyncCallback, this );
  411. //activate the client (for sync callback)
  412. if ( jack_activate ( fManagerClient ) != 0 )
  413. jack_error ( "Can't activate the network manager client, transport disabled." );
  414. //launch the manager thread
  415. if ( jack_client_create_thread ( fManagerClient, &fManagerThread, 0, 0, NetManagerThread, this ) )
  416. jack_error ( "Can't create the network manager control thread." );
  417. }
  418. JackNetMasterManager::~JackNetMasterManager()
  419. {
  420. jack_log ( "JackNetMasterManager::~JackNetMasterManager" );
  421. jack_info ( "Exiting net manager..." );
  422. fRunning = false;
  423. jack_client_stop_thread ( fManagerClient, fManagerThread );
  424. master_list_t::iterator it;
  425. for ( it = fMasterList.begin(); it != fMasterList.end(); it++ )
  426. delete ( *it );
  427. fSocket.Close();
  428. SocketAPIEnd();
  429. }
  430. int JackNetMasterManager::SetSyncCallback ( jack_transport_state_t state, jack_position_t* pos, void* arg )
  431. {
  432. return static_cast<JackNetMasterManager*> ( arg )->SyncCallback ( state, pos );
  433. }
  434. int JackNetMasterManager::SyncCallback ( jack_transport_state_t state, jack_position_t* pos )
  435. {
  436. //check if each slave is ready to roll
  437. int ret = 1;
  438. master_list_it_t it;
  439. for ( it = fMasterList.begin(); it != fMasterList.end(); it++ )
  440. if ( ! ( *it )->IsSlaveReadyToRoll() )
  441. ret = 0;
  442. jack_log ( "JackNetMasterManager::SyncCallback returns '%s'", ( ret ) ? "true" : "false" );
  443. return ret;
  444. }
  445. void* JackNetMasterManager::NetManagerThread ( void* arg )
  446. {
  447. JackNetMasterManager* master_manager = static_cast<JackNetMasterManager*> ( arg );
  448. jack_info ( "Starting Jack Network Manager." );
  449. jack_info ( "Listening on '%s:%d'", master_manager->fMulticastIP, master_manager->fSocket.GetPort() );
  450. master_manager->Run();
  451. return NULL;
  452. }
  453. void JackNetMasterManager::Run()
  454. {
  455. jack_log ( "JackNetMasterManager::Run" );
  456. //utility variables
  457. int attempt = 0;
  458. //data
  459. session_params_t params;
  460. int rx_bytes = 0;
  461. JackNetMaster* net_master;
  462. //init socket API (win32)
  463. if ( SocketAPIInit() < 0 )
  464. {
  465. jack_error ( "Can't init Socket API, exiting..." );
  466. return;
  467. }
  468. //socket
  469. if ( fSocket.NewSocket() == SOCKET_ERROR )
  470. {
  471. jack_error ( "Can't create the network management input socket : %s", StrError ( NET_ERROR_CODE ) );
  472. return;
  473. }
  474. //bind the socket to the local port
  475. if ( fSocket.Bind () == SOCKET_ERROR )
  476. {
  477. jack_error ( "Can't bind the network manager socket : %s", StrError ( NET_ERROR_CODE ) );
  478. fSocket.Close();
  479. return;
  480. }
  481. //join multicast group
  482. if ( fSocket.JoinMCastGroup ( fMulticastIP ) == SOCKET_ERROR )
  483. jack_error ( "Can't join multicast group : %s", StrError ( NET_ERROR_CODE ) );
  484. //local loop
  485. if ( fSocket.SetLocalLoop() == SOCKET_ERROR )
  486. jack_error ( "Can't set local loop : %s", StrError ( NET_ERROR_CODE ) );
  487. //set a timeout on the multicast receive (the thread can now be cancelled)
  488. if ( fSocket.SetTimeOut ( 2000000 ) == SOCKET_ERROR )
  489. jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) );
  490. jack_info ( "Waiting for a slave..." );
  491. //main loop, wait for data, deal with it and wait again
  492. do
  493. {
  494. rx_bytes = fSocket.CatchHost ( &params, sizeof ( session_params_t ), 0 );
  495. if ( ( rx_bytes == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) )
  496. {
  497. jack_error ( "Error in receive : %s", StrError ( NET_ERROR_CODE ) );
  498. if ( ++attempt == 10 )
  499. {
  500. jack_error ( "Can't receive on the socket, exiting net manager." );
  501. return;
  502. }
  503. }
  504. if ( rx_bytes == sizeof ( session_params_t ) )
  505. {
  506. switch ( GetPacketType ( &params ) )
  507. {
  508. case SLAVE_AVAILABLE:
  509. if ( ( net_master = MasterInit ( params ) ) )
  510. SessionParamsDisplay ( &net_master->fParams );
  511. else
  512. jack_error ( "Can't init new net master..." );
  513. jack_info ( "Waiting for a slave..." );
  514. break;
  515. case KILL_MASTER:
  516. if ( KillMaster ( &params ) )
  517. jack_info ( "Waiting for a slave..." );
  518. break;
  519. default:
  520. break;
  521. }
  522. }
  523. }
  524. while ( fRunning );
  525. }
  526. JackNetMaster* JackNetMasterManager::MasterInit ( session_params_t& params )
  527. {
  528. jack_log ( "JackNetMasterManager::MasterInit, Slave : %s", params.fName );
  529. //settings
  530. fSocket.GetName ( params.fMasterNetName );
  531. params.fID = ++fGlobalID;
  532. params.fSampleRate = jack_get_sample_rate ( fManagerClient );
  533. params.fPeriodSize = jack_get_buffer_size ( fManagerClient );
  534. params.fBitdepth = 0;
  535. SetSlaveName ( params );
  536. //create a new master and add it to the list
  537. JackNetMaster* master = new JackNetMaster ( fSocket, params, fMulticastIP );
  538. if ( master->Init() )
  539. {
  540. fMasterList.push_back ( master );
  541. return master;
  542. }
  543. delete master;
  544. return NULL;
  545. }
  546. void JackNetMasterManager::SetSlaveName ( session_params_t& params )
  547. {
  548. jack_log ( "JackNetMasterManager::SetSlaveName" );
  549. master_list_it_t it;
  550. for ( it = fMasterList.begin(); it != fMasterList.end(); it++ )
  551. if ( strcmp ( ( *it )->fParams.fName, params.fName ) == 0 )
  552. sprintf ( params.fName, "%s-%u", params.fName, params.fID );
  553. }
  554. master_list_it_t JackNetMasterManager::FindMaster ( uint32_t id )
  555. {
  556. jack_log ( "JackNetMasterManager::FindMaster, ID %u.", id );
  557. master_list_it_t it;
  558. for ( it = fMasterList.begin(); it != fMasterList.end(); it++ )
  559. if ( ( *it )->fParams.fID == id )
  560. return it;
  561. return it;
  562. }
  563. int JackNetMasterManager::KillMaster ( session_params_t* params )
  564. {
  565. jack_log ( "JackNetMasterManager::KillMaster, ID %u.", params->fID );
  566. master_list_it_t master = FindMaster ( params->fID );
  567. if ( master != fMasterList.end() )
  568. {
  569. fMasterList.erase ( master );
  570. delete *master;
  571. return 1;
  572. }
  573. return 0;
  574. }
  575. }//namespace
  576. static Jack::JackNetMasterManager* master_manager = NULL;
  577. #ifdef __cplusplus
  578. extern "C"
  579. {
  580. #endif
  581. EXPORT jack_driver_desc_t* jack_get_descriptor()
  582. {
  583. jack_driver_desc_t *desc;
  584. desc = ( jack_driver_desc_t* ) calloc ( 1, sizeof ( jack_driver_desc_t ) );
  585. strcpy ( desc->name, "netmanager" );
  586. desc->nparams = 2;
  587. desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) );
  588. int i = 0;
  589. strcpy ( desc->params[i].name, "multicast_ip" );
  590. desc->params[i].character = 'a';
  591. desc->params[i].type = JackDriverParamString;
  592. strcpy ( desc->params[i].value.str, DEFAULT_MULTICAST_IP );
  593. strcpy ( desc->params[i].short_desc, "Multicast Address" );
  594. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  595. i++;
  596. strcpy ( desc->params[i].name, "udp_net_port" );
  597. desc->params[i].character = 'p';
  598. desc->params[i].type = JackDriverParamInt;
  599. desc->params[i].value.i = DEFAULT_PORT;
  600. strcpy ( desc->params[i].short_desc, "UDP port" );
  601. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  602. return desc;
  603. }
  604. EXPORT int jack_internal_initialize ( jack_client_t* jack_client, const JSList* params )
  605. {
  606. if ( master_manager )
  607. {
  608. jack_error ( "Master Manager already loaded" );
  609. return 1;
  610. }
  611. else
  612. {
  613. jack_log ( "Loading Master Manager" );
  614. master_manager = new Jack::JackNetMasterManager ( jack_client, params );
  615. return ( master_manager ) ? 0 : 1;
  616. }
  617. }
  618. EXPORT int jack_initialize ( jack_client_t* jack_client, const char* load_init )
  619. {
  620. JSList* params = NULL;
  621. jack_driver_desc_t* desc = jack_get_descriptor();
  622. Jack::JackArgParser parser ( load_init );
  623. if ( parser.GetArgc() > 0 )
  624. {
  625. if ( parser.ParseParams ( desc, &params ) < 0 )
  626. jack_error ( "Internal client JackArgParser::ParseParams error." );
  627. }
  628. return jack_internal_initialize ( jack_client, params );
  629. }
  630. EXPORT void jack_finish ( void* arg )
  631. {
  632. if ( master_manager )
  633. {
  634. jack_log ( "Unloading Master Manager" );
  635. delete master_manager;
  636. master_manager = NULL;
  637. }
  638. }
  639. #ifdef __cplusplus
  640. }
  641. #endif