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.

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