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.

584 lines
21KB

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