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.

714 lines
27KB

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