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.

343 lines
13KB

  1. /*
  2. Copyright (C) 2008 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. #if defined(HAVE_CONFIG_H)
  16. #include "config.h"
  17. #endif
  18. #include "JackPortAudioAdapter.h"
  19. #include "JackError.h"
  20. namespace Jack
  21. {
  22. int JackPortAudioAdapter::Render ( const void* inputBuffer,
  23. void* outputBuffer,
  24. unsigned long framesPerBuffer,
  25. const PaStreamCallbackTimeInfo* timeInfo,
  26. PaStreamCallbackFlags statusFlags,
  27. void* userData)
  28. {
  29. JackPortAudioAdapter* adapter = static_cast<JackPortAudioAdapter*>(userData);
  30. float** paBuffer;
  31. bool failure = false;
  32. jack_time_t time1, time2;
  33. adapter->ResampleFactor ( time1, time2 );
  34. paBuffer = (float**)inputBuffer;
  35. for ( int i = 0; i < adapter->fCaptureChannels; i++ )
  36. {
  37. adapter->fCaptureRingBuffer[i]->SetRatio ( time1, time2 );
  38. if (adapter->fCaptureRingBuffer[i]->WriteResample ( (float*)paBuffer[i], framesPerBuffer ) < framesPerBuffer )
  39. failure = true;
  40. }
  41. paBuffer = (float**)outputBuffer;
  42. for ( int i = 0; i < adapter->fPlaybackChannels; i++ )
  43. {
  44. adapter->fPlaybackRingBuffer[i]->SetRatio ( time2, time1 );
  45. if ( adapter->fPlaybackRingBuffer[i]->ReadResample ( (float*)paBuffer[i], framesPerBuffer ) < framesPerBuffer )
  46. failure = true;
  47. }
  48. #ifdef JACK_MONITOR
  49. adapter->fTable.Write ( time1, time2, double(time1) / double(time2), double(time2) / double(time1),
  50. adapter->fCaptureRingBuffer[0]->ReadSpace(), adapter->fPlaybackRingBuffer[0]->WriteSpace() );
  51. #endif
  52. // Reset all ringbuffers in case of failure
  53. if ( failure )
  54. {
  55. jack_error ( "JackPortAudioAdapter::Render ringbuffer failure... reset" );
  56. adapter->ResetRingBuffers();
  57. }
  58. return paContinue;
  59. }
  60. JackPortAudioAdapter::JackPortAudioAdapter ( jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params )
  61. : JackAudioAdapterInterface ( buffer_size, sample_rate )
  62. {
  63. jack_log ( "JackPortAudioAdapter::JackPortAudioAdapter buffer_size = %d, sample_rate = %d", buffer_size, sample_rate );
  64. const JSList* node;
  65. const jack_driver_param_t* param;
  66. int in_max = 0;
  67. int out_max = 0;
  68. fInputDevice = Pa_GetDefaultInputDevice();
  69. fOutputDevice = Pa_GetDefaultOutputDevice();
  70. for (node = params; node; node = jack_slist_next(node))
  71. {
  72. param = (const jack_driver_param_t*) node->data;
  73. switch (param->character)
  74. {
  75. case 'i' :
  76. fCaptureChannels = param->value.ui;
  77. break;
  78. case 'o' :
  79. fPlaybackChannels = param->value.ui;
  80. break;
  81. case 'C' :
  82. if ( fPaDevices.GetInputDeviceFromName(param->value.str, fInputDevice, in_max) < 0 )
  83. {
  84. jack_error ( "Can't use %s, taking default input device", param->value.str );
  85. fInputDevice = Pa_GetDefaultInputDevice();
  86. }
  87. break;
  88. case 'P' :
  89. if ( fPaDevices.GetOutputDeviceFromName(param->value.str, fOutputDevice, out_max) < 0 )
  90. {
  91. jack_error ( "Can't use %s, taking default output device", param->value.str );
  92. fOutputDevice = Pa_GetDefaultOutputDevice();
  93. }
  94. break;
  95. case 'r' :
  96. SetAdaptedSampleRate ( param->value.ui );
  97. break;
  98. case 'p' :
  99. SetAdaptedBufferSize ( param->value.ui );
  100. break;
  101. case 'd' :
  102. if ( fPaDevices.GetInputDeviceFromName ( param->value.str, fInputDevice, in_max ) < 0 )
  103. jack_error ( "Can't use %s, taking default input device", param->value.str );
  104. if ( fPaDevices.GetOutputDeviceFromName ( param->value.str, fOutputDevice, out_max ) < 0 )
  105. jack_error ( "Can't use %s, taking default output device", param->value.str );
  106. break;
  107. case 'l' :
  108. fPaDevices.DisplayDevicesNames();
  109. break;
  110. case 'q':
  111. fQuality = param->value.ui;
  112. break;
  113. case 'g':
  114. fRingbufferSize = param->value.ui;
  115. break;
  116. }
  117. }
  118. //max channels
  119. if ( in_max == 0 )
  120. in_max = fPaDevices.GetDeviceInfo ( fInputDevice )->maxInputChannels;
  121. if ( out_max == 0 )
  122. out_max = fPaDevices.GetDeviceInfo ( fOutputDevice )->maxOutputChannels;
  123. //effective channels
  124. if ( ( fCaptureChannels == 0 ) || ( fCaptureChannels > in_max ) )
  125. fCaptureChannels = in_max;
  126. if ( ( fPlaybackChannels == 0 ) || ( fPlaybackChannels > out_max ) )
  127. fPlaybackChannels = out_max;
  128. //set adapter interface channels
  129. SetInputs ( fCaptureChannels );
  130. SetOutputs ( fPlaybackChannels );
  131. }
  132. int JackPortAudioAdapter::Open()
  133. {
  134. PaError err;
  135. PaStreamParameters inputParameters;
  136. PaStreamParameters outputParameters;
  137. if ( JackAudioAdapterInterface::Open() < 0 )
  138. return -1;
  139. jack_log("JackPortAudioAdapter::Open fInputDevice = %d DeviceName %s", fInputDevice, fPaDevices.GetFullName(fInputDevice).c_str());
  140. jack_log("JackPortAudioAdapter::Open fOutputDevice = %d DeviceName %s", fOutputDevice, fPaDevices.GetFullName(fOutputDevice).c_str());
  141. jack_log("JackPortAudioAdapter::Open fAdaptedBufferSize = %u fAdaptedSampleRate %u", fAdaptedBufferSize, fAdaptedSampleRate);
  142. inputParameters.device = fInputDevice;
  143. inputParameters.channelCount = fCaptureChannels;
  144. inputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output
  145. inputParameters.suggestedLatency = ( fInputDevice != paNoDevice ) // TODO: check how to setup this on ASIO
  146. ? fPaDevices.GetDeviceInfo(fInputDevice)->defaultLowInputLatency
  147. : 0;
  148. inputParameters.hostApiSpecificStreamInfo = NULL;
  149. outputParameters.device = fOutputDevice;
  150. outputParameters.channelCount = fPlaybackChannels;
  151. outputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output
  152. outputParameters.suggestedLatency = ( fOutputDevice != paNoDevice ) // TODO: check how to setup this on ASIO
  153. ? fPaDevices.GetDeviceInfo(fOutputDevice)->defaultLowOutputLatency
  154. : 0;
  155. outputParameters.hostApiSpecificStreamInfo = NULL;
  156. err = Pa_OpenStream( &fStream,
  157. ( fInputDevice == paNoDevice ) ? 0 : &inputParameters,
  158. ( fOutputDevice == paNoDevice ) ? 0 : &outputParameters,
  159. fAdaptedSampleRate,
  160. fAdaptedBufferSize,
  161. paNoFlag, // Clipping is on...
  162. Render,
  163. this );
  164. if ( err != paNoError )
  165. {
  166. jack_error ( "Pa_OpenStream error = %s", Pa_GetErrorText ( err ) );
  167. return -1;
  168. }
  169. err = Pa_StartStream ( fStream );
  170. if ( err != paNoError )
  171. {
  172. jack_error ( "Pa_StartStream error = %s", Pa_GetErrorText ( err ) );
  173. return -1;
  174. }
  175. jack_log ( "JackPortAudioAdapter::Open OK" );
  176. return 0;
  177. }
  178. int JackPortAudioAdapter::Close()
  179. {
  180. #ifdef JACK_MONITOR
  181. fTable.Save();
  182. #endif
  183. jack_log ( "JackPortAudioAdapter::Close" );
  184. Pa_StopStream ( fStream );
  185. jack_log ( "JackPortAudioAdapter:: Pa_StopStream" );
  186. Pa_CloseStream ( fStream );
  187. jack_log ( "JackPortAudioAdapter:: Pa_CloseStream" );
  188. return JackAudioAdapterInterface::Close();
  189. }
  190. int JackPortAudioAdapter::SetSampleRate ( jack_nframes_t sample_rate )
  191. {
  192. JackAudioAdapterInterface::SetHostSampleRate ( sample_rate );
  193. Close();
  194. return Open();
  195. }
  196. int JackPortAudioAdapter::SetBufferSize ( jack_nframes_t buffer_size )
  197. {
  198. JackAudioAdapterInterface::SetHostBufferSize ( buffer_size );
  199. Close();
  200. return Open();
  201. }
  202. } // namespace
  203. #ifdef __cplusplus
  204. extern "C"
  205. {
  206. #endif
  207. SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor()
  208. {
  209. jack_driver_desc_t *desc;
  210. unsigned int i;
  211. desc = (jack_driver_desc_t*)calloc(1, sizeof(jack_driver_desc_t));
  212. strcpy(desc->name, "audioadapter"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1
  213. strcpy(desc->desc, "netjack audio <==> net backend adapter"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1
  214. desc->nparams = 10;
  215. desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t));
  216. i = 0;
  217. strcpy(desc->params[i].name, "inchannels");
  218. desc->params[i].character = 'i';
  219. desc->params[i].type = JackDriverParamInt;
  220. desc->params[i].value.ui = 0;
  221. strcpy(desc->params[i].short_desc, "Maximum number of input channels");
  222. strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
  223. i++;
  224. strcpy(desc->params[i].name, "outchannels");
  225. desc->params[i].character = 'o';
  226. desc->params[i].type = JackDriverParamInt;
  227. desc->params[i].value.ui = 0;
  228. strcpy(desc->params[i].short_desc, "Maximum number of output channels");
  229. strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
  230. i++;
  231. strcpy(desc->params[i].name, "capture");
  232. desc->params[i].character = 'C';
  233. desc->params[i].type = JackDriverParamString;
  234. strcpy(desc->params[i].value.str, "default input device");
  235. strcpy(desc->params[i].short_desc, "Provide capture ports. Optionally set PortAudio device name");
  236. strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
  237. i++;
  238. strcpy(desc->params[i].name, "playback");
  239. desc->params[i].character = 'P';
  240. desc->params[i].type = JackDriverParamString;
  241. strcpy(desc->params[i].value.str, "default output device");
  242. strcpy(desc->params[i].short_desc, "Provide playback ports. Optionally set PortAudio device name");
  243. strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
  244. i++;
  245. strcpy(desc->params[i].name, "rate");
  246. desc->params[i].character = 'r';
  247. desc->params[i].type = JackDriverParamUInt;
  248. desc->params[i].value.ui = 44100U;
  249. strcpy(desc->params[i].short_desc, "Sample rate");
  250. strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
  251. i++;
  252. strcpy(desc->params[i].name, "periodsize");
  253. desc->params[i].character = 'p';
  254. desc->params[i].type = JackDriverParamUInt;
  255. desc->params[i].value.ui = 512U;
  256. strcpy(desc->params[i].short_desc, "Period size");
  257. strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
  258. i++;
  259. strcpy(desc->params[i].name, "device");
  260. desc->params[i].character = 'd';
  261. desc->params[i].type = JackDriverParamString;
  262. desc->params[i].value.ui = 128U;
  263. strcpy(desc->params[i].value.str, "default device");
  264. strcpy(desc->params[i].short_desc, "PortAudio device name");
  265. strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
  266. i++;
  267. strcpy(desc->params[i].name, "list-devices");
  268. desc->params[i].character = 'l';
  269. desc->params[i].type = JackDriverParamBool;
  270. desc->params[i].value.i = TRUE;
  271. strcpy(desc->params[i].short_desc, "Display available PortAudio devices");
  272. strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
  273. i++;
  274. strcpy(desc->params[i].name, "quality");
  275. desc->params[i].character = 'q';
  276. desc->params[i].type = JackDriverParamInt;
  277. desc->params[i].value.ui = 0;
  278. strcpy(desc->params[i].short_desc, "Resample algorithm quality (0 - 4)");
  279. strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
  280. i++;
  281. strcpy(desc->params[i].name, "ring-buffer");
  282. desc->params[i].character = 'g';
  283. desc->params[i].type = JackDriverParamInt;
  284. desc->params[i].value.ui = 0;
  285. strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 32768)");
  286. strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
  287. return desc;
  288. }
  289. #ifdef __cplusplus
  290. }
  291. #endif