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.

761 lines
28KB

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