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.

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