jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

742 lines
31KB

  1. /*
  2. Copyright (C) 2001 Paul Davis
  3. Copyright (C) 2008 Romain Moret at Grame
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. #include "JackNetDriver.h"
  17. #include "JackEngineControl.h"
  18. #include "JackClientControl.h"
  19. #include "JackGraphManager.h"
  20. #include "JackDriverLoader.h"
  21. #include "JackThreadedDriver.h"
  22. #include "JackWaitThreadedDriver.h"
  23. using namespace std;
  24. namespace Jack
  25. {
  26. JackNetDriver::JackNetDriver ( const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table,
  27. const char* ip, int port, int mtu, int midi_input_ports, int midi_output_ports,
  28. char* net_name, uint transport_sync, char network_mode )
  29. : JackAudioDriver ( name, alias, engine, table ), JackNetSlaveInterface ( ip, port )
  30. {
  31. jack_log ( "JackNetDriver::JackNetDriver ip %s, port %d", ip, port );
  32. // Use the hostname if no name parameter was given
  33. if (strcmp(net_name, "") == 0)
  34. GetHostName(net_name, JACK_CLIENT_NAME_SIZE);
  35. fParams.fMtu = mtu;
  36. fParams.fSendMidiChannels = midi_input_ports;
  37. fParams.fReturnMidiChannels = midi_output_ports;
  38. strcpy ( fParams.fName, net_name );
  39. fSocket.GetName ( fParams.fSlaveNetName );
  40. fParams.fTransportSync = transport_sync;
  41. fParams.fNetworkMode = network_mode;
  42. fLastTimebaseMaster = -1;
  43. fMidiCapturePortList = NULL;
  44. fMidiPlaybackPortList = NULL;
  45. #ifdef JACK_MONITOR
  46. fNetTimeMon = NULL;
  47. #endif
  48. }
  49. JackNetDriver::~JackNetDriver()
  50. {
  51. delete[] fMidiCapturePortList;
  52. delete[] fMidiPlaybackPortList;
  53. #ifdef JACK_MONITOR
  54. delete fNetTimeMon;
  55. #endif
  56. }
  57. //open, close, attach and detach------------------------------------------------------
  58. int JackNetDriver::Open ( jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, bool playing,
  59. int inchannels, int outchannels, bool monitor,
  60. const char* capture_driver_name, const char* playback_driver_name,
  61. jack_nframes_t capture_latency, jack_nframes_t playback_latency )
  62. {
  63. int res = JackAudioDriver::Open ( buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor,
  64. capture_driver_name, playback_driver_name, capture_latency, playback_latency );
  65. fEngineControl->fPeriod = 0;
  66. fEngineControl->fComputation = 500 * 1000;
  67. fEngineControl->fConstraint = 500 * 1000;
  68. return res;
  69. }
  70. #ifdef JACK_MONITOR
  71. int JackNetDriver::Close()
  72. {
  73. if ( fNetTimeMon )
  74. fNetTimeMon->Save();
  75. return JackDriver::Close();
  76. }
  77. #endif
  78. int JackNetDriver::Attach()
  79. {
  80. return 0;
  81. }
  82. int JackNetDriver::Detach()
  83. {
  84. return 0;
  85. }
  86. //init and restart--------------------------------------------------------------------
  87. bool JackNetDriver::Init()
  88. {
  89. jack_log ( "JackNetDriver::Init()" );
  90. //new loading, but existing socket, restart the driver
  91. if ( fSocket.IsSocket() )
  92. Restart();
  93. //set the parameters to send
  94. fParams.fSendAudioChannels = fCaptureChannels;
  95. fParams.fReturnAudioChannels = fPlaybackChannels;
  96. fParams.fSlaveSyncMode = fEngineControl->fSyncMode;
  97. //display some additional infos
  98. jack_info ( "Net driver started in %s mode %s Master's transport sync.",
  99. ( fParams.fSlaveSyncMode ) ? "sync" : "async", ( fParams.fTransportSync ) ? "with" : "without" );
  100. //init network
  101. if ( !JackNetSlaveInterface::Init() )
  102. return false;
  103. //set global paramaters
  104. SetParams();
  105. //register jack ports
  106. if ( AllocPorts() != 0 )
  107. {
  108. jack_error ( "Can't allocate ports." );
  109. return false;
  110. }
  111. //init done, display parameters
  112. SessionParamsDisplay ( &fParams );
  113. //monitor
  114. #ifdef JACK_MONITOR
  115. string plot_name;
  116. //NetTimeMon
  117. plot_name = string ( fParams.fName );
  118. plot_name += string ( "_slave" );
  119. plot_name += ( fEngineControl->fSyncMode ) ? string ( "_sync" ) : string ( "_async" );
  120. switch ( fParams.fNetworkMode )
  121. {
  122. case 's' :
  123. plot_name += string ( "_slow" );
  124. break;
  125. case 'n' :
  126. plot_name += string ( "_normal" );
  127. break;
  128. case 'f' :
  129. plot_name += string ( "_fast" );
  130. break;
  131. }
  132. fNetTimeMon = new JackGnuPlotMonitor<float> ( 128, 5, plot_name );
  133. string net_time_mon_fields[] =
  134. {
  135. string ( "sync decoded" ),
  136. string ( "end of read" ),
  137. string ( "start of write" ),
  138. string ( "sync send" ),
  139. string ( "end of write" )
  140. };
  141. string net_time_mon_options[] =
  142. {
  143. string ( "set xlabel \"audio cycles\"" ),
  144. string ( "set ylabel \"% of audio cycle\"" )
  145. };
  146. fNetTimeMon->SetPlotFile ( net_time_mon_options, 2, net_time_mon_fields, 5 );
  147. #endif
  148. //driver parametering
  149. JackAudioDriver::SetBufferSize ( fParams.fPeriodSize );
  150. JackAudioDriver::SetSampleRate ( fParams.fSampleRate );
  151. JackDriver::NotifyBufferSize ( fParams.fPeriodSize );
  152. JackDriver::NotifySampleRate ( fParams.fSampleRate );
  153. //transport engine parametering
  154. fEngineControl->fTransport.SetNetworkSync ( true );
  155. //allocate midi ports lists
  156. fMidiCapturePortList = new jack_port_id_t [fParams.fSendMidiChannels];
  157. fMidiPlaybackPortList = new jack_port_id_t [fParams.fReturnMidiChannels];
  158. assert(fMidiCapturePortList);
  159. assert(fMidiPlaybackPortList);
  160. return true;
  161. }
  162. void JackNetDriver::Restart()
  163. {
  164. jack_log ( "JackNetDriver::Restart" );
  165. jack_info ( "Restarting driver..." );
  166. delete[] fTxBuffer;
  167. fTxBuffer = NULL;
  168. delete[] fRxBuffer;
  169. fRxBuffer = NULL;
  170. delete fNetAudioCaptureBuffer;
  171. fNetAudioCaptureBuffer = NULL;
  172. delete fNetAudioPlaybackBuffer;
  173. fNetAudioPlaybackBuffer = NULL;
  174. delete fNetMidiCaptureBuffer;
  175. fNetMidiCaptureBuffer = NULL;
  176. delete fNetMidiPlaybackBuffer;
  177. fNetMidiPlaybackBuffer = NULL;
  178. FreePorts();
  179. delete[] fMidiCapturePortList;
  180. fMidiCapturePortList = NULL;
  181. delete[] fMidiPlaybackPortList;
  182. fMidiPlaybackPortList = NULL;
  183. #ifdef JACK_MONITOR
  184. delete fNetTimeMon;
  185. fNetTimeMon = NULL;
  186. #endif
  187. }
  188. //jack ports and buffers--------------------------------------------------------------
  189. int JackNetDriver::AllocPorts()
  190. {
  191. jack_log ( "JackNetDriver::AllocPorts fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate );
  192. JackPort* port;
  193. jack_port_id_t port_id;
  194. char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE];
  195. char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE];
  196. unsigned long port_flags;
  197. int audio_port_index;
  198. uint midi_port_index;
  199. //audio
  200. port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
  201. for ( audio_port_index = 0; audio_port_index < fCaptureChannels; audio_port_index++ )
  202. {
  203. snprintf ( alias, sizeof ( alias ) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, audio_port_index + 1 );
  204. snprintf ( name, sizeof ( name ) - 1, "%s:capture_%d", fClientControl.fName, audio_port_index + 1 );
  205. if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE,
  206. static_cast<JackPortFlags> ( port_flags ), fEngineControl->fBufferSize ) ) == NO_PORT )
  207. {
  208. jack_error ( "driver: cannot register port for %s", name );
  209. return -1;
  210. }
  211. port = fGraphManager->GetPort ( port_id );
  212. port->SetAlias ( alias );
  213. //port latency
  214. port->SetLatency ( fEngineControl->fBufferSize );
  215. fCapturePortList[audio_port_index] = port_id;
  216. jack_log ( "JackNetDriver::AllocPorts() fCapturePortList[%d] audio_port_index = %ld fPortLatency = %ld", audio_port_index, port_id, port->GetLatency() );
  217. }
  218. port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
  219. for ( audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++ )
  220. {
  221. snprintf ( alias, sizeof ( alias ) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, audio_port_index + 1 );
  222. snprintf ( name, sizeof ( name ) - 1, "%s:playback_%d",fClientControl.fName, audio_port_index + 1 );
  223. if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE,
  224. static_cast<JackPortFlags> ( port_flags ), fEngineControl->fBufferSize ) ) == NO_PORT )
  225. {
  226. jack_error ( "driver: cannot register port for %s", name );
  227. return -1;
  228. }
  229. port = fGraphManager->GetPort ( port_id );
  230. port->SetAlias ( alias );
  231. //port latency
  232. switch ( fParams.fNetworkMode )
  233. {
  234. case 'f' :
  235. port->SetLatency ( ( fEngineControl->fSyncMode ) ? 0 : fEngineControl->fBufferSize );
  236. break;
  237. case 'n' :
  238. port->SetLatency ( fEngineControl->fBufferSize + ( fEngineControl->fSyncMode ) ? 0 : fEngineControl->fBufferSize );
  239. break;
  240. case 's' :
  241. port->SetLatency ( 2 * fEngineControl->fBufferSize + ( fEngineControl->fSyncMode ) ? 0 : fEngineControl->fBufferSize );
  242. break;
  243. }
  244. fPlaybackPortList[audio_port_index] = port_id;
  245. jack_log ( "JackNetDriver::AllocPorts() fPlaybackPortList[%d] audio_port_index = %ld fPortLatency = %ld", audio_port_index, port_id, port->GetLatency() );
  246. }
  247. //midi
  248. port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
  249. for ( midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++ )
  250. {
  251. snprintf ( alias, sizeof ( alias ) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, midi_port_index + 1 );
  252. snprintf ( name, sizeof ( name ) - 1, "%s:midi_capture_%d", fClientControl.fName, midi_port_index + 1 );
  253. if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE,
  254. static_cast<JackPortFlags> ( port_flags ), fEngineControl->fBufferSize ) ) == NO_PORT )
  255. {
  256. jack_error ( "driver: cannot register port for %s", name );
  257. return -1;
  258. }
  259. port = fGraphManager->GetPort ( port_id );
  260. //port latency
  261. port->SetLatency ( fEngineControl->fBufferSize );
  262. fMidiCapturePortList[midi_port_index] = port_id;
  263. jack_log ( "JackNetDriver::AllocPorts() fMidiCapturePortList[%d] midi_port_index = %ld fPortLatency = %ld", midi_port_index, port_id, port->GetLatency() );
  264. }
  265. port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
  266. for ( midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++ )
  267. {
  268. snprintf ( alias, sizeof ( alias ) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, midi_port_index + 1 );
  269. snprintf ( name, sizeof ( name ) - 1, "%s:midi_playback_%d", fClientControl.fName, midi_port_index + 1 );
  270. if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE,
  271. static_cast<JackPortFlags> ( port_flags ), fEngineControl->fBufferSize ) ) == NO_PORT )
  272. {
  273. jack_error ( "driver: cannot register port for %s", name );
  274. return -1;
  275. }
  276. port = fGraphManager->GetPort ( port_id );
  277. //port latency
  278. switch ( fParams.fNetworkMode )
  279. {
  280. case 'f' :
  281. port->SetLatency ( ( fEngineControl->fSyncMode ) ? 0 : fEngineControl->fBufferSize );
  282. break;
  283. case 'n' :
  284. port->SetLatency ( fEngineControl->fBufferSize + ( fEngineControl->fSyncMode ) ? 0 : fEngineControl->fBufferSize ) ;
  285. break;
  286. case 's' :
  287. port->SetLatency ( 2 * fEngineControl->fBufferSize + ( fEngineControl->fSyncMode ) ? 0 : fEngineControl->fBufferSize );
  288. break;
  289. }
  290. fMidiPlaybackPortList[midi_port_index] = port_id;
  291. jack_log ( "JackNetDriver::AllocPorts() fMidiPlaybackPortList[%d] midi_port_index = %ld fPortLatency = %ld", midi_port_index, port_id, port->GetLatency() );
  292. }
  293. return 0;
  294. }
  295. int JackNetDriver::FreePorts()
  296. {
  297. jack_log ( "JackNetDriver::FreePorts" );
  298. int audio_port_index;
  299. uint midi_port_index;
  300. for ( audio_port_index = 0; audio_port_index < fCaptureChannels; audio_port_index++ )
  301. fGraphManager->ReleasePort ( fClientControl.fRefNum, fCapturePortList[audio_port_index] );
  302. for ( audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++ )
  303. fGraphManager->ReleasePort ( fClientControl.fRefNum, fPlaybackPortList[audio_port_index] );
  304. for ( midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++ )
  305. fGraphManager->ReleasePort ( fClientControl.fRefNum, fMidiCapturePortList[midi_port_index] );
  306. for ( midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++ )
  307. fGraphManager->ReleasePort ( fClientControl.fRefNum, fMidiPlaybackPortList[midi_port_index] );
  308. return 0;
  309. }
  310. JackMidiBuffer* JackNetDriver::GetMidiInputBuffer ( int port_index )
  311. {
  312. return static_cast<JackMidiBuffer*> ( fGraphManager->GetBuffer ( fMidiCapturePortList[port_index], fEngineControl->fBufferSize ) );
  313. }
  314. JackMidiBuffer* JackNetDriver::GetMidiOutputBuffer ( int port_index )
  315. {
  316. return static_cast<JackMidiBuffer*> ( fGraphManager->GetBuffer ( fMidiPlaybackPortList[port_index], fEngineControl->fBufferSize ) );
  317. }
  318. //transport---------------------------------------------------------------------------
  319. int JackNetDriver::DecodeTransportData()
  320. {
  321. //is there a new timebase master on the net master ?
  322. // - release timebase master only if it's a non-conditional request
  323. // - no change or no request : don't do anything
  324. // - conditional request : don't change anything too, the master will know if this slave is actually the timebase master
  325. int refnum;
  326. bool conditional;
  327. if ( fSendTransportData.fTimebaseMaster == TIMEBASEMASTER )
  328. {
  329. fEngineControl->fTransport.GetTimebaseMaster ( refnum, conditional );
  330. if ( refnum != -1 )
  331. fEngineControl->fTransport.ResetTimebase ( refnum );
  332. jack_info ( "The NetMaster is now the new timebase master." );
  333. }
  334. //is there a tranport state change to handle ?
  335. if ( fSendTransportData.fNewState && ( fSendTransportData.fState != fEngineControl->fTransport.GetState() ) )
  336. {
  337. switch ( fSendTransportData.fState )
  338. {
  339. case JackTransportStopped :
  340. fEngineControl->fTransport.SetCommand ( TransportCommandStop );
  341. jack_info ( "Master stops transport." );
  342. break;
  343. case JackTransportStarting :
  344. fEngineControl->fTransport.RequestNewPos ( &fSendTransportData.fPosition );
  345. fEngineControl->fTransport.SetCommand ( TransportCommandStart );
  346. jack_info ( "Master starts transport." );
  347. break;
  348. case JackTransportRolling :
  349. fEngineControl->fTransport.SetState ( JackTransportRolling );
  350. jack_info ( "Master is rolling." );
  351. break;
  352. }
  353. }
  354. return 0;
  355. }
  356. int JackNetDriver::EncodeTransportData()
  357. {
  358. //is there a timebase master change ?
  359. int refnum;
  360. bool conditional;
  361. fEngineControl->fTransport.GetTimebaseMaster ( refnum, conditional );
  362. if ( refnum != fLastTimebaseMaster )
  363. {
  364. //timebase master has released its function
  365. if ( refnum == -1 )
  366. {
  367. fReturnTransportData.fTimebaseMaster = RELEASE_TIMEBASEMASTER;
  368. jack_info ( "Sending a timebase master release request." );
  369. }
  370. //there is a new timebase master
  371. else
  372. {
  373. fReturnTransportData.fTimebaseMaster = ( conditional ) ? CONDITIONAL_TIMEBASEMASTER : TIMEBASEMASTER;
  374. jack_info ( "Sending a %s timebase master request.", ( conditional ) ? "conditional" : "non-conditional" );
  375. }
  376. fLastTimebaseMaster = refnum;
  377. }
  378. else
  379. fReturnTransportData.fTimebaseMaster = NO_CHANGE;
  380. //update transport state and position
  381. fReturnTransportData.fState = fEngineControl->fTransport.Query ( &fReturnTransportData.fPosition );
  382. //is it a new state (that the master need to know...) ?
  383. fReturnTransportData.fNewState = ( ( fReturnTransportData.fState != fLastTransportState ) &&
  384. ( fReturnTransportData.fState != fSendTransportData.fState ) );
  385. if ( fReturnTransportData.fNewState )
  386. jack_info ( "Sending '%s'.", GetTransportState ( fReturnTransportData.fState ) );
  387. fLastTransportState = fReturnTransportData.fState;
  388. return 0;
  389. }
  390. //network sync------------------------------------------------------------------------
  391. int JackNetDriver::DecodeSyncPacket()
  392. {
  393. //this method contains every step of sync packet informations decoding process
  394. //first : transport
  395. if ( fParams.fTransportSync )
  396. {
  397. //copy received transport data to transport data structure
  398. memcpy ( &fSendTransportData, fRxData, sizeof ( net_transport_data_t ) );
  399. if ( DecodeTransportData() < 0 )
  400. return -1;
  401. }
  402. //then others
  403. //...
  404. return 0;
  405. }
  406. int JackNetDriver::EncodeSyncPacket()
  407. {
  408. //this method contains every step of sync packet informations coding
  409. //first of all, reset sync packet
  410. memset ( fTxData, 0, fPayloadSize );
  411. //then first step : transport
  412. if ( fParams.fTransportSync )
  413. {
  414. if ( EncodeTransportData() < 0 )
  415. return -1;
  416. //copy to TxBuffer
  417. memcpy ( fTxData, &fReturnTransportData, sizeof ( net_transport_data_t ) );
  418. }
  419. //then others
  420. //...
  421. return 0;
  422. }
  423. //driver processes--------------------------------------------------------------------
  424. int JackNetDriver::Read()
  425. {
  426. uint midi_port_index;
  427. uint audio_port_index;
  428. //buffers
  429. for ( midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++ )
  430. fNetMidiCaptureBuffer->SetBuffer ( midi_port_index, GetMidiInputBuffer ( midi_port_index ) );
  431. for ( audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++ )
  432. fNetAudioCaptureBuffer->SetBuffer ( audio_port_index, GetInputBuffer ( audio_port_index ) );
  433. #ifdef JACK_MONITOR
  434. fNetTimeMon->New();
  435. #endif
  436. //receive sync (launch the cycle)
  437. if ( SyncRecv() == SOCKET_ERROR )
  438. return 0;
  439. //take the time at the beginning of the cycle
  440. JackDriver::CycleTakeBeginTime();
  441. //decode sync
  442. //if there is an error, don't return -1, it will skip Write() and the network error probably won't be identified
  443. if ( DecodeSyncPacket() < 0 )
  444. return 0;
  445. #ifdef JACK_MONITOR
  446. fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - JackDriver::fBeginDateUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f );
  447. #endif
  448. //audio, midi or sync if driver is late
  449. if ( DataRecv() == SOCKET_ERROR )
  450. return SOCKET_ERROR;
  451. #ifdef JACK_MONITOR
  452. fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - JackDriver::fBeginDateUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f );
  453. #endif
  454. return 0;
  455. }
  456. int JackNetDriver::Write()
  457. {
  458. uint midi_port_index;
  459. int audio_port_index;
  460. //buffers
  461. for ( midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++ )
  462. fNetMidiPlaybackBuffer->SetBuffer ( midi_port_index, GetMidiOutputBuffer ( midi_port_index ) );
  463. for ( audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++ )
  464. fNetAudioPlaybackBuffer->SetBuffer ( audio_port_index, GetOutputBuffer ( audio_port_index ) );
  465. #ifdef JACK_MONITOR
  466. fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - JackDriver::fBeginDateUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f );
  467. #endif
  468. //sync
  469. if ( EncodeSyncPacket() < 0 )
  470. return 0;
  471. //send sync
  472. if ( SyncSend() == SOCKET_ERROR )
  473. return SOCKET_ERROR;
  474. #ifdef JACK_MONITOR
  475. fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - JackDriver::fBeginDateUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f );
  476. #endif
  477. //send data
  478. if ( DataSend() == SOCKET_ERROR )
  479. return SOCKET_ERROR;
  480. #ifdef JACK_MONITOR
  481. fNetTimeMon->AddLast ( ( ( float ) ( GetMicroSeconds() - JackDriver::fBeginDateUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f );
  482. #endif
  483. return 0;
  484. }
  485. //driver loader-----------------------------------------------------------------------
  486. #ifdef __cplusplus
  487. extern "C"
  488. {
  489. #endif
  490. SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor ()
  491. {
  492. jack_driver_desc_t* desc = ( jack_driver_desc_t* ) calloc ( 1, sizeof ( jack_driver_desc_t ) );
  493. strcpy(desc->name, "net"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1
  494. strcpy(desc->desc, "netjack slave backend component"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1
  495. desc->nparams = 10;
  496. desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) );
  497. int i = 0;
  498. strcpy ( desc->params[i].name, "multicast_ip" );
  499. desc->params[i].character = 'a';
  500. desc->params[i].type = JackDriverParamString;
  501. strcpy ( desc->params[i].value.str, DEFAULT_MULTICAST_IP );
  502. strcpy ( desc->params[i].short_desc, "Multicast Address" );
  503. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  504. i++;
  505. strcpy ( desc->params[i].name, "udp_net_port" );
  506. desc->params[i].character = 'p';
  507. desc->params[i].type = JackDriverParamInt;
  508. desc->params[i].value.i = 19000;
  509. strcpy ( desc->params[i].short_desc, "UDP port" );
  510. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  511. i++;
  512. strcpy ( desc->params[i].name, "mtu" );
  513. desc->params[i].character = 'M';
  514. desc->params[i].type = JackDriverParamInt;
  515. desc->params[i].value.i = 1500;
  516. strcpy ( desc->params[i].short_desc, "MTU to the master" );
  517. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  518. i++;
  519. strcpy ( desc->params[i].name, "input_ports" );
  520. desc->params[i].character = 'C';
  521. desc->params[i].type = JackDriverParamInt;
  522. desc->params[i].value.i = 2;
  523. strcpy ( desc->params[i].short_desc, "Number of audio input ports" );
  524. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  525. i++;
  526. strcpy ( desc->params[i].name, "output_ports" );
  527. desc->params[i].character = 'P';
  528. desc->params[i].type = JackDriverParamInt;
  529. desc->params[i].value.i = 2;
  530. strcpy ( desc->params[i].short_desc, "Number of audio output ports" );
  531. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  532. i++;
  533. strcpy ( desc->params[i].name, "midi_in_ports" );
  534. desc->params[i].character = 'i';
  535. desc->params[i].type = JackDriverParamInt;
  536. desc->params[i].value.i = 0;
  537. strcpy ( desc->params[i].short_desc, "Number of midi input ports" );
  538. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  539. i++;
  540. strcpy ( desc->params[i].name, "midi_out_ports" );
  541. desc->params[i].character = 'o';
  542. desc->params[i].type = JackDriverParamUInt;
  543. desc->params[i].value.i = 0;
  544. strcpy ( desc->params[i].short_desc, "Number of midi output ports" );
  545. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  546. i++;
  547. strcpy ( desc->params[i].name, "client_name" );
  548. desc->params[i].character = 'n';
  549. desc->params[i].type = JackDriverParamString;
  550. strcpy ( desc->params[i].value.str, "'hostname'" );
  551. strcpy ( desc->params[i].short_desc, "Name of the jack client" );
  552. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  553. i++;
  554. strcpy ( desc->params[i].name, "transport_sync" );
  555. desc->params[i].character = 't';
  556. desc->params[i].type = JackDriverParamUInt;
  557. desc->params[i].value.ui = 1U;
  558. strcpy ( desc->params[i].short_desc, "Sync transport with master's" );
  559. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  560. i++;
  561. strcpy ( desc->params[i].name, "mode" );
  562. desc->params[i].character = 'm';
  563. desc->params[i].type = JackDriverParamString;
  564. strcpy ( desc->params[i].value.str, "normal" );
  565. strcpy ( desc->params[i].short_desc, "Slow, Normal or Fast mode." );
  566. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  567. return desc;
  568. }
  569. SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize ( Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params )
  570. {
  571. char multicast_ip[16];
  572. strcpy ( multicast_ip, DEFAULT_MULTICAST_IP );
  573. char net_name[JACK_CLIENT_NAME_SIZE];
  574. int udp_port = DEFAULT_PORT;
  575. int mtu = 1500;
  576. uint transport_sync = 1;
  577. jack_nframes_t period_size = 128;
  578. jack_nframes_t sample_rate = 48000;
  579. int audio_capture_ports = 2;
  580. int audio_playback_ports = 2;
  581. int midi_input_ports = 0;
  582. int midi_output_ports = 0;
  583. bool monitor = false;
  584. char network_mode = 'n';
  585. const JSList* node;
  586. const jack_driver_param_t* param;
  587. net_name[0] = 0;
  588. for ( node = params; node; node = jack_slist_next ( node ) )
  589. {
  590. param = ( const jack_driver_param_t* ) node->data;
  591. switch ( param->character )
  592. {
  593. case 'a' :
  594. strncpy ( multicast_ip, param->value.str, 15 );
  595. break;
  596. case 'p':
  597. udp_port = param->value.ui;
  598. break;
  599. case 'M':
  600. mtu = param->value.i;
  601. break;
  602. case 'C':
  603. audio_capture_ports = param->value.i;
  604. break;
  605. case 'P':
  606. audio_playback_ports = param->value.i;
  607. break;
  608. case 'i':
  609. midi_input_ports = param->value.i;
  610. break;
  611. case 'o':
  612. midi_output_ports = param->value.i;
  613. break;
  614. case 'n' :
  615. strncpy ( net_name, param->value.str, JACK_CLIENT_NAME_SIZE );
  616. break;
  617. case 't' :
  618. transport_sync = param->value.ui;
  619. break;
  620. case 'm' :
  621. if ( strcmp ( param->value.str, "normal" ) == 0 )
  622. network_mode = 'n';
  623. else if ( strcmp ( param->value.str, "slow" ) == 0 )
  624. network_mode = 's';
  625. else if ( strcmp ( param->value.str, "fast" ) == 0 )
  626. network_mode = 'f';
  627. else
  628. jack_error ( "Unknown network mode, using 'normal' mode." );
  629. break;
  630. }
  631. }
  632. try {
  633. Jack::JackDriverClientInterface* driver =
  634. new Jack::JackWaitThreadedDriver(
  635. new Jack::JackNetDriver("system", "net_pcm", engine, table, multicast_ip, udp_port, mtu,
  636. midi_input_ports, midi_output_ports, net_name, transport_sync, network_mode));
  637. if (driver->Open (period_size, sample_rate, 1, 1, audio_capture_ports, audio_playback_ports,
  638. monitor, "from_master_", "to_master_", 0, 0) == 0) {
  639. return driver;
  640. } else {
  641. delete driver;
  642. return NULL;
  643. }
  644. } catch (...) {
  645. return NULL;
  646. }
  647. }
  648. #ifdef __cplusplus
  649. }
  650. #endif
  651. }