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.

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