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.

854 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. int usec_timeout = 1000000;
  145. uint attempt = 0;
  146. int rx_bytes = 0;
  147. int rx_bufsize = 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 ( usec_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. //set the new rx buffer size
  189. rx_bufsize = GetNetBufferSize ( &fParams );
  190. if ( fSocket.SetOption ( SOL_SOCKET, SO_RCVBUF, &rx_bufsize, sizeof ( rx_bufsize ) ) == SOCKET_ERROR )
  191. {
  192. jack_error ( "Can't set rx buffer size : %s", StrError ( NET_ERROR_CODE ) );
  193. return false;
  194. }
  195. //jack client and process
  196. jack_status_t status;
  197. jack_options_t options = JackNullOption;
  198. if ( ( fJackClient = jack_client_open ( fClientName, options, &status, NULL ) ) == NULL )
  199. {
  200. jack_error ( "Can't open a new jack client." );
  201. return false;
  202. }
  203. jack_set_process_callback ( fJackClient, SetProcess, this );
  204. //port registering
  205. uint i;
  206. char name[24];
  207. jack_nframes_t port_latency = jack_get_buffer_size ( fJackClient );
  208. unsigned long port_flags;
  209. //audio
  210. port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
  211. for ( i = 0; i < fParams.fSendAudioChannels; i++ )
  212. {
  213. sprintf ( name, "to_slave_%d", i+1 );
  214. if ( ( fAudioCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0 ) ) == NULL )
  215. goto fail;
  216. jack_port_set_latency ( fAudioCapturePorts[i], 0 );
  217. }
  218. port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
  219. for ( i = 0; i < fParams.fReturnAudioChannels; i++ )
  220. {
  221. sprintf ( name, "from_slave_%d", i+1 );
  222. if ( ( fAudioPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0 ) ) == NULL )
  223. goto fail;
  224. jack_port_set_latency ( fAudioPlaybackPorts[i], port_latency + ( fParams.fSlaveSyncMode ) ? 0 : port_latency );
  225. }
  226. //midi
  227. port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
  228. for ( i = 0; i < fParams.fSendMidiChannels; i++ )
  229. {
  230. sprintf ( name, "midi_to_slave_%d", i+1 );
  231. if ( ( fMidiCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, port_flags, 0 ) ) == NULL )
  232. goto fail;
  233. jack_port_set_latency ( fMidiCapturePorts[i], 0 );
  234. }
  235. port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
  236. for ( i = 0; i < fParams.fReturnMidiChannels; i++ )
  237. {
  238. sprintf ( name, "midi_from_slave_%d", i+1 );
  239. if ( ( fMidiPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, port_flags, 0 ) ) == NULL )
  240. goto fail;
  241. jack_port_set_latency ( fMidiPlaybackPorts[i], port_latency + ( fParams.fSlaveSyncMode ) ? 0 : port_latency );
  242. }
  243. fRunning = true;
  244. //finally activate jack client
  245. if ( jack_activate ( fJackClient ) != 0 )
  246. {
  247. jack_error ( "Can't activate jack client." );
  248. goto fail;
  249. }
  250. jack_info ( "NetJack new master started." );
  251. return true;
  252. fail:
  253. FreePorts();
  254. jack_client_close ( fJackClient );
  255. fJackClient = NULL;
  256. return false;
  257. }
  258. void JackNetMaster::FreePorts()
  259. {
  260. jack_log ( "JackNetMaster::FreePorts, ID %u", fParams.fID );
  261. uint port_index;
  262. for ( port_index = 0; port_index < fParams.fSendAudioChannels; port_index++ )
  263. if ( fAudioCapturePorts[port_index] )
  264. jack_port_unregister ( fJackClient, fAudioCapturePorts[port_index] );
  265. for ( port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++ )
  266. if ( fAudioPlaybackPorts[port_index] )
  267. jack_port_unregister ( fJackClient, fAudioPlaybackPorts[port_index] );
  268. for ( port_index = 0; port_index < fParams.fSendMidiChannels; port_index++ )
  269. if ( fMidiCapturePorts[port_index] )
  270. jack_port_unregister ( fJackClient, fMidiCapturePorts[port_index] );
  271. for ( port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++ )
  272. if ( fMidiPlaybackPorts[port_index] )
  273. jack_port_unregister ( fJackClient, fMidiPlaybackPorts[port_index] );
  274. }
  275. void JackNetMaster::Exit()
  276. {
  277. jack_log ( "JackNetMaster::Exit, ID %u", fParams.fID );
  278. //stop process
  279. fRunning = false;
  280. //send a 'multicast euthanasia request' - new socket is required on macosx
  281. jack_info ( "Exiting '%s'", fParams.fName );
  282. SetPacketType ( &fParams, KILL_MASTER );
  283. JackNetSocket mcast_socket ( fMasterManager->fMulticastIP, fSocket.GetPort() );
  284. if ( mcast_socket.NewSocket() == SOCKET_ERROR )
  285. jack_error ( "Can't create socket : %s", StrError ( NET_ERROR_CODE ) );
  286. if ( mcast_socket.SendTo ( &fParams, sizeof ( session_params_t ), 0, fMasterManager->fMulticastIP ) == SOCKET_ERROR )
  287. jack_error ( "Can't send suicide request : %s", StrError ( NET_ERROR_CODE ) );
  288. mcast_socket.Close();
  289. }
  290. int JackNetMaster::SetSyncPacket()
  291. {
  292. if ( fParams.fTransportSync )
  293. {
  294. //TODO : set the TransportData
  295. //copy to TxBuffer
  296. memcpy ( fTxData, &fTransportData, sizeof ( net_transport_data_t ) );
  297. }
  298. return 0;
  299. }
  300. int JackNetMaster::Send ( char* buffer, size_t size, int flags )
  301. {
  302. int tx_bytes;
  303. if ( ( tx_bytes = fSocket.Send ( buffer, size, flags ) ) == SOCKET_ERROR )
  304. {
  305. net_error_t error = fSocket.GetError();
  306. if ( fRunning && ( error == NET_CONN_ERROR ) )
  307. {
  308. //fatal connection issue, exit
  309. jack_error ( "'%s' : %s, please check network connection with '%s'.",
  310. fParams.fName, StrError ( NET_ERROR_CODE ), fParams.fSlaveNetName );
  311. Exit();
  312. }
  313. else if ( fRunning )
  314. jack_error ( "Error in send : %s", StrError ( NET_ERROR_CODE ) );
  315. }
  316. return tx_bytes;
  317. }
  318. int JackNetMaster::Recv ( size_t size, int flags )
  319. {
  320. int rx_bytes;
  321. if ( ( rx_bytes = fSocket.Recv ( fRxBuffer, size, flags ) ) == SOCKET_ERROR )
  322. {
  323. net_error_t error = fSocket.GetError();
  324. //no data isn't really a network error, so just return 0 avalaible read bytes
  325. if ( error == NET_NO_DATA )
  326. return 0;
  327. else if ( fRunning && ( error == NET_CONN_ERROR ) )
  328. {
  329. //fatal connection issue, exit
  330. jack_error ( "'%s' : %s, network connection with '%s' broken, exiting.",
  331. fParams.fName, StrError ( NET_ERROR_CODE ), fParams.fSlaveNetName );
  332. //ask to the manager to properly remove the master
  333. Exit();
  334. }
  335. else if ( fRunning )
  336. jack_error ( "Error in receive : %s", StrError ( NET_ERROR_CODE ) );
  337. }
  338. return rx_bytes;
  339. }
  340. int JackNetMaster::SetProcess ( jack_nframes_t nframes, void* arg )
  341. {
  342. JackNetMaster* master = static_cast<JackNetMaster*> ( arg );
  343. return master->Process();
  344. }
  345. int JackNetMaster::Process()
  346. {
  347. if ( !fRunning )
  348. return 0;
  349. int tx_bytes = 0;
  350. int rx_bytes = 0;
  351. uint midi_recvd_pckt = 0;
  352. uint jumpcnt = 0;
  353. fTxHeader.fCycle++;
  354. fTxHeader.fSubCycle = 0;
  355. fTxHeader.fIsLastPckt = 'n';
  356. packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
  357. #ifdef JACK_MONITOR
  358. jack_time_t begin_time = jack_get_time();
  359. fMeasureId = 0;
  360. #endif
  361. //buffers
  362. uint port_index;
  363. for ( port_index = 0; port_index < fParams.fSendMidiChannels; port_index++ )
  364. fNetMidiCaptureBuffer->SetBuffer ( port_index,
  365. static_cast<JackMidiBuffer*> ( jack_port_get_buffer ( fMidiCapturePorts[port_index],
  366. fParams.fPeriodSize ) ) );
  367. for ( port_index = 0; port_index < fParams.fSendAudioChannels; port_index++ )
  368. fNetAudioCaptureBuffer->SetBuffer ( port_index,
  369. static_cast<sample_t*> ( jack_port_get_buffer ( fAudioCapturePorts[port_index],
  370. fParams.fPeriodSize ) ) );
  371. for ( port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++ )
  372. fNetMidiPlaybackBuffer->SetBuffer ( port_index,
  373. static_cast<JackMidiBuffer*> ( jack_port_get_buffer ( fMidiPlaybackPorts[port_index],
  374. fParams.fPeriodSize ) ) );
  375. for ( port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++ )
  376. fNetAudioPlaybackBuffer->SetBuffer ( port_index,
  377. static_cast<sample_t*> ( jack_port_get_buffer ( fAudioPlaybackPorts[port_index],
  378. fParams.fPeriodSize ) ) );
  379. //send ------------------------------------------------------------------------------------------------------------------
  380. //sync
  381. fTxHeader.fDataType = 's';
  382. //memset ( fTxData, 0, fPayloadSize );
  383. //SetSyncPacket();
  384. if ( !fParams.fSendMidiChannels && !fParams.fSendAudioChannels )
  385. fTxHeader.fIsLastPckt = 'y';
  386. fTxHeader.fPacketSize = sizeof ( packet_header_t );
  387. memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) );
  388. tx_bytes = Send ( fTxBuffer, fTxHeader.fPacketSize, 0 );
  389. if ( tx_bytes == SOCKET_ERROR )
  390. return tx_bytes;
  391. #ifdef JACK_MONITOR
  392. fMeasure[fMeasureId++] = ( ( ( float ) ( jack_get_time() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f;
  393. #endif
  394. //midi
  395. if ( fParams.fSendMidiChannels )
  396. {
  397. fTxHeader.fDataType = 'm';
  398. fTxHeader.fMidiDataSize = fNetMidiCaptureBuffer->RenderFromJackPorts();
  399. fTxHeader.fNMidiPckt = GetNMidiPckt ( &fParams, fTxHeader.fMidiDataSize );
  400. for ( uint subproc = 0; subproc < fTxHeader.fNMidiPckt; subproc++ )
  401. {
  402. fTxHeader.fSubCycle = subproc;
  403. if ( ( subproc == ( fTxHeader.fNMidiPckt - 1 ) ) && !fParams.fSendAudioChannels )
  404. fTxHeader.fIsLastPckt = 'y';
  405. fTxHeader.fPacketSize = fNetMidiCaptureBuffer->RenderToNetwork ( subproc, fTxHeader.fMidiDataSize );
  406. fTxHeader.fPacketSize += sizeof ( packet_header_t );
  407. memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) );
  408. tx_bytes = Send ( fTxBuffer, fTxHeader.fPacketSize, 0 );
  409. if ( 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. fTxHeader.fPacketSize = fAudioTxLen;
  423. fNetAudioCaptureBuffer->RenderFromJackPorts ( subproc );
  424. memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) );
  425. tx_bytes = Send ( fTxBuffer, fTxHeader.fPacketSize, 0 );
  426. if ( tx_bytes == SOCKET_ERROR )
  427. return tx_bytes;
  428. }
  429. }
  430. #ifdef JACK_MONITOR
  431. fMeasure[fMeasureId++] = ( ( ( float ) ( jack_get_time() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f;
  432. #endif
  433. //receive --------------------------------------------------------------------------------------------------------------------
  434. //sync
  435. rx_bytes = Recv ( sizeof ( packet_header_t ), 0 );
  436. //wait here for sync, switch network mode :
  437. // -fast : this recv will wait for a long time (90% of cycle duration)
  438. // -slow : just wait for a short time, then return, the data will be available at the next cycle
  439. if ( ( rx_bytes == 0 ) || ( rx_bytes == SOCKET_ERROR ) )
  440. return rx_bytes;
  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. rx_bytes = Recv ( fParams.fMtu, MSG_PEEK );
  449. if ( rx_bytes == SOCKET_ERROR )
  450. return rx_bytes;
  451. if ( ++jumpcnt == fNSubProcess )
  452. {
  453. jack_error ( "No data from %s...", fParams.fName );
  454. jumpcnt = 0;
  455. }
  456. if ( rx_bytes && ( rx_head->fDataStream == 'r' ) && ( rx_head->fID == fParams.fID ) )
  457. {
  458. switch ( rx_head->fDataType )
  459. {
  460. case 'm': //midi
  461. Recv ( rx_head->fPacketSize, 0 );
  462. fRxHeader.fCycle = rx_head->fCycle;
  463. fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
  464. fNetMidiPlaybackBuffer->RenderFromNetwork ( rx_head->fSubCycle, rx_bytes - sizeof ( packet_header_t ) );
  465. if ( ++midi_recvd_pckt == rx_head->fNMidiPckt )
  466. fNetMidiPlaybackBuffer->RenderToJackPorts();
  467. jumpcnt = 0;
  468. break;
  469. case 'a': //audio
  470. Recv ( rx_head->fPacketSize, 0 );
  471. if ( !IsNextPacket ( &fRxHeader, rx_head, fNSubProcess ) )
  472. jack_error ( "Packet(s) missing from '%s'...", fParams.fName );
  473. fRxHeader.fCycle = rx_head->fCycle;
  474. fRxHeader.fSubCycle = rx_head->fSubCycle;
  475. fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
  476. fNetAudioPlaybackBuffer->RenderToJackPorts ( rx_head->fSubCycle );
  477. jumpcnt = 0;
  478. break;
  479. case 's': //sync
  480. Recv ( rx_head->fPacketSize, 0 );
  481. return 0;
  482. }
  483. }
  484. }
  485. while ( fRxHeader.fIsLastPckt != 'y' );
  486. }
  487. #ifdef JACK_MONITOR
  488. fMeasure[fMeasureId++] = ( ( ( float ) ( jack_get_time() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f;
  489. fMonitor->Write ( fMeasure );
  490. if ( fTxHeader.fCycle - fRxHeader.fCycle )
  491. jack_log ( "NetMonitor::%s %d", ( fParams.fSlaveSyncMode ) ? "SyncCycleOffset" : "AsyncCycleOffset", fTxHeader.fCycle - fRxHeader.fCycle );
  492. #endif
  493. return 0;
  494. }
  495. //JackNetMasterManager***********************************************************************************************
  496. JackNetMasterManager::JackNetMasterManager ( jack_client_t* client, const JSList* params ) : fSocket()
  497. {
  498. jack_log ( "JackNetMasterManager::JackNetMasterManager" );
  499. fManagerClient = client;
  500. fManagerName = jack_get_client_name ( fManagerClient );
  501. fMulticastIP = DEFAULT_MULTICAST_IP;
  502. fSocket.SetPort ( DEFAULT_PORT );
  503. fGlobalID = 0;
  504. fRunning = true;
  505. const JSList* node;
  506. const jack_driver_param_t* param;
  507. for ( node = params; node; node = jack_slist_next ( node ) )
  508. {
  509. param = ( const jack_driver_param_t* ) node->data;
  510. switch ( param->character )
  511. {
  512. case 'a' :
  513. fMulticastIP = strdup ( param->value.str );
  514. break;
  515. case 'p':
  516. fSocket.SetPort ( param->value.ui );
  517. }
  518. }
  519. //set sync callback
  520. jack_set_sync_callback ( fManagerClient, SetSyncCallback, this );
  521. //activate the client (for sync callback)
  522. if ( jack_activate ( fManagerClient ) != 0 )
  523. jack_error ( "Can't activate the network manager client, transport disabled." );
  524. //launch the manager thread
  525. if ( jack_client_create_thread ( fManagerClient, &fManagerThread, 0, 0, NetManagerThread, this ) )
  526. jack_error ( "Can't create the network manager control thread." );
  527. }
  528. JackNetMasterManager::~JackNetMasterManager()
  529. {
  530. jack_log ( "JackNetMasterManager::~JackNetMasterManager" );
  531. Exit();
  532. master_list_t::iterator it;
  533. for ( it = fMasterList.begin(); it != fMasterList.end(); it++ )
  534. delete ( *it );
  535. fSocket.Close();
  536. SocketAPIEnd();
  537. }
  538. int JackNetMasterManager::SetSyncCallback ( jack_transport_state_t state, jack_position_t* pos, void* arg )
  539. {
  540. JackNetMasterManager* master_manager = static_cast<JackNetMasterManager*> ( arg );
  541. return master_manager->SyncCallback ( state, pos );
  542. }
  543. int JackNetMasterManager::SyncCallback ( jack_transport_state_t state, jack_position_t* pos )
  544. {
  545. //check sync state for every master in the list
  546. int ret = 1;
  547. master_list_it_t it;
  548. for ( it = fMasterList.begin(); it != fMasterList.end(); it++ )
  549. if ( ( *it )->fSyncState == 0 )
  550. ret = 0;
  551. jack_log ( "JackNetMasterManager::SyncCallback returns '%s'", ( ret ) ? "true" : "false" );
  552. return ret;
  553. }
  554. void* JackNetMasterManager::NetManagerThread ( void* arg )
  555. {
  556. JackNetMasterManager* master_manager = static_cast<JackNetMasterManager*> ( arg );
  557. jack_info ( "Starting Jack Network Manager." );
  558. jack_info ( "Listening on '%s:%d'", master_manager->fMulticastIP, master_manager->fSocket.GetPort() );
  559. master_manager->Run();
  560. return NULL;
  561. }
  562. void JackNetMasterManager::Run()
  563. {
  564. jack_log ( "JackNetMasterManager::Run" );
  565. //utility variables
  566. int usec_timeout = 2000000;
  567. int attempt = 0;
  568. //data
  569. session_params_t params;
  570. int rx_bytes = 0;
  571. JackNetMaster* net_master;
  572. //init socket API (win32)
  573. if ( SocketAPIInit() < 0 )
  574. {
  575. jack_error ( "Can't init Socket API, exiting..." );
  576. return;
  577. }
  578. //socket
  579. if ( fSocket.NewSocket() == SOCKET_ERROR )
  580. {
  581. jack_error ( "Can't create the network management input socket : %s", StrError ( NET_ERROR_CODE ) );
  582. return;
  583. }
  584. //bind the socket to the local port
  585. if ( fSocket.Bind () == SOCKET_ERROR )
  586. {
  587. jack_error ( "Can't bind the network manager socket : %s", StrError ( NET_ERROR_CODE ) );
  588. fSocket.Close();
  589. return;
  590. }
  591. //join multicast group
  592. if ( fSocket.JoinMCastGroup ( fMulticastIP ) == SOCKET_ERROR )
  593. jack_error ( "Can't join multicast group : %s", StrError ( NET_ERROR_CODE ) );
  594. //local loop
  595. if ( fSocket.SetLocalLoop() == SOCKET_ERROR )
  596. jack_error ( "Can't set local loop : %s", StrError ( NET_ERROR_CODE ) );
  597. //set a timeout on the multicast receive (the thread can now be cancelled)
  598. if ( fSocket.SetTimeOut ( usec_timeout ) == SOCKET_ERROR )
  599. jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) );
  600. jack_info ( "Waiting for a slave..." );
  601. //main loop, wait for data, deal with it and wait again
  602. do
  603. {
  604. rx_bytes = fSocket.CatchHost ( &params, sizeof ( session_params_t ), 0 );
  605. if ( ( rx_bytes == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) )
  606. {
  607. jack_error ( "Error in receive : %s", StrError ( NET_ERROR_CODE ) );
  608. if ( ++attempt == 10 )
  609. {
  610. jack_error ( "Can't receive on the socket, exiting net manager." );
  611. return;
  612. }
  613. }
  614. if ( rx_bytes == sizeof ( session_params_t ) )
  615. {
  616. switch ( GetPacketType ( &params ) )
  617. {
  618. case SLAVE_AVAILABLE:
  619. if ( ( net_master = MasterInit ( params ) ) )
  620. SessionParamsDisplay ( &net_master->fParams );
  621. else
  622. jack_error ( "Can't init new net master..." );
  623. jack_info ( "Waiting for a slave..." );
  624. break;
  625. case KILL_MASTER:
  626. if ( KillMaster ( &params ) )
  627. jack_info ( "Waiting for a slave..." );
  628. break;
  629. default:
  630. break;
  631. }
  632. }
  633. }
  634. while ( fRunning );
  635. }
  636. void JackNetMasterManager::Exit()
  637. {
  638. jack_log ( "JackNetMasterManager::Exit" );
  639. fRunning = false;
  640. jack_client_stop_thread ( fManagerClient, fManagerThread );
  641. jack_info ( "Exiting net manager..." );
  642. }
  643. JackNetMaster* JackNetMasterManager::MasterInit ( session_params_t& params )
  644. {
  645. jack_log ( "JackNetMasterManager::MasterInit, Slave : %s", params.fName );
  646. //settings
  647. fSocket.GetName ( params.fMasterNetName );
  648. params.fID = ++fGlobalID;
  649. params.fSampleRate = jack_get_sample_rate ( fManagerClient );
  650. params.fPeriodSize = jack_get_buffer_size ( fManagerClient );
  651. params.fBitdepth = 0;
  652. SetFramesPerPacket ( &params );
  653. SetSlaveName ( params );
  654. //create a new master and add it to the list
  655. JackNetMaster* master = new JackNetMaster ( this, params );
  656. if ( master->Init() )
  657. {
  658. fMasterList.push_back ( master );
  659. return master;
  660. }
  661. delete master;
  662. return NULL;
  663. }
  664. void JackNetMasterManager::SetSlaveName ( session_params_t& params )
  665. {
  666. jack_log ( "JackNetMasterManager::SetSlaveName" );
  667. master_list_it_t it;
  668. for ( it = fMasterList.begin(); it != fMasterList.end(); it++ )
  669. if ( strcmp ( ( *it )->fParams.fName, params.fName ) == 0 )
  670. sprintf ( params.fName, "%s-%u", params.fName, params.fID );
  671. }
  672. master_list_it_t JackNetMasterManager::FindMaster ( uint32_t id )
  673. {
  674. jack_log ( "JackNetMasterManager::FindMaster, ID %u.", id );
  675. master_list_it_t it;
  676. for ( it = fMasterList.begin(); it != fMasterList.end(); it++ )
  677. if ( ( *it )->fParams.fID == id )
  678. return it;
  679. return it;
  680. }
  681. int JackNetMasterManager::KillMaster ( session_params_t* params )
  682. {
  683. jack_log ( "JackNetMasterManager::KillMaster, ID %u.", params->fID );
  684. master_list_it_t master = FindMaster ( params->fID );
  685. if ( master != fMasterList.end() )
  686. {
  687. fMasterList.erase ( master );
  688. delete *master;
  689. return 1;
  690. }
  691. return 0;
  692. }
  693. }//namespace
  694. static Jack::JackNetMasterManager* master_manager = NULL;
  695. #ifdef __cplusplus
  696. extern "C"
  697. {
  698. #endif
  699. EXPORT jack_driver_desc_t* jack_get_descriptor()
  700. {
  701. jack_driver_desc_t *desc;
  702. desc = ( jack_driver_desc_t* ) calloc ( 1, sizeof ( jack_driver_desc_t ) );
  703. strcpy ( desc->name, "netmanager" );
  704. desc->nparams = 2;
  705. desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) );
  706. int i = 0;
  707. strcpy ( desc->params[i].name, "multicast_ip" );
  708. desc->params[i].character = 'a';
  709. desc->params[i].type = JackDriverParamString;
  710. strcpy ( desc->params[i].value.str, DEFAULT_MULTICAST_IP );
  711. strcpy ( desc->params[i].short_desc, "Multicast Address" );
  712. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  713. i++;
  714. strcpy ( desc->params[i].name, "udp_net_port" );
  715. desc->params[i].character = 'p';
  716. desc->params[i].type = JackDriverParamInt;
  717. desc->params[i].value.i = DEFAULT_PORT;
  718. strcpy ( desc->params[i].short_desc, "UDP port" );
  719. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  720. return desc;
  721. }
  722. EXPORT int jack_internal_initialize ( jack_client_t* jack_client, const JSList* params )
  723. {
  724. if ( master_manager )
  725. {
  726. jack_error ( "Master Manager already loaded" );
  727. return 1;
  728. }
  729. else
  730. {
  731. jack_log ( "Loading Master Manager" );
  732. master_manager = new Jack::JackNetMasterManager ( jack_client, params );
  733. return ( master_manager ) ? 0 : 1;
  734. }
  735. }
  736. EXPORT int jack_initialize ( jack_client_t* jack_client, const char* load_init )
  737. {
  738. JSList* params = NULL;
  739. jack_driver_desc_t* desc = jack_get_descriptor();
  740. Jack::JackArgParser parser ( load_init );
  741. if ( parser.GetArgc() > 0 )
  742. {
  743. if ( parser.ParseParams ( desc, &params ) < 0 )
  744. jack_error ( "Internal client JackArgParser::ParseParams error." );
  745. }
  746. return jack_internal_initialize ( jack_client, params );
  747. }
  748. EXPORT void jack_finish ( void* arg )
  749. {
  750. if ( master_manager )
  751. {
  752. jack_log ( "Unloading Master Manager" );
  753. delete master_manager;
  754. master_manager = NULL;
  755. }
  756. }
  757. #ifdef __cplusplus
  758. }
  759. #endif