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.

395 lines
13KB

  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. #define DEFAULT_MULTICAST_IP "225.3.19.154"
  18. #define DEFAULT_PORT 19000
  19. namespace Jack
  20. {
  21. JackNetAdapter::JackNetAdapter ( 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. fMulticastIP = new char[16];
  29. strcpy ( fMulticastIP, DEFAULT_MULTICAST_IP );
  30. uint port = DEFAULT_PORT;
  31. GetHostName ( fParams.fName, JACK_CLIENT_NAME_SIZE );
  32. fSocket.GetName ( fParams.fSlaveNetName );
  33. fParams.fMtu = 1500;
  34. fParams.fTransportSync = 1;
  35. fParams.fSendAudioChannels = 2;
  36. fParams.fReturnAudioChannels = 2;
  37. fParams.fSendMidiChannels = 0;
  38. fParams.fReturnMidiChannels = 0;
  39. fParams.fSampleRate = sample_rate;
  40. fParams.fPeriodSize = buffer_size;
  41. fParams.fSlaveSyncMode = 1;
  42. fParams.fNetworkMode = 'n';
  43. //options parsing
  44. const JSList* node;
  45. const jack_driver_param_t* param;
  46. for ( node = params; node; node = jack_slist_next ( node ) )
  47. {
  48. param = ( const jack_driver_param_t* ) node->data;
  49. switch ( param->character )
  50. {
  51. case 'a' :
  52. if ( strlen ( param->value.str ) < 16 )
  53. strcpy ( fMulticastIP, param->value.str );
  54. else
  55. jack_error ( "Can't use multicast address %s, using default %s", param->value.ui, DEFAULT_MULTICAST_IP );
  56. break;
  57. case 'p' :
  58. fSocket.SetPort ( param->value.ui );
  59. break;
  60. case 'M' :
  61. fParams.fMtu = param->value.i;
  62. break;
  63. case 'C' :
  64. fParams.fSendAudioChannels = param->value.i;
  65. break;
  66. case 'P' :
  67. fParams.fReturnAudioChannels = param->value.i;
  68. break;
  69. case 'n' :
  70. strncpy ( fParams.fName, param->value.str, JACK_CLIENT_NAME_SIZE );
  71. break;
  72. case 't' :
  73. fParams.fTransportSync = param->value.ui;
  74. break;
  75. case 'm' :
  76. if ( strcmp ( param->value.str, "normal" ) == 0 )
  77. fParams.fNetworkMode = 'n';
  78. else if ( strcmp ( param->value.str, "slow" ) == 0 )
  79. fParams.fNetworkMode = 's';
  80. else if ( strcmp ( param->value.str, "fast" ) == 0 )
  81. fParams.fNetworkMode = 'f';
  82. else
  83. jack_error ( "Unknown network mode, using 'normal' mode." );
  84. break;
  85. case 'S' :
  86. fParams.fSlaveSyncMode = 1;
  87. break;
  88. }
  89. }
  90. fSocket.SetPort ( port );
  91. fSocket.SetAddress ( fMulticastIP, port );
  92. SetInputs ( fParams.fSendAudioChannels );
  93. SetOutputs ( fParams.fReturnAudioChannels );
  94. fSoftCaptureBuffer = NULL;
  95. fSoftPlaybackBuffer = NULL;
  96. }
  97. JackNetAdapter::~JackNetAdapter()
  98. {
  99. int port_index;
  100. for ( port_index = 0; port_index < fCaptureChannels; port_index++ )
  101. delete[] fSoftCaptureBuffer[port_index];
  102. delete[] fSoftCaptureBuffer;
  103. for ( port_index = 0; port_index < fPlaybackChannels; port_index++ )
  104. delete[] fSoftPlaybackBuffer[port_index];
  105. delete[] fSoftPlaybackBuffer;
  106. }
  107. int JackNetAdapter::Open()
  108. {
  109. jack_log ( "JackNetAdapter::Open" );
  110. jack_info ( "Net adapter started in %s mode %s Master's transport sync.",
  111. ( fParams.fSlaveSyncMode ) ? "sync" : "async", ( fParams.fTransportSync ) ? "with" : "without" );
  112. fThread.AcquireRealTime ( 85 );
  113. return fThread.StartSync();
  114. }
  115. int JackNetAdapter::Close()
  116. {
  117. fThread.Stop();
  118. fSocket.Close();
  119. return 0;
  120. }
  121. int JackNetAdapter::SetBufferSize ( jack_nframes_t buffer_size )
  122. {
  123. fParams.fPeriodSize = buffer_size;
  124. return 0;
  125. }
  126. bool JackNetAdapter::Init()
  127. {
  128. jack_log ( "JackNetAdapter::Init" );
  129. int port_index;
  130. //init network connection
  131. if ( !JackNetSlaveInterface::Init() )
  132. return false;
  133. //then set global parameters
  134. SetParams();
  135. //set buffers
  136. fSoftCaptureBuffer = new sample_t*[fCaptureChannels];
  137. for ( port_index = 0; port_index < fCaptureChannels; port_index++ )
  138. {
  139. fSoftCaptureBuffer[port_index] = new sample_t[fParams.fPeriodSize];
  140. fNetAudioCaptureBuffer->SetBuffer ( port_index, fSoftCaptureBuffer[port_index] );
  141. }
  142. fSoftPlaybackBuffer = new sample_t*[fPlaybackChannels];
  143. for ( port_index = 0; port_index < fCaptureChannels; port_index++ )
  144. {
  145. fSoftPlaybackBuffer[port_index] = new sample_t[fParams.fPeriodSize];
  146. fNetAudioPlaybackBuffer->SetBuffer ( port_index, fSoftPlaybackBuffer[port_index] );
  147. }
  148. //init done, display parameters
  149. SessionParamsDisplay ( &fParams );
  150. return true;
  151. }
  152. bool JackNetAdapter::Execute()
  153. {
  154. try
  155. {
  156. // Keep running even in case of error
  157. while ( fThread.GetStatus() == JackThread::kRunning )
  158. if ( Process() == SOCKET_ERROR )
  159. return false;
  160. return false;
  161. }
  162. catch ( JackNetException& e )
  163. {
  164. e.PrintMessage();
  165. jack_log ( "NetAdapter is restarted." );
  166. fThread.DropRealTime();
  167. fThread.SetStatus(JackThread::kIniting);
  168. if ( Init() )
  169. {
  170. fThread.SetStatus ( JackThread::kRunning );
  171. return true;
  172. }
  173. else
  174. return false;
  175. }
  176. }
  177. int JackNetAdapter::Process()
  178. {
  179. bool failure = false;
  180. int port_index;
  181. //receive
  182. if ( SyncRecv() == SOCKET_ERROR )
  183. return 0;
  184. if ( DataRecv() == SOCKET_ERROR )
  185. return SOCKET_ERROR;
  186. //resample
  187. jack_nframes_t time1, time2;
  188. ResampleFactor ( time1, time2 );
  189. for ( port_index = 0; port_index < fCaptureChannels; port_index++ )
  190. {
  191. fCaptureRingBuffer[port_index]->SetRatio ( time1, time2 );
  192. if ( fCaptureRingBuffer[port_index]->WriteResample ( fSoftCaptureBuffer[port_index], fBufferSize ) < fBufferSize )
  193. failure = true;
  194. }
  195. for ( port_index = 0; port_index < fPlaybackChannels; port_index++ )
  196. {
  197. fPlaybackRingBuffer[port_index]->SetRatio ( time2, time1 );
  198. if ( fPlaybackRingBuffer[port_index]->ReadResample ( fSoftPlaybackBuffer[port_index], fBufferSize ) < fBufferSize )
  199. failure = true;
  200. }
  201. //send
  202. if ( SyncSend() == SOCKET_ERROR )
  203. return SOCKET_ERROR;
  204. if ( DataSend() == SOCKET_ERROR )
  205. return SOCKET_ERROR;
  206. if ( failure )
  207. {
  208. jack_error ( "JackNetAdapter::Execute ringbuffer failure...reset." );
  209. ResetRingBuffers();
  210. }
  211. return true;
  212. }
  213. } // namespace Jack
  214. #ifdef __cplusplus
  215. extern "C"
  216. {
  217. #endif
  218. #include "driver_interface.h"
  219. #include "JackAudioAdapter.h"
  220. using namespace Jack;
  221. EXPORT jack_driver_desc_t* jack_get_descriptor()
  222. {
  223. jack_driver_desc_t* desc = ( jack_driver_desc_t* ) calloc ( 1, sizeof ( jack_driver_desc_t ) );
  224. strcpy ( desc->name, "net" );
  225. desc->nparams = 9;
  226. desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) );
  227. int i = 0;
  228. strcpy ( desc->params[i].name, "multicast_ip" );
  229. desc->params[i].character = 'a';
  230. desc->params[i].type = JackDriverParamString;
  231. strcpy ( desc->params[i].value.str, DEFAULT_MULTICAST_IP );
  232. strcpy ( desc->params[i].short_desc, "Multicast Address" );
  233. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  234. i++;
  235. strcpy ( desc->params[i].name, "udp_net_port" );
  236. desc->params[i].character = 'p';
  237. desc->params[i].type = JackDriverParamInt;
  238. desc->params[i].value.i = 19000;
  239. strcpy ( desc->params[i].short_desc, "UDP port" );
  240. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  241. i++;
  242. strcpy ( desc->params[i].name, "mtu" );
  243. desc->params[i].character = 'M';
  244. desc->params[i].type = JackDriverParamInt;
  245. desc->params[i].value.i = 1500;
  246. strcpy ( desc->params[i].short_desc, "MTU to the master" );
  247. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  248. i++;
  249. strcpy ( desc->params[i].name, "input_ports" );
  250. desc->params[i].character = 'C';
  251. desc->params[i].type = JackDriverParamInt;
  252. desc->params[i].value.i = 2;
  253. strcpy ( desc->params[i].short_desc, "Number of audio input ports" );
  254. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  255. i++;
  256. strcpy ( desc->params[i].name, "output_ports" );
  257. desc->params[i].character = 'P';
  258. desc->params[i].type = JackDriverParamInt;
  259. desc->params[i].value.i = 2;
  260. strcpy ( desc->params[i].short_desc, "Number of audio output ports" );
  261. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  262. i++;
  263. strcpy ( desc->params[i].name, "client_name" );
  264. desc->params[i].character = 'n';
  265. desc->params[i].type = JackDriverParamString;
  266. strcpy ( desc->params[i].value.str, "'hostname'" );
  267. strcpy ( desc->params[i].short_desc, "Name of the jack client" );
  268. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  269. i++;
  270. strcpy ( desc->params[i].name, "transport_sync" );
  271. desc->params[i].character = 't';
  272. desc->params[i].type = JackDriverParamUInt;
  273. desc->params[i].value.ui = 1U;
  274. strcpy ( desc->params[i].short_desc, "Sync transport with master's" );
  275. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  276. i++;
  277. strcpy ( desc->params[i].name, "mode" );
  278. desc->params[i].character = 'm';
  279. desc->params[i].type = JackDriverParamString;
  280. strcpy ( desc->params[i].value.str, "normal" );
  281. strcpy ( desc->params[i].short_desc, "Slow, Normal or Fast mode." );
  282. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  283. i++;
  284. strcpy ( desc->params[i].name, "sync_mode" );
  285. desc->params[i].character = 'S';
  286. desc->params[i].type = JackDriverParamString;
  287. strcpy ( desc->params[i].value.str, "" );
  288. strcpy ( desc->params[i].short_desc, "Sync mode (same as driver's sync mode) ?" );
  289. strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
  290. return desc;
  291. }
  292. EXPORT int jack_internal_initialize ( jack_client_t* jack_client, const JSList* params )
  293. {
  294. jack_log ( "Loading netadapter" );
  295. Jack::JackAudioAdapter* adapter;
  296. jack_nframes_t buffer_size = jack_get_buffer_size ( jack_client );
  297. jack_nframes_t sample_rate = jack_get_sample_rate ( jack_client );
  298. adapter = new Jack::JackAudioAdapter ( jack_client, new Jack::JackNetAdapter ( buffer_size, sample_rate, params ) );
  299. assert ( adapter );
  300. if ( adapter->Open() == 0 )
  301. return 0;
  302. else
  303. {
  304. delete adapter;
  305. return 1;
  306. }
  307. }
  308. EXPORT int jack_initialize ( jack_client_t* jack_client, const char* load_init )
  309. {
  310. JSList* params = NULL;
  311. jack_driver_desc_t *desc = jack_get_descriptor();
  312. JackArgParser parser ( load_init );
  313. if ( parser.GetArgc() > 0 )
  314. if ( parser.ParseParams ( desc, &params ) != 0 )
  315. jack_error ( "Internal client : JackArgParser::ParseParams error." );
  316. return jack_internal_initialize ( jack_client, params );
  317. }
  318. EXPORT void jack_finish ( void* arg )
  319. {
  320. Jack::JackAudioAdapter* adapter = static_cast<Jack::JackAudioAdapter*> ( arg );
  321. if ( adapter )
  322. {
  323. jack_log ( "Unloading netadapter" );
  324. adapter->Close();
  325. delete adapter;
  326. }
  327. }
  328. #ifdef __cplusplus
  329. }
  330. #endif