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.

238 lines
6.9KB

  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. #include "JackAlsaAdapter.h"
  16. namespace Jack
  17. {
  18. JackAlsaAdapter::JackAlsaAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params)
  19. :JackAudioAdapterInterface(buffer_size, sample_rate)
  20. ,fThread(this), fAudioInterface(GetInputs(), GetOutputs(), buffer_size, sample_rate)
  21. {
  22. const JSList* node;
  23. const jack_driver_param_t* param;
  24. fCaptureChannels = 2;
  25. fPlaybackChannels = 2;
  26. for (node = params; node; node = jack_slist_next(node)) {
  27. param = (const jack_driver_param_t*) node->data;
  28. switch (param->character) {
  29. case 'i':
  30. fCaptureChannels = param->value.ui;
  31. break;
  32. case 'o':
  33. fPlaybackChannels = param->value.ui;
  34. break;
  35. case 'C':
  36. break;
  37. case 'P':
  38. break;
  39. case 'D':
  40. break;
  41. case 'n':
  42. fAudioInterface.fPeriod = param->value.ui;
  43. break;
  44. case 'd':
  45. fAudioInterface.fCardName = strdup(param->value.str);
  46. break;
  47. case 'r':
  48. SetAudioSampleRate(param->value.ui);
  49. break;
  50. }
  51. }
  52. }
  53. int JackAlsaAdapter::Open()
  54. {
  55. if (fAudioInterface.open() == 0) {
  56. fAudioInterface.longinfo();
  57. fThread.AcquireRealTime(85);
  58. return fThread.StartSync();
  59. } else {
  60. return -1;
  61. }
  62. }
  63. int JackAlsaAdapter::Close()
  64. {
  65. #ifdef DEBUG
  66. fTable.Save();
  67. #endif
  68. fThread.Stop();
  69. return fAudioInterface.close();
  70. }
  71. bool JackAlsaAdapter::Init()
  72. {
  73. fAudioInterface.write();
  74. fAudioInterface.write();
  75. return true;
  76. }
  77. bool JackAlsaAdapter::Execute()
  78. {
  79. if (fAudioInterface.read() < 0)
  80. return false;
  81. bool failure = false;
  82. jack_nframes_t time1, time2;
  83. ResampleFactor(time1, time2);
  84. for (int i = 0; i < fCaptureChannels; i++) {
  85. fCaptureRingBuffer[i]->SetRatio(time1, time2);
  86. if (fCaptureRingBuffer[i]->WriteResample(fAudioInterface.fInputSoftChannels[i], fBufferSize) < fBufferSize)
  87. failure = true;
  88. }
  89. for (int i = 0; i < fPlaybackChannels; i++) {
  90. fPlaybackRingBuffer[i]->SetRatio(time2, time1);
  91. if (fPlaybackRingBuffer[i]->ReadResample(fAudioInterface.fOutputSoftChannels[i], fBufferSize) < fBufferSize)
  92. failure = true;
  93. }
  94. #ifdef DEBUG
  95. fTable.Write(time1, time2, double(time1) / double(time2), double(time2) / double(time1),
  96. fCaptureRingBuffer[0]->ReadSpace(), fPlaybackRingBuffer[0]->WriteSpace());
  97. #endif
  98. if (fAudioInterface.write() < 0)
  99. return false;
  100. // Reset all ringbuffers in case of failure
  101. if (failure) {
  102. jack_error("JackAlsaAdapter::Execute ringbuffer failure... reset");
  103. ResetRingBuffers();
  104. }
  105. return true;
  106. }
  107. int JackAlsaAdapter::SetBufferSize(jack_nframes_t buffer_size)
  108. {
  109. JackAudioAdapterInterface::SetBufferSize(buffer_size);
  110. Close();
  111. return Open();
  112. }
  113. } // namespace
  114. #ifdef __cplusplus
  115. extern "C"
  116. {
  117. #endif
  118. EXPORT jack_driver_desc_t* jack_get_descriptor()
  119. {
  120. jack_driver_desc_t *desc;
  121. jack_driver_param_desc_t * params;
  122. unsigned int i;
  123. desc = (jack_driver_desc_t*)calloc(1, sizeof(jack_driver_desc_t));
  124. strcpy (desc->name, "alsa-adapter");
  125. desc->nparams = 8;
  126. params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t));
  127. i = 0;
  128. strcpy(params[i].name, "capture");
  129. params[i].character = 'C';
  130. params[i].type = JackDriverParamString;
  131. strcpy (params[i].value.str, "none");
  132. strcpy (params[i].short_desc,
  133. "Provide capture ports. Optionally set device");
  134. strcpy (params[i].long_desc, params[i].short_desc);
  135. i++;
  136. strcpy(params[i].name, "playback");
  137. params[i].character = 'P';
  138. params[i].type = JackDriverParamString;
  139. strcpy(params[i].value.str, "none");
  140. strcpy(params[i].short_desc,
  141. "Provide playback ports. Optionally set device");
  142. strcpy(params[i].long_desc, params[i].short_desc);
  143. i++;
  144. strcpy(params[i].name, "device");
  145. params[i].character = 'd';
  146. params[i].type = JackDriverParamString;
  147. strcpy(params[i].value.str, "hw:0");
  148. strcpy(params[i].short_desc, "ALSA device name");
  149. strcpy(params[i].long_desc, params[i].short_desc);
  150. i++;
  151. strcpy (params[i].name, "rate");
  152. params[i].character = 'r';
  153. params[i].type = JackDriverParamUInt;
  154. params[i].value.ui = 48000U;
  155. strcpy(params[i].short_desc, "Sample rate");
  156. strcpy(params[i].long_desc, params[i].short_desc);
  157. i++;
  158. strcpy(params[i].name, "nperiods");
  159. params[i].character = 'n';
  160. params[i].type = JackDriverParamUInt;
  161. params[i].value.ui = 2U;
  162. strcpy(params[i].short_desc, "Number of periods of playback latency");
  163. strcpy(params[i].long_desc, params[i].short_desc);
  164. i++;
  165. strcpy(params[i].name, "duplex");
  166. params[i].character = 'D';
  167. params[i].type = JackDriverParamBool;
  168. params[i].value.i = 1;
  169. strcpy(params[i].short_desc,
  170. "Provide both capture and playback ports");
  171. strcpy(params[i].long_desc, params[i].short_desc);
  172. i++;
  173. strcpy(params[i].name, "inchannels");
  174. params[i].character = 'i';
  175. params[i].type = JackDriverParamUInt;
  176. params[i].value.i = 0;
  177. strcpy(params[i].short_desc,
  178. "Number of capture channels (defaults to hardware max)");
  179. strcpy(params[i].long_desc, params[i].short_desc);
  180. i++;
  181. strcpy(params[i].name, "outchannels");
  182. params[i].character = 'o';
  183. params[i].type = JackDriverParamUInt;
  184. params[i].value.i = 0;
  185. strcpy(params[i].short_desc,
  186. "Number of playback channels (defaults to hardware max)");
  187. strcpy(params[i].long_desc, params[i].short_desc);
  188. desc->params = params;
  189. return desc;
  190. }
  191. #ifdef __cplusplus
  192. }
  193. #endif