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.

464 lines
18KB

  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. #ifdef __APPLE__
  16. #include <TargetConditionals.h>
  17. #endif
  18. #include "JackAudioAdapter.h"
  19. #ifndef MY_TARGET_OS_IPHONE
  20. #include "JackLibSampleRateResampler.h"
  21. #endif
  22. #include "JackTime.h"
  23. #include "JackError.h"
  24. #include <stdio.h>
  25. namespace Jack
  26. {
  27. #ifdef JACK_MONITOR
  28. void MeasureTable::Write(int time1, int time2, float r1, float r2, int pos1, int pos2)
  29. {
  30. int pos = (++fCount) % TABLE_MAX;
  31. fTable[pos].time1 = time1;
  32. fTable[pos].time2 = time2;
  33. fTable[pos].r1 = r1;
  34. fTable[pos].r2 = r2;
  35. fTable[pos].pos1 = pos1;
  36. fTable[pos].pos2 = pos2;
  37. }
  38. void MeasureTable::Save(unsigned int fHostBufferSize, unsigned int fHostSampleRate, unsigned int fAdaptedSampleRate, unsigned int fAdaptedBufferSize)
  39. {
  40. FILE* file = fopen("JackAudioAdapter.log", "w");
  41. int max = (fCount) % TABLE_MAX - 1;
  42. for (int i = 1; i < max; i++) {
  43. fprintf(file, "%d \t %d \t %d \t %f \t %f \t %d \t %d \n",
  44. fTable[i].delta, fTable[i].time1, fTable[i].time2,
  45. fTable[i].r1, fTable[i].r2, fTable[i].pos1, fTable[i].pos2);
  46. }
  47. fclose(file);
  48. // No used for now
  49. // Adapter timing 1
  50. file = fopen("AdapterTiming1.plot", "w");
  51. fprintf(file, "set multiplot\n");
  52. fprintf(file, "set grid\n");
  53. fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n"
  54. ,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize);
  55. fprintf(file, "set xlabel \"audio cycles\"\n");
  56. fprintf(file, "set ylabel \"frames\"\n");
  57. fprintf(file, "plot ");
  58. fprintf(file, "\"JackAudioAdapter.log\" using 2 title \"Ringbuffer error\" with dots,");
  59. fprintf(file, "\"JackAudioAdapter.log\" using 3 title \"Ringbuffer error with timing correction\" with dots");
  60. fprintf(file, "\n unset multiplot\n");
  61. fprintf(file, "set output 'AdapterTiming1.svg\n");
  62. fprintf(file, "set terminal svg\n");
  63. fprintf(file, "set multiplot\n");
  64. fprintf(file, "set grid\n");
  65. fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n"
  66. ,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize);
  67. fprintf(file, "set xlabel \"audio cycles\"\n");
  68. fprintf(file, "set ylabel \"frames\"\n");
  69. fprintf(file, "plot ");
  70. fprintf(file, "\"JackAudioAdapter.log\" using 2 title \"Consumer interrupt period\" with dots,");
  71. fprintf(file, "\"JackAudioAdapter.log\" using 3 title \"Producer interrupt period\" with dots\n");
  72. fprintf(file, "unset multiplot\n");
  73. fprintf(file, "unset output\n");
  74. fclose(file);
  75. // Adapter timing 2
  76. file = fopen("AdapterTiming2.plot", "w");
  77. fprintf(file, "set multiplot\n");
  78. fprintf(file, "set grid\n");
  79. fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n"
  80. ,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize);
  81. fprintf(file, "set xlabel \"audio cycles\"\n");
  82. fprintf(file, "set ylabel \"resampling ratio\"\n");
  83. fprintf(file, "plot ");
  84. fprintf(file, "\"JackAudioAdapter.log\" using 4 title \"Ratio 1\" with dots,");
  85. fprintf(file, "\"JackAudioAdapter.log\" using 5 title \"Ratio 2\" with dots");
  86. fprintf(file, "\n unset multiplot\n");
  87. fprintf(file, "set output 'AdapterTiming2.svg\n");
  88. fprintf(file, "set terminal svg\n");
  89. fprintf(file, "set multiplot\n");
  90. fprintf(file, "set grid\n");
  91. fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n"
  92. ,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize);
  93. fprintf(file, "set xlabel \"audio cycles\"\n");
  94. fprintf(file, "set ylabel \"resampling ratio\"\n");
  95. fprintf(file, "plot ");
  96. fprintf(file, "\"JackAudioAdapter.log\" using 4 title \"Ratio 1\" with dots,");
  97. fprintf(file, "\"JackAudioAdapter.log\" using 5 title \"Ratio 2\" with dots\n");
  98. fprintf(file, "unset multiplot\n");
  99. fprintf(file, "unset output\n");
  100. fclose(file);
  101. // Adapter timing 3
  102. file = fopen("AdapterTiming3.plot", "w");
  103. fprintf(file, "set multiplot\n");
  104. fprintf(file, "set grid\n");
  105. fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n"
  106. ,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize);
  107. fprintf(file, "set xlabel \"audio cycles\"\n");
  108. fprintf(file, "set ylabel \"frames\"\n");
  109. fprintf(file, "plot ");
  110. fprintf(file, "\"JackAudioAdapter.log\" using 6 title \"Frames position in consumer ringbuffer\" with dots,");
  111. fprintf(file, "\"JackAudioAdapter.log\" using 7 title \"Frames position in producer ringbuffer\" with dots");
  112. fprintf(file, "\n unset multiplot\n");
  113. fprintf(file, "set output 'AdapterTiming3.svg\n");
  114. fprintf(file, "set terminal svg\n");
  115. fprintf(file, "set multiplot\n");
  116. fprintf(file, "set grid\n");
  117. fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n"
  118. ,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize);
  119. fprintf(file, "set xlabel \"audio cycles\"\n");
  120. fprintf(file, "set ylabel \"frames\"\n");
  121. fprintf(file, "plot ");
  122. fprintf(file, "\"JackAudioAdapter.log\" using 6 title \"Frames position in consumer ringbuffer\" with dots,");
  123. fprintf(file, "\"JackAudioAdapter.log\" using 7 title \"Frames position in producer ringbuffer\" with dots\n");
  124. fprintf(file, "unset multiplot\n");
  125. fprintf(file, "unset output\n");
  126. fclose(file);
  127. }
  128. #endif
  129. void JackAudioAdapterInterface::GrowRingBufferSize()
  130. {
  131. fRingbufferCurSize *= 2;
  132. }
  133. void JackAudioAdapterInterface::AdaptRingBufferSize()
  134. {
  135. if (fHostBufferSize > fAdaptedBufferSize) {
  136. fRingbufferCurSize = 4 * fHostBufferSize;
  137. } else {
  138. fRingbufferCurSize = 4 * fAdaptedBufferSize;
  139. }
  140. }
  141. void JackAudioAdapterInterface::ResetRingBuffers()
  142. {
  143. if (fRingbufferCurSize > DEFAULT_RB_SIZE) {
  144. fRingbufferCurSize = DEFAULT_RB_SIZE;
  145. }
  146. for (int i = 0; i < fCaptureChannels; i++) {
  147. fCaptureRingBuffer[i]->Reset(fRingbufferCurSize);
  148. fPIControllerCapture[i]->Reset();
  149. }
  150. for (int i = 0; i < fPlaybackChannels; i++) {
  151. fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize);
  152. fPIControllerPlayback[i]->Reset();
  153. }
  154. }
  155. void JackAudioAdapterInterface::Reset()
  156. {
  157. ResetRingBuffers();
  158. fRunning = false;
  159. }
  160. #ifdef MY_TARGET_OS_IPHONE
  161. void JackAudioAdapterInterface::Create()
  162. {}
  163. #else
  164. void JackAudioAdapterInterface::Create()
  165. {
  166. fCaptureRingBuffer = new JackResampler*[fCaptureChannels];
  167. fPIControllerCapture = new JackPIController*[fCaptureChannels];
  168. fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels];
  169. fPIControllerPlayback = new JackPIController*[fPlaybackChannels];
  170. if (fAdaptative) {
  171. AdaptRingBufferSize();
  172. jack_info("Ringbuffer automatic adaptative mode size = %d frames", fRingbufferCurSize);
  173. } else {
  174. if (fRingbufferCurSize > DEFAULT_RB_SIZE) {
  175. fRingbufferCurSize = DEFAULT_RB_SIZE;
  176. }
  177. jack_info("Fixed ringbuffer size = %d frames", fRingbufferCurSize);
  178. }
  179. if (fResampleRatioPerChannel){
  180. jack_info("Resample ratio tracked independently for each capture and playback channel");
  181. } else {
  182. jack_info("Shared resample ratio tracking for all capture and playback channels");
  183. }
  184. for (int i = 0; i < fCaptureChannels; i++ ) {
  185. fCaptureRingBuffer[i] = new JackLibSampleRateResampler(fQuality);
  186. fCaptureRingBuffer[i]->Reset(fRingbufferCurSize);
  187. fPIControllerCapture[i] = new JackPIController(double(fHostSampleRate) / double(fAdaptedSampleRate));
  188. }
  189. for (int i = 0; i < fPlaybackChannels; i++ ) {
  190. fPlaybackRingBuffer[i] = new JackLibSampleRateResampler(fQuality);
  191. fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize);
  192. fPIControllerPlayback[i] = new JackPIController(double(fHostSampleRate) / double(fAdaptedSampleRate));
  193. }
  194. if (fCaptureChannels > 0) {
  195. jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace());
  196. }
  197. if (fPlaybackChannels > 0) {
  198. jack_log("WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace());
  199. }
  200. }
  201. #endif
  202. void JackAudioAdapterInterface::Destroy()
  203. {
  204. for (int i = 0; i < fCaptureChannels; i++) {
  205. delete(fCaptureRingBuffer[i]);
  206. delete(fPIControllerCapture[i]);
  207. }
  208. for (int i = 0; i < fPlaybackChannels; i++) {
  209. delete (fPlaybackRingBuffer[i]);
  210. delete(fPIControllerPlayback[i]);
  211. }
  212. delete[] fCaptureRingBuffer;
  213. delete [] fPIControllerCapture;
  214. delete[] fPlaybackRingBuffer;
  215. delete [] fPIControllerPlayback;
  216. }
  217. double JackAudioAdapterInterface::GetSharedRatio(int delta_frames)
  218. {
  219. if (0 < fCaptureChannels) {
  220. return fPIControllerCapture[0]->GetRatio(fCaptureRingBuffer[0]->GetReadBalance() - delta_frames);
  221. }
  222. else if (0 < fPlaybackChannels) {
  223. return fPIControllerPlayback[0]->GetRatio(fPlaybackRingBuffer[0]->GetReadBalance() - delta_frames);
  224. }
  225. return 1;
  226. }
  227. int JackAudioAdapterInterface::PushAndPull(float** inputBuffer, float** outputBuffer, unsigned int frames)
  228. {
  229. // Most of the time we can use a shared ratio calculated on a single input or output channel ringbuffer and apply this ratio also to all other channels.
  230. // In some situations we see that there is a drift between the channels coming from or going to the same device.
  231. // On those devices we need to activate the fResampleRatioPerChannel option so that every channel will calculate and keep track of its own resample ratio
  232. // in order to keep his ringbuffer in a good balance which is half used for reading and half used for writing.
  233. // Not using this option when it is needed will result in buffer errors followed by resets for all the buffers.
  234. // cfr. https://github.com/jackaudio/jack2/issues/534
  235. bool failure = false;
  236. fRunning = true;
  237. // Finer estimation of the position in the ringbuffer
  238. int delta_frames = (fPullAndPushTime > 0) ? (int)((float(long(GetMicroSeconds() - fPullAndPushTime)) * float(fAdaptedSampleRate)) / 1000000.f) : 0;
  239. double ratioC[fCaptureChannels];
  240. double ratioP[fPlaybackChannels];
  241. if(!fResampleRatioPerChannel) {
  242. double shared_ratio = GetSharedRatio(delta_frames);
  243. for (int i = 0; i < fCaptureChannels; i++) {
  244. ratioC[i] = shared_ratio;
  245. }
  246. for (int i = 0; i < fPlaybackChannels; i++) {
  247. ratioP[i] = shared_ratio;
  248. }
  249. #ifdef JACK_MONITOR
  250. if (fCaptureRingBuffer && fCaptureRingBuffer[0] != NULL) {
  251. fTable.Write(fCaptureRingBuffer[0]->GetReadBalance(), fCaptureRingBuffer[0]->GetReadBalance() - delta_frames, shared_ratio, 1/shared_ratio, fCaptureRingBuffer[0]->ReadSpace(), fCaptureRingBuffer[0]->ReadSpace());
  252. }
  253. #endif // JACK_MONITOR
  254. }
  255. else {
  256. for (int i = 0; i < fCaptureChannels; i++) {
  257. ratioC[i] = fPIControllerCapture[i]->GetRatio(fCaptureRingBuffer[i]->GetReadBalance() - delta_frames);
  258. }
  259. for (int i = 0; i < fPlaybackChannels; i++) {
  260. ratioP[i] = fPIControllerPlayback[i]->GetRatio(fPlaybackRingBuffer[i]->GetWriteBalance() + delta_frames);
  261. }
  262. #ifdef JACK_MONITOR
  263. if (fCaptureRingBuffer && fCaptureRingBuffer[0] != NULL) {
  264. fTable.Write(fCaptureRingBuffer[0]->GetReadBalance(), fCaptureRingBuffer[0]->GetReadBalance() - delta_frames, ratioC[0], 1/ratioC[0], fCaptureRingBuffer[0]->ReadSpace(), fCaptureRingBuffer[0]->ReadSpace());
  265. }
  266. #endif // JACK_MONITOR
  267. }
  268. // Push/pull from ringbuffer
  269. for (int i = 0; i < fCaptureChannels; i++) {
  270. fCaptureRingBuffer[i]->SetRatio(ratioC[i]);
  271. if (inputBuffer[i]) {
  272. if (fCaptureRingBuffer[i]->WriteResample(inputBuffer[i], frames) < frames) {
  273. failure = true;
  274. }
  275. }
  276. }
  277. for (int i = 0; i < fPlaybackChannels; i++) {
  278. fPlaybackRingBuffer[i]->SetRatio(1 / ratioP[i]);
  279. if (outputBuffer[i]) {
  280. if (fPlaybackRingBuffer[i]->ReadResample(outputBuffer[i], frames) < frames) {
  281. failure = true;
  282. }
  283. }
  284. }
  285. // Reset all ringbuffers in case of failure
  286. if (failure) {
  287. jack_error("JackAudioAdapterInterface::PushAndPull ringbuffer failure... reset");
  288. if (fAdaptative) {
  289. GrowRingBufferSize();
  290. jack_info("Ringbuffer size = %d frames", fRingbufferCurSize);
  291. }
  292. ResetRingBuffers();
  293. return -1;
  294. } else {
  295. return 0;
  296. }
  297. }
  298. int JackAudioAdapterInterface::PullAndPush(float** inputBuffer, float** outputBuffer, unsigned int frames)
  299. {
  300. fPullAndPushTime = GetMicroSeconds();
  301. if (!fRunning) {
  302. return 0;
  303. }
  304. int res = 0;
  305. // Push/pull from ringbuffer
  306. for (int i = 0; i < fCaptureChannels; i++) {
  307. if (inputBuffer[i]) {
  308. if (fCaptureRingBuffer[i]->Read(inputBuffer[i], frames) < frames) {
  309. res = -1;
  310. }
  311. }
  312. }
  313. for (int i = 0; i < fPlaybackChannels; i++) {
  314. if (outputBuffer[i]) {
  315. if (fPlaybackRingBuffer[i]->Write(outputBuffer[i], frames) < frames) {
  316. res = -1;
  317. }
  318. }
  319. }
  320. return res;
  321. }
  322. int JackAudioAdapterInterface::SetHostBufferSize(jack_nframes_t buffer_size)
  323. {
  324. fHostBufferSize = buffer_size;
  325. if (fAdaptative) {
  326. AdaptRingBufferSize();
  327. }
  328. return 0;
  329. }
  330. int JackAudioAdapterInterface::SetAdaptedBufferSize(jack_nframes_t buffer_size)
  331. {
  332. fAdaptedBufferSize = buffer_size;
  333. if (fAdaptative) {
  334. AdaptRingBufferSize();
  335. }
  336. return 0;
  337. }
  338. int JackAudioAdapterInterface::SetBufferSize(jack_nframes_t buffer_size)
  339. {
  340. SetHostBufferSize(buffer_size);
  341. SetAdaptedBufferSize(buffer_size);
  342. return 0;
  343. }
  344. int JackAudioAdapterInterface::SetHostSampleRate(jack_nframes_t sample_rate)
  345. {
  346. fHostSampleRate = sample_rate;
  347. if (NULL != fPIControllerCapture) {
  348. for (int i = 0; i < fCaptureChannels; i++) {
  349. fPIControllerCapture[i]->Init(double(fHostSampleRate) / double(fAdaptedSampleRate));
  350. }
  351. }
  352. if (NULL != fPIControllerPlayback) {
  353. for (int i = 0; i < fPlaybackChannels; i++) {
  354. fPIControllerPlayback[i]->Init(double(fHostSampleRate) / double(fAdaptedSampleRate));
  355. }
  356. }
  357. return 0;
  358. }
  359. int JackAudioAdapterInterface::SetAdaptedSampleRate(jack_nframes_t sample_rate)
  360. {
  361. fAdaptedSampleRate = sample_rate;
  362. if (NULL != fPIControllerCapture) {
  363. for (int i = 0; i < fCaptureChannels; i++) {
  364. fPIControllerCapture[i]->Init(double(fHostSampleRate) / double(fAdaptedSampleRate));
  365. }
  366. }
  367. if (NULL != fPIControllerPlayback) {
  368. for (int i = 0; i < fPlaybackChannels; i++ ) {
  369. fPIControllerPlayback[i]->Init(double(fHostSampleRate) / double(fAdaptedSampleRate));
  370. }
  371. }
  372. return 0;
  373. }
  374. int JackAudioAdapterInterface::SetSampleRate(jack_nframes_t sample_rate)
  375. {
  376. SetHostSampleRate(sample_rate);
  377. SetAdaptedSampleRate(sample_rate);
  378. return 0;
  379. }
  380. void JackAudioAdapterInterface::SetInputs(int inputs)
  381. {
  382. jack_log("JackAudioAdapterInterface::SetInputs %d", inputs);
  383. fCaptureChannels = inputs;
  384. }
  385. void JackAudioAdapterInterface::SetOutputs(int outputs)
  386. {
  387. jack_log("JackAudioAdapterInterface::SetOutputs %d", outputs);
  388. fPlaybackChannels = outputs;
  389. }
  390. int JackAudioAdapterInterface::GetInputs()
  391. {
  392. //jack_log("JackAudioAdapterInterface::GetInputs %d", fCaptureChannels);
  393. return fCaptureChannels;
  394. }
  395. int JackAudioAdapterInterface::GetOutputs()
  396. {
  397. //jack_log ("JackAudioAdapterInterface::GetOutputs %d", fPlaybackChannels);
  398. return fPlaybackChannels;
  399. }
  400. } // namespace