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.

839 lines
33KB

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