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.

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