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.

595 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. #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 )
  26. : JackNetMasterInterface ( params, socket )
  27. {
  28. jack_log ( "JackNetMaster::JackNetMaster" );
  29. //settings
  30. fClientName = const_cast<char*> ( fParams.fName );
  31. fJackClient = NULL;
  32. fSyncState = 1;
  33. uint port_index;
  34. //jack audio ports
  35. fAudioCapturePorts = new jack_port_t* [fParams.fSendAudioChannels];
  36. for ( port_index = 0; port_index < fParams.fSendAudioChannels; port_index++ )
  37. fAudioCapturePorts[port_index] = NULL;
  38. fAudioPlaybackPorts = new jack_port_t* [fParams.fReturnAudioChannels];
  39. for ( port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++ )
  40. fAudioPlaybackPorts[port_index] = NULL;
  41. //jack midi ports
  42. fMidiCapturePorts = new jack_port_t* [fParams.fSendMidiChannels];
  43. for ( port_index = 0; port_index < fParams.fSendMidiChannels; port_index++ )
  44. fMidiCapturePorts[port_index] = NULL;
  45. fMidiPlaybackPorts = new jack_port_t* [fParams.fReturnMidiChannels];
  46. for ( port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++ )
  47. fMidiPlaybackPorts[port_index] = NULL;
  48. //monitor
  49. #ifdef JACK_MONITOR
  50. fPeriodUsecs = ( int ) ( 1000000.f * ( ( float ) fParams.fPeriodSize / ( float ) fParams.fSampleRate ) );
  51. string plot_name;
  52. plot_name = string ( fParams.fName );
  53. plot_name += string ( "_master" );
  54. plot_name += string ( ( fParams.fSlaveSyncMode ) ? "_sync" : "_async" );
  55. plot_name += ( fParams.fNetworkMode == 'f' ) ? string ( "_fast" ) : string ( "_normal" );
  56. fNetTimeMon = new JackGnuPlotMonitor<float> ( 128, 4, plot_name );
  57. string net_time_mon_fields[] =
  58. {
  59. string ( "sync send" ),
  60. string ( "end of send" ),
  61. string ( "sync recv" ),
  62. string ( "end of cycle" )
  63. };
  64. string net_time_mon_options[] =
  65. {
  66. string ( "set xlabel \"audio cycles\"" ),
  67. string ( "set ylabel \"% of audio cycle\"" )
  68. };
  69. fNetTimeMon->SetPlotFile ( net_time_mon_options, 2, net_time_mon_fields, 4 );
  70. #endif
  71. }
  72. JackNetMaster::~JackNetMaster()
  73. {
  74. jack_log ( "JackNetMaster::~JackNetMaster, ID %u.", fParams.fID );
  75. if ( fJackClient )
  76. {
  77. jack_deactivate ( fJackClient );
  78. FreePorts();
  79. jack_client_close ( fJackClient );
  80. }
  81. delete[] fAudioCapturePorts;
  82. delete[] fAudioPlaybackPorts;
  83. delete[] fMidiCapturePorts;
  84. delete[] fMidiPlaybackPorts;
  85. #ifdef JACK_MONITOR
  86. fNetTimeMon->Save();
  87. delete fNetTimeMon;
  88. #endif
  89. }
  90. bool JackNetMaster::Init()
  91. {
  92. //network init
  93. if ( !JackNetMasterInterface::Init() )
  94. return false;
  95. //jack client and process
  96. jack_status_t status;
  97. if ( ( fJackClient = jack_client_open ( fClientName, JackNullOption, &status, NULL ) ) == NULL )
  98. {
  99. jack_error ( "Can't open a new jack client." );
  100. return false;
  101. }
  102. jack_set_process_callback ( fJackClient, SetProcess, this );
  103. if ( AllocPorts() != 0 )
  104. {
  105. jack_error ( "Can't allocate jack ports." );
  106. goto fail;
  107. }
  108. //process can now run
  109. fRunning = true;
  110. //finally activate jack client
  111. if ( jack_activate ( fJackClient ) != 0 )
  112. {
  113. jack_error ( "Can't activate jack client." );
  114. goto fail;
  115. }
  116. jack_info ( "NetJack new master started." );
  117. return true;
  118. fail:
  119. FreePorts();
  120. jack_client_close ( fJackClient );
  121. fJackClient = NULL;
  122. return false;
  123. }
  124. int JackNetMaster::AllocPorts()
  125. {
  126. jack_log ( "JackNetMaster::AllocPorts" );
  127. uint i;
  128. char name[24];
  129. jack_nframes_t port_latency = jack_get_buffer_size ( fJackClient );
  130. unsigned long port_flags;
  131. //audio
  132. port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
  133. for ( i = 0; i < fParams.fSendAudioChannels; i++ )
  134. {
  135. sprintf ( name, "to_slave_%d", i+1 );
  136. if ( ( fAudioCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0 ) ) == NULL )
  137. return -1;
  138. jack_port_set_latency ( fAudioCapturePorts[i], 0 );
  139. }
  140. port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
  141. for ( i = 0; i < fParams.fReturnAudioChannels; i++ )
  142. {
  143. sprintf ( name, "from_slave_%d", i+1 );
  144. if ( ( fAudioPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0 ) ) == NULL )
  145. return -1;
  146. jack_port_set_latency ( fAudioPlaybackPorts[i], ( fParams.fNetworkMode == 'f' ) ? 0 : port_latency + ( fParams.fSlaveSyncMode ) ? 0 : port_latency );
  147. }
  148. //midi
  149. port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
  150. for ( i = 0; i < fParams.fSendMidiChannels; i++ )
  151. {
  152. sprintf ( name, "midi_to_slave_%d", i+1 );
  153. if ( ( fMidiCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, port_flags, 0 ) ) == NULL )
  154. return -1;
  155. jack_port_set_latency ( fMidiCapturePorts[i], 0 );
  156. }
  157. port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
  158. for ( i = 0; i < fParams.fReturnMidiChannels; i++ )
  159. {
  160. sprintf ( name, "midi_from_slave_%d", i+1 );
  161. if ( ( fMidiPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, port_flags, 0 ) ) == NULL )
  162. return -1;
  163. jack_port_set_latency ( fMidiPlaybackPorts[i], ( fParams.fNetworkMode == 'f' ) ? 0 : port_latency + ( fParams.fSlaveSyncMode ) ? 0 : port_latency );
  164. }
  165. return 0;
  166. }
  167. void JackNetMaster::FreePorts()
  168. {
  169. jack_log ( "JackNetMaster::FreePorts, ID %u", fParams.fID );
  170. uint port_index;
  171. for ( port_index = 0; port_index < fParams.fSendAudioChannels; port_index++ )
  172. if ( fAudioCapturePorts[port_index] )
  173. jack_port_unregister ( fJackClient, fAudioCapturePorts[port_index] );
  174. for ( port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++ )
  175. if ( fAudioPlaybackPorts[port_index] )
  176. jack_port_unregister ( fJackClient, fAudioPlaybackPorts[port_index] );
  177. for ( port_index = 0; port_index < fParams.fSendMidiChannels; port_index++ )
  178. if ( fMidiCapturePorts[port_index] )
  179. jack_port_unregister ( fJackClient, fMidiCapturePorts[port_index] );
  180. for ( port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++ )
  181. if ( fMidiPlaybackPorts[port_index] )
  182. jack_port_unregister ( fJackClient, fMidiPlaybackPorts[port_index] );
  183. }
  184. int JackNetMaster::SetSyncPacket()
  185. {
  186. if ( fParams.fTransportSync )
  187. {
  188. //TODO : set the TransportData
  189. //copy to TxBuffer
  190. memcpy ( fTxData, &fTransportData, sizeof ( net_transport_data_t ) );
  191. }
  192. return 0;
  193. }
  194. int JackNetMaster::SetProcess ( jack_nframes_t nframes, void* arg )
  195. {
  196. JackNetMaster* master = static_cast<JackNetMaster*> ( arg );
  197. return master->Process();
  198. }
  199. int JackNetMaster::Process()
  200. {
  201. if ( !fRunning )
  202. return 0;
  203. uint port_index;
  204. int res = 0;
  205. #ifdef JACK_MONITOR
  206. jack_time_t begin_time = jack_get_time();
  207. fNetTimeMon->New();
  208. #endif
  209. //buffers
  210. for ( port_index = 0; port_index < fParams.fSendMidiChannels; port_index++ )
  211. fNetMidiCaptureBuffer->SetBuffer ( port_index,
  212. static_cast<JackMidiBuffer*> ( jack_port_get_buffer ( fMidiCapturePorts[port_index],
  213. fParams.fPeriodSize ) ) );
  214. for ( port_index = 0; port_index < fParams.fSendAudioChannels; port_index++ )
  215. fNetAudioCaptureBuffer->SetBuffer ( port_index,
  216. static_cast<sample_t*> ( jack_port_get_buffer ( fAudioCapturePorts[port_index],
  217. fParams.fPeriodSize ) ) );
  218. for ( port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++ )
  219. fNetMidiPlaybackBuffer->SetBuffer ( port_index,
  220. static_cast<JackMidiBuffer*> ( jack_port_get_buffer ( fMidiPlaybackPorts[port_index],
  221. fParams.fPeriodSize ) ) );
  222. for ( port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++ )
  223. fNetAudioPlaybackBuffer->SetBuffer ( port_index,
  224. static_cast<sample_t*> ( jack_port_get_buffer ( fAudioPlaybackPorts[port_index],
  225. fParams.fPeriodSize ) ) );
  226. //Set the first packet to send
  227. memset ( fTxData, 0, fPayloadSize );
  228. SetSyncPacket();
  229. //send sync
  230. if ( SyncSend() == SOCKET_ERROR )
  231. return SOCKET_ERROR;
  232. #ifdef JACK_MONITOR
  233. fNetTimeMon->Add ( ( ( ( float ) ( jack_get_time() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f );
  234. #endif
  235. //send data
  236. if ( DataSend() == SOCKET_ERROR )
  237. return SOCKET_ERROR;
  238. #ifdef JACK_MONITOR
  239. fNetTimeMon->Add ( ( ( ( float ) ( jack_get_time() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f );
  240. #endif
  241. //receive sync
  242. res = SyncRecv();
  243. if ( ( res == 0 ) || ( res == SOCKET_ERROR ) )
  244. return res;
  245. #ifdef JACK_MONITOR
  246. fNetTimeMon->Add ( ( ( ( float ) ( jack_get_time() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f );
  247. #endif
  248. //receive data
  249. res = DataRecv();
  250. if ( ( res == 0 ) || ( res == SOCKET_ERROR ) )
  251. return res;
  252. #ifdef JACK_MONITOR
  253. fNetTimeMon->AddLast ( ( ( ( float ) ( jack_get_time() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f );
  254. #endif
  255. return 0;
  256. }
  257. //JackNetMasterManager***********************************************************************************************
  258. JackNetMasterManager::JackNetMasterManager ( jack_client_t* client, const JSList* params ) : fSocket()
  259. {
  260. jack_log ( "JackNetMasterManager::JackNetMasterManager" );
  261. fManagerClient = client;
  262. fManagerName = jack_get_client_name ( fManagerClient );
  263. fMulticastIP = DEFAULT_MULTICAST_IP;
  264. fSocket.SetPort ( DEFAULT_PORT );
  265. fGlobalID = 0;
  266. fRunning = true;
  267. const JSList* node;
  268. const jack_driver_param_t* param;
  269. for ( node = params; node; node = jack_slist_next ( node ) )
  270. {
  271. param = ( const jack_driver_param_t* ) node->data;
  272. switch ( param->character )
  273. {
  274. case 'a' :
  275. fMulticastIP = strdup ( param->value.str );
  276. break;
  277. case 'p':
  278. fSocket.SetPort ( param->value.ui );
  279. }
  280. }
  281. //set sync callback
  282. jack_set_sync_callback ( fManagerClient, SetSyncCallback, this );
  283. //activate the client (for sync callback)
  284. if ( jack_activate ( fManagerClient ) != 0 )
  285. jack_error ( "Can't activate the network manager client, transport disabled." );
  286. //launch the manager thread
  287. if ( jack_client_create_thread ( fManagerClient, &fManagerThread, 0, 0, NetManagerThread, this ) )
  288. jack_error ( "Can't create the network manager control thread." );
  289. }
  290. JackNetMasterManager::~JackNetMasterManager()
  291. {
  292. jack_log ( "JackNetMasterManager::~JackNetMasterManager" );
  293. jack_info ( "Exiting net manager..." );
  294. fRunning = false;
  295. jack_client_stop_thread ( fManagerClient, fManagerThread );
  296. master_list_t::iterator it;
  297. for ( it = fMasterList.begin(); it != fMasterList.end(); it++ )
  298. delete ( *it );
  299. fSocket.Close();
  300. SocketAPIEnd();
  301. }
  302. int JackNetMasterManager::SetSyncCallback ( jack_transport_state_t state, jack_position_t* pos, void* arg )
  303. {
  304. JackNetMasterManager* master_manager = static_cast<JackNetMasterManager*> ( arg );
  305. return master_manager->SyncCallback ( state, pos );
  306. }
  307. int JackNetMasterManager::SyncCallback ( jack_transport_state_t state, jack_position_t* pos )
  308. {
  309. //check sync state for every master in the list
  310. int ret = 1;
  311. master_list_it_t it;
  312. for ( it = fMasterList.begin(); it != fMasterList.end(); it++ )
  313. if ( ( *it )->fSyncState == 0 )
  314. ret = 0;
  315. jack_log ( "JackNetMasterManager::SyncCallback returns '%s'", ( ret ) ? "true" : "false" );
  316. return ret;
  317. }
  318. void* JackNetMasterManager::NetManagerThread ( void* arg )
  319. {
  320. JackNetMasterManager* master_manager = static_cast<JackNetMasterManager*> ( arg );
  321. jack_info ( "Starting Jack Network Manager." );
  322. jack_info ( "Listening on '%s:%d'", master_manager->fMulticastIP, master_manager->fSocket.GetPort() );
  323. master_manager->Run();
  324. return NULL;
  325. }
  326. void JackNetMasterManager::Run()
  327. {
  328. jack_log ( "JackNetMasterManager::Run" );
  329. //utility variables
  330. int attempt = 0;
  331. //data
  332. session_params_t params;
  333. int rx_bytes = 0;
  334. JackNetMaster* net_master;
  335. //init socket API (win32)
  336. if ( SocketAPIInit() < 0 )
  337. {
  338. jack_error ( "Can't init Socket API, exiting..." );
  339. return;
  340. }
  341. //socket
  342. if ( fSocket.NewSocket() == SOCKET_ERROR )
  343. {
  344. jack_error ( "Can't create the network management input socket : %s", StrError ( NET_ERROR_CODE ) );
  345. return;
  346. }
  347. //bind the socket to the local port
  348. if ( fSocket.Bind () == SOCKET_ERROR )
  349. {
  350. jack_error ( "Can't bind the network manager socket : %s", StrError ( NET_ERROR_CODE ) );
  351. fSocket.Close();
  352. return;
  353. }
  354. //join multicast group
  355. if ( fSocket.JoinMCastGroup ( fMulticastIP ) == SOCKET_ERROR )
  356. jack_error ( "Can't join multicast group : %s", StrError ( NET_ERROR_CODE ) );
  357. //local loop
  358. if ( fSocket.SetLocalLoop() == SOCKET_ERROR )
  359. jack_error ( "Can't set local loop : %s", StrError ( NET_ERROR_CODE ) );
  360. //set a timeout on the multicast receive (the thread can now be cancelled)
  361. if ( fSocket.SetTimeOut ( 2000000 ) == SOCKET_ERROR )
  362. jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) );
  363. jack_info ( "Waiting for a slave..." );
  364. //main loop, wait for data, deal with it and wait again
  365. do
  366. {
  367. rx_bytes = fSocket.CatchHost ( &params, sizeof ( session_params_t ), 0 );
  368. if ( ( rx_bytes == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) )
  369. {
  370. jack_error ( "Error in receive : %s", StrError ( NET_ERROR_CODE ) );
  371. if ( ++attempt == 10 )
  372. {
  373. jack_error ( "Can't receive on the socket, exiting net manager." );
  374. return;
  375. }
  376. }
  377. if ( rx_bytes == sizeof ( session_params_t ) )
  378. {
  379. switch ( GetPacketType ( &params ) )
  380. {
  381. case SLAVE_AVAILABLE:
  382. if ( ( net_master = MasterInit ( params ) ) )
  383. SessionParamsDisplay ( &net_master->fParams );
  384. else
  385. jack_error ( "Can't init new net master..." );
  386. jack_info ( "Waiting for a slave..." );
  387. break;
  388. case KILL_MASTER:
  389. if ( KillMaster ( &params ) )
  390. jack_info ( "Waiting for a slave..." );
  391. break;
  392. default:
  393. break;
  394. }
  395. }
  396. }
  397. while ( fRunning );
  398. }
  399. JackNetMaster* JackNetMasterManager::MasterInit ( session_params_t& params )
  400. {
  401. jack_log ( "JackNetMasterManager::MasterInit, Slave : %s", params.fName );
  402. //settings
  403. fSocket.GetName ( params.fMasterNetName );
  404. params.fID = ++fGlobalID;
  405. params.fSampleRate = jack_get_sample_rate ( fManagerClient );
  406. params.fPeriodSize = jack_get_buffer_size ( fManagerClient );
  407. params.fBitdepth = 0;
  408. SetFramesPerPacket ( &params );
  409. SetSlaveName ( params );
  410. //create a new master and add it to the list
  411. JackNetMaster* master = new JackNetMaster ( fSocket, params );
  412. if ( master->Init() )
  413. {
  414. fMasterList.push_back ( master );
  415. return master;
  416. }
  417. delete master;
  418. return NULL;
  419. }
  420. void JackNetMasterManager::SetSlaveName ( session_params_t& params )
  421. {
  422. jack_log ( "JackNetMasterManager::SetSlaveName" );
  423. master_list_it_t it;
  424. for ( it = fMasterList.begin(); it != fMasterList.end(); it++ )
  425. if ( strcmp ( ( *it )->fParams.fName, params.fName ) == 0 )
  426. sprintf ( params.fName, "%s-%u", params.fName, params.fID );
  427. }
  428. master_list_it_t JackNetMasterManager::FindMaster ( uint32_t id )
  429. {
  430. jack_log ( "JackNetMasterManager::FindMaster, ID %u.", id );
  431. master_list_it_t it;
  432. for ( it = fMasterList.begin(); it != fMasterList.end(); it++ )
  433. if ( ( *it )->fParams.fID == id )
  434. return it;
  435. return it;
  436. }
  437. int JackNetMasterManager::KillMaster ( session_params_t* params )
  438. {
  439. jack_log ( "JackNetMasterManager::KillMaster, ID %u.", params->fID );
  440. master_list_it_t master = FindMaster ( params->fID );
  441. if ( master != fMasterList.end() )
  442. {
  443. fMasterList.erase ( master );
  444. delete *master;
  445. return 1;
  446. }
  447. return 0;
  448. }
  449. }//namespace
  450. static Jack::JackNetMasterManager* master_manager = NULL;
  451. #ifdef __cplusplus
  452. extern "C"
  453. {
  454. #endif
  455. EXPORT jack_driver_desc_t* jack_get_descriptor()
  456. {
  457. jack_driver_desc_t *desc;
  458. desc = ( jack_driver_desc_t* ) calloc ( 1, sizeof ( jack_driver_desc_t ) );
  459. strcpy ( desc->name, "netmanager" );
  460. desc->nparams = 2;
  461. desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) );
  462. int i = 0;
  463. strcpy ( desc->params[i].name, "multicast_ip" );
  464. desc->params[i].character = 'a';
  465. desc->params[i].type = JackDriverParamString;
  466. strcpy ( desc->params[i].value.str, DEFAULT_MULTICAST_IP );
  467. strcpy ( desc->params[i].short_desc, "Multicast Address" );
  468. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  469. i++;
  470. strcpy ( desc->params[i].name, "udp_net_port" );
  471. desc->params[i].character = 'p';
  472. desc->params[i].type = JackDriverParamInt;
  473. desc->params[i].value.i = DEFAULT_PORT;
  474. strcpy ( desc->params[i].short_desc, "UDP port" );
  475. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  476. return desc;
  477. }
  478. EXPORT int jack_internal_initialize ( jack_client_t* jack_client, const JSList* params )
  479. {
  480. if ( master_manager )
  481. {
  482. jack_error ( "Master Manager already loaded" );
  483. return 1;
  484. }
  485. else
  486. {
  487. jack_log ( "Loading Master Manager" );
  488. master_manager = new Jack::JackNetMasterManager ( jack_client, params );
  489. return ( master_manager ) ? 0 : 1;
  490. }
  491. }
  492. EXPORT int jack_initialize ( jack_client_t* jack_client, const char* load_init )
  493. {
  494. JSList* params = NULL;
  495. jack_driver_desc_t* desc = jack_get_descriptor();
  496. Jack::JackArgParser parser ( load_init );
  497. if ( parser.GetArgc() > 0 )
  498. {
  499. if ( parser.ParseParams ( desc, &params ) < 0 )
  500. jack_error ( "Internal client JackArgParser::ParseParams error." );
  501. }
  502. return jack_internal_initialize ( jack_client, params );
  503. }
  504. EXPORT void jack_finish ( void* arg )
  505. {
  506. if ( master_manager )
  507. {
  508. jack_log ( "Unloading Master Manager" );
  509. delete master_manager;
  510. master_manager = NULL;
  511. }
  512. }
  513. #ifdef __cplusplus
  514. }
  515. #endif