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.

220 lines
7.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 "JackAudioAdapter.h"
  16. #include "JackLibSampleRateResampler.h"
  17. #include "JackTime.h"
  18. #include <stdio.h>
  19. namespace Jack
  20. {
  21. #ifdef JACK_MONITOR
  22. void MeasureTable::Write(int time1, int time2, float r1, float r2, int pos1, int pos2)
  23. {
  24. int pos = (++fCount) % TABLE_MAX;
  25. fTable[pos].time1 = time1;
  26. fTable[pos].time2 = time2;
  27. fTable[pos].r1 = r1;
  28. fTable[pos].r2 = r2;
  29. fTable[pos].pos1 = pos1;
  30. fTable[pos].pos2 = pos2;
  31. }
  32. void MeasureTable::Save()
  33. {
  34. char buffer[1024];
  35. FILE* file = fopen("JackAudioAdapter.log", "w");
  36. int max = (fCount) % TABLE_MAX - 1;
  37. for (int i = 1; i < max; i++)
  38. {
  39. fprintf(file, "%d \t %d \t %d \t %f \t %f \t %d \t %d \n",
  40. fTable[i].delta, fTable[i+1].time1 - fTable[i].time1,
  41. fTable[i+1].time2 - fTable[i].time2,
  42. fTable[i].r1, fTable[i].r2, fTable[i].pos1, fTable[i].pos2);
  43. }
  44. fclose(file);
  45. // Adapter timing 1
  46. file = fopen("AdapterTiming1.plot", "w");
  47. fprintf(file, "set multiplot\n");
  48. fprintf(file, "set grid\n");
  49. fprintf(file, "set title \"Audio adapter timing\"\n");
  50. fprintf(file, "set xlabel \"audio cycles\"\n");
  51. fprintf(file, "set ylabel \"frames\"\n");
  52. fprintf(file, "plot ");
  53. sprintf(buffer, "\"JackAudioAdapter.log\" using 2 title \"Consumer interrupt period\" with lines,");
  54. fprintf(file, buffer);
  55. sprintf(buffer, "\"JackAudioAdapter.log\" using 3 title \"Producer interrupt period\" with lines");
  56. fprintf(file, buffer);
  57. fclose(file);
  58. // Adapter timing 2
  59. file = fopen("AdapterTiming2.plot", "w");
  60. fprintf(file, "set multiplot\n");
  61. fprintf(file, "set grid\n");
  62. fprintf(file, "set title \"Audio adapter timing\"\n");
  63. fprintf(file, "set xlabel \"audio cycles\"\n");
  64. fprintf(file, "set ylabel \"resampling ratio\"\n");
  65. fprintf(file, "plot ");
  66. sprintf(buffer, "\"JackAudioAdapter.log\" using 4 title \"Ratio 1\" with lines,");
  67. fprintf(file, buffer);
  68. sprintf(buffer, "\"JackAudioAdapter.log\" using 5 title \"Ratio 2\" with lines");
  69. fprintf(file, buffer);
  70. fclose(file);
  71. // Adapter timing 3
  72. file = fopen("AdapterTiming3.plot", "w");
  73. fprintf(file, "set multiplot\n");
  74. fprintf(file, "set grid\n");
  75. fprintf(file, "set title \"Audio adapter timing\"\n");
  76. fprintf(file, "set xlabel \"audio cycles\"\n");
  77. fprintf(file, "set ylabel \"frames\"\n");
  78. fprintf(file, "plot ");
  79. sprintf(buffer, "\"JackAudioAdapter.log\" using 6 title \"Frames position in consumer ringbuffer\" with lines,");
  80. fprintf(file, buffer);
  81. sprintf(buffer, "\"JackAudioAdapter.log\" using 7 title \"Frames position in producer ringbuffer\" with lines");
  82. fprintf(file, buffer);
  83. fclose(file);
  84. }
  85. #endif
  86. void JackAudioAdapterInterface::ResetRingBuffers()
  87. {
  88. for (int i = 0; i < fCaptureChannels; i++)
  89. fCaptureRingBuffer[i]->Reset();
  90. for (int i = 0; i < fPlaybackChannels; i++)
  91. fPlaybackRingBuffer[i]->Reset();
  92. }
  93. void JackAudioAdapterInterface::ResampleFactor ( jack_time_t& frame1, jack_time_t& frame2 )
  94. {
  95. jack_time_t time = GetMicroSeconds();
  96. if (!fRunning) {
  97. // Init DLL
  98. fRunning = true;
  99. fHostDLL.Init(time);
  100. fAdaptedDLL.Init(time);
  101. frame1 = 1;
  102. frame2 = 1;
  103. } else {
  104. // DLL
  105. fAdaptedDLL.IncFrame(time);
  106. jack_nframes_t time1 = fHostDLL.Time2Frames(time);
  107. jack_nframes_t time2 = fAdaptedDLL.Time2Frames(time);
  108. frame1 = time1;
  109. frame2 = time2;
  110. jack_log("JackAudioAdapterInterface::ResampleFactor time1 = %ld time2 = %ld src_ratio_input = %f src_ratio_output = %f",
  111. long(time1), long(time2), double(time1) / double(time2), double(time2) / double(time1));
  112. }
  113. }
  114. void JackAudioAdapterInterface::Reset()
  115. {
  116. ResetRingBuffers();
  117. fRunning = false;
  118. }
  119. void JackAudioAdapterInterface::Create()
  120. {
  121. //ringbuffers
  122. fCaptureRingBuffer = new JackResampler*[fCaptureChannels];
  123. fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels];
  124. for (int i = 0; i < fCaptureChannels; i++ )
  125. fCaptureRingBuffer[i] = new JackLibSampleRateResampler(fQuality, fRingbufferSize);
  126. for (int i = 0; i < fPlaybackChannels; i++ )
  127. fPlaybackRingBuffer[i] = new JackLibSampleRateResampler(fQuality, fRingbufferSize);
  128. if (fCaptureChannels > 0)
  129. jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace());
  130. if (fPlaybackChannels > 0)
  131. jack_log("WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace());
  132. }
  133. void JackAudioAdapterInterface::Destroy()
  134. {
  135. for (int i = 0; i < fCaptureChannels; i++ )
  136. delete ( fCaptureRingBuffer[i] );
  137. for (int i = 0; i < fPlaybackChannels; i++ )
  138. delete ( fPlaybackRingBuffer[i] );
  139. delete[] fCaptureRingBuffer;
  140. delete[] fPlaybackRingBuffer;
  141. }
  142. void JackAudioAdapterInterface::PushAndPull(float** inputBuffer, float** outputBuffer, unsigned int inNumberFrames)
  143. {
  144. bool failure = false;
  145. jack_time_t time1, time2;
  146. ResampleFactor(time1, time2);
  147. // Push/pull from ringbuffer
  148. for (int i = 0; i < fCaptureChannels; i++) {
  149. fCaptureRingBuffer[i]->SetRatio(time1, time2);
  150. if (fCaptureRingBuffer[i]->WriteResample(inputBuffer[i], inNumberFrames) < inNumberFrames)
  151. failure = true;
  152. }
  153. for (int i = 0; i < fPlaybackChannels; i++) {
  154. fPlaybackRingBuffer[i]->SetRatio(time2, time1);
  155. if (fPlaybackRingBuffer[i]->ReadResample(outputBuffer[i], inNumberFrames) < inNumberFrames)
  156. failure = true;
  157. }
  158. #ifdef JACK_MONITOR
  159. fTable.Write(time1, time2, double(time1) / double(time2), double(time2) / double(time1),
  160. fCaptureRingBuffer[0]->ReadSpace(), fPlaybackRingBuffer[0]->WriteSpace());
  161. #endif
  162. // Reset all ringbuffers in case of failure
  163. if (failure) {
  164. jack_error("JackAudioAdapterInterface::PushAndPull ringbuffer failure... reset");
  165. ResetRingBuffers();
  166. }
  167. }
  168. void JackAudioAdapterInterface::PullAndPush(float** inputBuffer, float** outputBuffer, unsigned int inNumberFrames)
  169. {
  170. bool failure = false;
  171. SetCallbackTime(GetMicroSeconds());
  172. // Push/pull from ringbuffer
  173. for (int i = 0; i < fCaptureChannels; i++) {
  174. if (fCaptureRingBuffer[i]->Read(inputBuffer[i], inNumberFrames) < inNumberFrames)
  175. failure = true;
  176. }
  177. for (int i = 0; i < fPlaybackChannels; i++) {
  178. if (fPlaybackRingBuffer[i]->Write(outputBuffer[i], inNumberFrames) < inNumberFrames)
  179. failure = true;
  180. }
  181. // Reset all ringbuffers in case of failure
  182. if (failure) {
  183. jack_error("JackCallbackAudioAdapter::PullAndPush ringbuffer failure... reset");
  184. Reset();
  185. }
  186. }
  187. } // namespace