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.

573 lines
20KB

  1. /*
  2. Copyright (C) 2008 Romain Moret at Grame
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. */
  15. #include "JackNetAdapter.h"
  16. #include "JackException.h"
  17. #include "JackServer.h"
  18. #include "JackEngineControl.h"
  19. namespace Jack
  20. {
  21. JackNetAdapter::JackNetAdapter ( jack_client_t* jack_client, jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params )
  22. : JackAudioAdapterInterface ( buffer_size, sample_rate ), JackNetSlaveInterface(), fThread ( this )
  23. {
  24. jack_log ( "JackNetAdapter::JackNetAdapter" );
  25. if ( SocketAPIInit() < 0 )
  26. jack_error ( "Can't init Socket API, exiting..." );
  27. //global parametering
  28. //we can't call JackNetSlaveInterface constructor with some parameters before
  29. //because we don't have full parametering right now
  30. //parameters will be parsed from the param list, and then JackNetSlaveInterface will be filled with proper values
  31. fMulticastIP = new char[16];
  32. strcpy ( fMulticastIP, DEFAULT_MULTICAST_IP );
  33. uint port = DEFAULT_PORT;
  34. GetHostName ( fParams.fName, JACK_CLIENT_NAME_SIZE );
  35. fSocket.GetName ( fParams.fSlaveNetName );
  36. fParams.fMtu = 1500;
  37. fParams.fTransportSync = 0;
  38. fParams.fSendAudioChannels = 2;
  39. fParams.fReturnAudioChannels = 2;
  40. fParams.fSendMidiChannels = 0;
  41. fParams.fReturnMidiChannels = 0;
  42. fParams.fSampleRate = sample_rate;
  43. fParams.fPeriodSize = buffer_size;
  44. fParams.fSlaveSyncMode = 1;
  45. fParams.fNetworkMode = 'n';
  46. fJackClient = jack_client;
  47. //options parsing
  48. const JSList* node;
  49. const jack_driver_param_t* param;
  50. for ( node = params; node; node = jack_slist_next ( node ) )
  51. {
  52. param = ( const jack_driver_param_t* ) node->data;
  53. switch ( param->character )
  54. {
  55. case 'a' :
  56. if ( strlen ( param->value.str ) < 16 )
  57. strcpy ( fMulticastIP, param->value.str );
  58. else
  59. jack_error ( "Can't use multicast address %s, using default %s", param->value.ui, DEFAULT_MULTICAST_IP );
  60. break;
  61. case 'p' :
  62. fSocket.SetPort ( param->value.ui );
  63. break;
  64. case 'M' :
  65. fParams.fMtu = param->value.i;
  66. break;
  67. case 'C' :
  68. fParams.fSendAudioChannels = param->value.i;
  69. break;
  70. case 'P' :
  71. fParams.fReturnAudioChannels = param->value.i;
  72. break;
  73. case 'n' :
  74. strncpy ( fParams.fName, param->value.str, JACK_CLIENT_NAME_SIZE );
  75. break;
  76. case 't' :
  77. //fParams.fTransportSync = param->value.ui;
  78. break;
  79. case 'm' :
  80. if ( strcmp ( param->value.str, "normal" ) == 0 )
  81. fParams.fNetworkMode = 'n';
  82. else if ( strcmp ( param->value.str, "slow" ) == 0 )
  83. fParams.fNetworkMode = 's';
  84. else if ( strcmp ( param->value.str, "fast" ) == 0 )
  85. fParams.fNetworkMode = 'f';
  86. else
  87. jack_error ( "Unknown network mode, using 'normal' mode." );
  88. break;
  89. case 'S' :
  90. fParams.fSlaveSyncMode = 1;
  91. break;
  92. }
  93. }
  94. //set the socket parameters
  95. fSocket.SetPort ( port );
  96. fSocket.SetAddress ( fMulticastIP, port );
  97. //set the audio adapter interface channel values
  98. SetInputs ( fParams.fSendAudioChannels );
  99. SetOutputs ( fParams.fReturnAudioChannels );
  100. //soft buffers will be allocated later (once network initialization done)
  101. fSoftCaptureBuffer = NULL;
  102. fSoftPlaybackBuffer = NULL;
  103. }
  104. JackNetAdapter::~JackNetAdapter()
  105. {
  106. jack_log ( "JackNetAdapter::~JackNetAdapter" );
  107. int port_index;
  108. if ( fSoftCaptureBuffer )
  109. {
  110. for ( port_index = 0; port_index < fCaptureChannels; port_index++ )
  111. delete[] fSoftCaptureBuffer[port_index];
  112. delete[] fSoftCaptureBuffer;
  113. }
  114. if ( fSoftPlaybackBuffer )
  115. {
  116. for ( port_index = 0; port_index < fPlaybackChannels; port_index++ )
  117. delete[] fSoftPlaybackBuffer[port_index];
  118. delete[] fSoftPlaybackBuffer;
  119. }
  120. }
  121. //open/close--------------------------------------------------------------------------
  122. int JackNetAdapter::Open()
  123. {
  124. jack_log ( "JackNetAdapter::Open" );
  125. jack_info ( "Net adapter started in %s mode %s Master's transport sync.",
  126. ( fParams.fSlaveSyncMode ) ? "sync" : "async", ( fParams.fTransportSync ) ? "with" : "without" );
  127. if ( fThread.StartSync() < 0 )
  128. {
  129. jack_error ( "Cannot start netadapter thread" );
  130. return -1;
  131. }
  132. return 0;
  133. }
  134. int JackNetAdapter::Close()
  135. {
  136. jack_log ( "JackNetAdapter::Close" );
  137. switch ( fThread.GetStatus() )
  138. {
  139. // Kill the thread in Init phase
  140. case JackThread::kStarting:
  141. case JackThread::kIniting:
  142. if ( fThread.Kill() < 0 )
  143. {
  144. jack_error ( "Cannot kill thread" );
  145. return -1;
  146. }
  147. break;
  148. // Stop when the thread cycle is finished
  149. case JackThread::kRunning:
  150. if ( fThread.Stop() < 0 )
  151. {
  152. jack_error ( "Cannot stop thread" );
  153. return -1;
  154. }
  155. break;
  156. default:
  157. break;
  158. }
  159. fSocket.Close();
  160. return 0;
  161. }
  162. int JackNetAdapter::SetBufferSize ( jack_nframes_t buffer_size )
  163. {
  164. JackAudioAdapterInterface::SetHostBufferSize ( buffer_size );
  165. return 0;
  166. }
  167. //thread------------------------------------------------------------------------------
  168. bool JackNetAdapter::Init()
  169. {
  170. jack_log ( "JackNetAdapter::Init" );
  171. int port_index;
  172. //init network connection
  173. if ( !JackNetSlaveInterface::Init() )
  174. return false;
  175. //then set global parameters
  176. SetParams();
  177. //set buffers
  178. fSoftCaptureBuffer = new sample_t*[fCaptureChannels];
  179. for ( port_index = 0; port_index < fCaptureChannels; port_index++ )
  180. {
  181. fSoftCaptureBuffer[port_index] = new sample_t[fParams.fPeriodSize];
  182. fNetAudioCaptureBuffer->SetBuffer ( port_index, fSoftCaptureBuffer[port_index] );
  183. }
  184. fSoftPlaybackBuffer = new sample_t*[fPlaybackChannels];
  185. for ( port_index = 0; port_index < fCaptureChannels; port_index++ )
  186. {
  187. fSoftPlaybackBuffer[port_index] = new sample_t[fParams.fPeriodSize];
  188. fNetAudioPlaybackBuffer->SetBuffer ( port_index, fSoftPlaybackBuffer[port_index] );
  189. }
  190. //set audio adapter parameters
  191. SetAdaptedBufferSize ( fParams.fPeriodSize );
  192. SetAdaptedSampleRate ( fParams.fSampleRate );
  193. if (fThread.AcquireRealTime ( JackServer::fInstance->GetEngineControl()->fPriority - 1 ) < 0) {
  194. jack_error("AcquireRealTime error");
  195. } else {
  196. set_threaded_log_function();
  197. }
  198. //init done, display parameters
  199. SessionParamsDisplay ( &fParams );
  200. return true;
  201. }
  202. bool JackNetAdapter::Execute()
  203. {
  204. try
  205. {
  206. // Keep running even in case of error
  207. while ( fThread.GetStatus() == JackThread::kRunning )
  208. if ( Process() == SOCKET_ERROR )
  209. return false;
  210. return false;
  211. }
  212. catch ( JackNetException& e )
  213. {
  214. e.PrintMessage();
  215. jack_log ( "NetAdapter is restarted." );
  216. fThread.DropRealTime();
  217. fThread.SetStatus ( JackThread::kIniting );
  218. if ( Init() )
  219. {
  220. fThread.SetStatus ( JackThread::kRunning );
  221. return true;
  222. }
  223. else
  224. return false;
  225. }
  226. }
  227. //transport---------------------------------------------------------------------------
  228. int JackNetAdapter::DecodeTransportData()
  229. {
  230. //TODO : we need here to get the actual timebase master to eventually release it from its duty (see JackNetDriver)
  231. //is there a new transport state ?
  232. if ( fSendTransportData.fNewState && ( fSendTransportData.fState != jack_transport_query ( fJackClient, NULL ) ) )
  233. {
  234. switch ( fSendTransportData.fState )
  235. {
  236. case JackTransportStopped :
  237. jack_transport_stop ( fJackClient );
  238. jack_info ( "NetMaster : transport stops." );
  239. break;
  240. case JackTransportStarting :
  241. jack_transport_reposition ( fJackClient, &fSendTransportData.fPosition );
  242. jack_transport_start ( fJackClient );
  243. jack_info ( "NetMaster : transport starts." );
  244. break;
  245. case JackTransportRolling :
  246. //TODO , we need to :
  247. // - find a way to call TransportEngine->SetNetworkSync()
  248. // - turn the transport state to JackTransportRolling
  249. jack_info ( "NetMaster : transport rolls." );
  250. break;
  251. }
  252. }
  253. return 0;
  254. }
  255. int JackNetAdapter::EncodeTransportData()
  256. {
  257. //is there a timebase master change ?
  258. int refnum = -1;
  259. bool conditional = 0;
  260. //TODO : get the actual timebase master
  261. if ( refnum != fLastTimebaseMaster )
  262. {
  263. //timebase master has released its function
  264. if ( refnum == -1 )
  265. {
  266. fReturnTransportData.fTimebaseMaster = RELEASE_TIMEBASEMASTER;
  267. jack_info ( "Sending a timebase master release request." );
  268. }
  269. //there is a new timebase master
  270. else
  271. {
  272. fReturnTransportData.fTimebaseMaster = ( conditional ) ? CONDITIONAL_TIMEBASEMASTER : TIMEBASEMASTER;
  273. jack_info ( "Sending a %s timebase master request.", ( conditional ) ? "conditional" : "non-conditional" );
  274. }
  275. fLastTimebaseMaster = refnum;
  276. }
  277. else
  278. fReturnTransportData.fTimebaseMaster = NO_CHANGE;
  279. //update transport state and position
  280. fReturnTransportData.fState = jack_transport_query ( fJackClient, &fReturnTransportData.fPosition );
  281. //is it a new state (that the master need to know...) ?
  282. fReturnTransportData.fNewState = ( ( fReturnTransportData.fState != fLastTransportState ) &&
  283. ( fReturnTransportData.fState != fSendTransportData.fState ) );
  284. if ( fReturnTransportData.fNewState )
  285. jack_info ( "Sending transport state '%s'.", GetTransportState ( fReturnTransportData.fState ) );
  286. fLastTransportState = fReturnTransportData.fState;
  287. return 0;
  288. }
  289. //network sync------------------------------------------------------------------------
  290. int JackNetAdapter::DecodeSyncPacket()
  291. {
  292. //this method contains every step of sync packet informations decoding process
  293. //first : transport
  294. if ( fParams.fTransportSync )
  295. {
  296. //copy received transport data to transport data structure
  297. memcpy ( &fSendTransportData, fRxData, sizeof ( net_transport_data_t ) );
  298. if ( DecodeTransportData() < 0 )
  299. return -1;
  300. }
  301. //then others
  302. //...
  303. return 0;
  304. }
  305. int JackNetAdapter::EncodeSyncPacket()
  306. {
  307. //this method contains every step of sync packet informations coding
  308. //first of all, reset sync packet
  309. memset ( fTxData, 0, fPayloadSize );
  310. //then first step : transport
  311. if ( fParams.fTransportSync )
  312. {
  313. if ( EncodeTransportData() < 0 )
  314. return -1;
  315. //copy to TxBuffer
  316. memcpy ( fTxData, &fReturnTransportData, sizeof ( net_transport_data_t ) );
  317. }
  318. //then others
  319. //...
  320. return 0;
  321. }
  322. //read/write operations---------------------------------------------------------------
  323. int JackNetAdapter::Read()
  324. {
  325. //don't return -1 in case of sync recv failure
  326. //we need the process to continue for network error detection
  327. if ( SyncRecv() == SOCKET_ERROR )
  328. return 0;
  329. if ( DecodeSyncPacket() < 0 )
  330. return 0;
  331. return DataRecv();
  332. }
  333. int JackNetAdapter::Write()
  334. {
  335. if ( EncodeSyncPacket() < 0 )
  336. return 0;
  337. if ( SyncSend() == SOCKET_ERROR )
  338. return SOCKET_ERROR;
  339. return DataSend();
  340. }
  341. //process-----------------------------------------------------------------------------
  342. int JackNetAdapter::Process()
  343. {
  344. bool failure = false;
  345. int port_index;
  346. //read data from the network
  347. //in case of fatal network error, stop the process
  348. if ( Read() == SOCKET_ERROR )
  349. return SOCKET_ERROR;
  350. //get the resample factor,
  351. jack_nframes_t time1, time2;
  352. ResampleFactor ( time1, time2 );
  353. //resample input data,
  354. for ( port_index = 0; port_index < fCaptureChannels; port_index++ )
  355. {
  356. fCaptureRingBuffer[port_index]->SetRatio ( time1, time2 );
  357. if ( fCaptureRingBuffer[port_index]->WriteResample ( fSoftCaptureBuffer[port_index], fAdaptedBufferSize ) < fAdaptedBufferSize )
  358. failure = true;
  359. }
  360. //and output data,
  361. for ( port_index = 0; port_index < fPlaybackChannels; port_index++ )
  362. {
  363. fPlaybackRingBuffer[port_index]->SetRatio ( time2, time1 );
  364. if ( fPlaybackRingBuffer[port_index]->ReadResample ( fSoftPlaybackBuffer[port_index], fAdaptedBufferSize ) < fAdaptedBufferSize )
  365. failure = true;
  366. }
  367. //then write data to network
  368. //in case of failure, stop process
  369. if ( Write() == SOCKET_ERROR )
  370. return SOCKET_ERROR;
  371. //if there was any ringbuffer failure during resampling, reset
  372. if ( failure )
  373. {
  374. jack_error ( "JackNetAdapter::Execute ringbuffer failure...reset." );
  375. ResetRingBuffers();
  376. }
  377. return true;
  378. }
  379. } // namespace Jack
  380. //loader------------------------------------------------------------------------------
  381. #ifdef __cplusplus
  382. extern "C"
  383. {
  384. #endif
  385. #include "driver_interface.h"
  386. #include "JackAudioAdapter.h"
  387. using namespace Jack;
  388. EXPORT jack_driver_desc_t* jack_get_descriptor()
  389. {
  390. jack_driver_desc_t* desc = ( jack_driver_desc_t* ) calloc ( 1, sizeof ( jack_driver_desc_t ) );
  391. strcpy ( desc->name, "netadapter" );
  392. desc->nparams = 9;
  393. desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) );
  394. int i = 0;
  395. strcpy ( desc->params[i].name, "multicast_ip" );
  396. desc->params[i].character = 'a';
  397. desc->params[i].type = JackDriverParamString;
  398. strcpy ( desc->params[i].value.str, DEFAULT_MULTICAST_IP );
  399. strcpy ( desc->params[i].short_desc, "Multicast Address" );
  400. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  401. i++;
  402. strcpy ( desc->params[i].name, "udp_net_port" );
  403. desc->params[i].character = 'p';
  404. desc->params[i].type = JackDriverParamInt;
  405. desc->params[i].value.i = 19000;
  406. strcpy ( desc->params[i].short_desc, "UDP port" );
  407. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  408. i++;
  409. strcpy ( desc->params[i].name, "mtu" );
  410. desc->params[i].character = 'M';
  411. desc->params[i].type = JackDriverParamInt;
  412. desc->params[i].value.i = 1500;
  413. strcpy ( desc->params[i].short_desc, "MTU to the master" );
  414. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  415. i++;
  416. strcpy ( desc->params[i].name, "input_ports" );
  417. desc->params[i].character = 'C';
  418. desc->params[i].type = JackDriverParamInt;
  419. desc->params[i].value.i = 2;
  420. strcpy ( desc->params[i].short_desc, "Number of audio input ports" );
  421. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  422. i++;
  423. strcpy ( desc->params[i].name, "output_ports" );
  424. desc->params[i].character = 'P';
  425. desc->params[i].type = JackDriverParamInt;
  426. desc->params[i].value.i = 2;
  427. strcpy ( desc->params[i].short_desc, "Number of audio output ports" );
  428. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  429. i++;
  430. strcpy ( desc->params[i].name, "client_name" );
  431. desc->params[i].character = 'n';
  432. desc->params[i].type = JackDriverParamString;
  433. strcpy ( desc->params[i].value.str, "'hostname'" );
  434. strcpy ( desc->params[i].short_desc, "Name of the jack client" );
  435. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  436. i++;
  437. strcpy ( desc->params[i].name, "transport_sync" );
  438. desc->params[i].character = 't';
  439. desc->params[i].type = JackDriverParamUInt;
  440. desc->params[i].value.ui = 1U;
  441. strcpy ( desc->params[i].short_desc, "Sync transport with master's" );
  442. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  443. i++;
  444. strcpy ( desc->params[i].name, "mode" );
  445. desc->params[i].character = 'm';
  446. desc->params[i].type = JackDriverParamString;
  447. strcpy ( desc->params[i].value.str, "normal" );
  448. strcpy ( desc->params[i].short_desc, "Slow, Normal or Fast mode." );
  449. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  450. i++;
  451. strcpy ( desc->params[i].name, "sync_mode" );
  452. desc->params[i].character = 'S';
  453. desc->params[i].type = JackDriverParamString;
  454. strcpy ( desc->params[i].value.str, "" );
  455. strcpy ( desc->params[i].short_desc, "Sync mode (same as driver's sync mode) ?" );
  456. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  457. return desc;
  458. }
  459. EXPORT int jack_internal_initialize ( jack_client_t* jack_client, const JSList* params )
  460. {
  461. jack_log ( "Loading netadapter" );
  462. Jack::JackAudioAdapter* adapter;
  463. jack_nframes_t buffer_size = jack_get_buffer_size ( jack_client );
  464. jack_nframes_t sample_rate = jack_get_sample_rate ( jack_client );
  465. adapter = new Jack::JackAudioAdapter ( jack_client, new Jack::JackNetAdapter ( jack_client, buffer_size, sample_rate, params ) );
  466. assert ( adapter );
  467. if ( adapter->Open() == 0 )
  468. return 0;
  469. else
  470. {
  471. delete adapter;
  472. return 1;
  473. }
  474. }
  475. EXPORT int jack_initialize ( jack_client_t* jack_client, const char* load_init )
  476. {
  477. JSList* params = NULL;
  478. jack_driver_desc_t *desc = jack_get_descriptor();
  479. JackArgParser parser(load_init);
  480. if (parser.GetArgc() > 0)
  481. parser.ParseParams (desc, &params);
  482. int res = jack_internal_initialize(jack_client, params);
  483. parser.FreeParams(params);
  484. return res;
  485. }
  486. EXPORT void jack_finish ( void* arg )
  487. {
  488. Jack::JackAudioAdapter* adapter = static_cast<Jack::JackAudioAdapter*> ( arg );
  489. if (adapter) {
  490. jack_log ( "Unloading netadapter" );
  491. adapter->Close();
  492. delete adapter;
  493. }
  494. }
  495. #ifdef __cplusplus
  496. }
  497. #endif