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.

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