21 #include <TargetConditionals.h>
24 #include "JackAudioAdapter.h"
25 #ifndef MY_TARGET_OS_IPHONE
26 #include "JackLibSampleRateResampler.h"
36 void MeasureTable::Write(
int time1,
int time2,
float r1,
float r2,
int pos1,
int pos2)
38 int pos = (++fCount) % TABLE_MAX;
39 fTable[pos].time1 = time1;
40 fTable[pos].time2 = time2;
43 fTable[pos].pos1 = pos1;
44 fTable[pos].pos2 = pos2;
47 void MeasureTable::Save(
unsigned int fHostBufferSize,
unsigned int fHostSampleRate,
unsigned int fAdaptedSampleRate,
unsigned int fAdaptedBufferSize)
49 FILE* file = fopen(
"JackAudioAdapter.log",
"w");
51 int max = (fCount) % TABLE_MAX - 1;
52 for (
int i = 1; i < max; i++) {
53 fprintf(file,
"%d \t %d \t %d \t %f \t %f \t %d \t %d \n",
54 fTable[i].delta, fTable[i].time1, fTable[i].time2,
55 fTable[i].r1, fTable[i].r2, fTable[i].pos1, fTable[i].pos2);
61 file = fopen(
"AdapterTiming1.plot",
"w");
62 fprintf(file,
"set multiplot\n");
63 fprintf(file,
"set grid\n");
64 fprintf(file,
"set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n"
65 ,
float(fHostSampleRate)/1000.f, fHostBufferSize,
float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize);
66 fprintf(file,
"set xlabel \"audio cycles\"\n");
67 fprintf(file,
"set ylabel \"frames\"\n");
68 fprintf(file,
"plot ");
69 fprintf(file,
"\"JackAudioAdapter.log\" using 2 title \"Ringbuffer error\" with lines,");
70 fprintf(file,
"\"JackAudioAdapter.log\" using 3 title \"Ringbuffer error with timing correction\" with lines");
72 fprintf(file,
"\n unset multiplot\n");
73 fprintf(file,
"set output 'AdapterTiming1.svg\n");
74 fprintf(file,
"set terminal svg\n");
76 fprintf(file,
"set multiplot\n");
77 fprintf(file,
"set grid\n");
78 fprintf(file,
"set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n"
79 ,
float(fHostSampleRate)/1000.f, fHostBufferSize,
float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize);
80 fprintf(file,
"set xlabel \"audio cycles\"\n");
81 fprintf(file,
"set ylabel \"frames\"\n");
82 fprintf(file,
"plot ");
83 fprintf(file,
"\"JackAudioAdapter.log\" using 2 title \"Consumer interrupt period\" with lines,");
84 fprintf(file,
"\"JackAudioAdapter.log\" using 3 title \"Producer interrupt period\" with lines\n");
85 fprintf(file,
"unset multiplot\n");
86 fprintf(file,
"unset output\n");
91 file = fopen(
"AdapterTiming2.plot",
"w");
92 fprintf(file,
"set multiplot\n");
93 fprintf(file,
"set grid\n");
94 fprintf(file,
"set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n"
95 ,
float(fHostSampleRate)/1000.f, fHostBufferSize,
float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize);
96 fprintf(file,
"set xlabel \"audio cycles\"\n");
97 fprintf(file,
"set ylabel \"resampling ratio\"\n");
98 fprintf(file,
"plot ");
99 fprintf(file,
"\"JackAudioAdapter.log\" using 4 title \"Ratio 1\" with lines,");
100 fprintf(file,
"\"JackAudioAdapter.log\" using 5 title \"Ratio 2\" with lines");
102 fprintf(file,
"\n unset multiplot\n");
103 fprintf(file,
"set output 'AdapterTiming2.svg\n");
104 fprintf(file,
"set terminal svg\n");
106 fprintf(file,
"set multiplot\n");
107 fprintf(file,
"set grid\n");
108 fprintf(file,
"set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n"
109 ,
float(fHostSampleRate)/1000.f, fHostBufferSize,
float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize);
110 fprintf(file,
"set xlabel \"audio cycles\"\n");
111 fprintf(file,
"set ylabel \"resampling ratio\"\n");
112 fprintf(file,
"plot ");
113 fprintf(file,
"\"JackAudioAdapter.log\" using 4 title \"Ratio 1\" with lines,");
114 fprintf(file,
"\"JackAudioAdapter.log\" using 5 title \"Ratio 2\" with lines\n");
115 fprintf(file,
"unset multiplot\n");
116 fprintf(file,
"unset output\n");
121 file = fopen(
"AdapterTiming3.plot",
"w");
122 fprintf(file,
"set multiplot\n");
123 fprintf(file,
"set grid\n");
124 fprintf(file,
"set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n"
125 ,
float(fHostSampleRate)/1000.f, fHostBufferSize,
float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize);
126 fprintf(file,
"set xlabel \"audio cycles\"\n");
127 fprintf(file,
"set ylabel \"frames\"\n");
128 fprintf(file,
"plot ");
129 fprintf(file,
"\"JackAudioAdapter.log\" using 6 title \"Frames position in consumer ringbuffer\" with lines,");
130 fprintf(file,
"\"JackAudioAdapter.log\" using 7 title \"Frames position in producer ringbuffer\" with lines");
132 fprintf(file,
"\n unset multiplot\n");
133 fprintf(file,
"set output 'AdapterTiming3.svg\n");
134 fprintf(file,
"set terminal svg\n");
136 fprintf(file,
"set multiplot\n");
137 fprintf(file,
"set grid\n");
138 fprintf(file,
"set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n"
139 ,
float(fHostSampleRate)/1000.f, fHostBufferSize,
float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize);
140 fprintf(file,
"set xlabel \"audio cycles\"\n");
141 fprintf(file,
"set ylabel \"frames\"\n");
142 fprintf(file,
"plot ");
143 fprintf(file,
"\"JackAudioAdapter.log\" using 6 title \"Frames position in consumer ringbuffer\" with lines,");
144 fprintf(file,
"\"JackAudioAdapter.log\" using 7 title \"Frames position in producer ringbuffer\" with lines\n");
145 fprintf(file,
"unset multiplot\n");
146 fprintf(file,
"unset output\n");
153 void JackAudioAdapterInterface::GrowRingBufferSize()
155 fRingbufferCurSize *= 2;
158 void JackAudioAdapterInterface::AdaptRingBufferSize()
160 if (fHostBufferSize > fAdaptedBufferSize) {
161 fRingbufferCurSize = 4 * fHostBufferSize;
163 fRingbufferCurSize = 4 * fAdaptedBufferSize;
167 void JackAudioAdapterInterface::ResetRingBuffers()
169 if (fRingbufferCurSize > DEFAULT_RB_SIZE) {
170 fRingbufferCurSize = DEFAULT_RB_SIZE;
173 for (
int i = 0; i < fCaptureChannels; i++) {
174 fCaptureRingBuffer[i]->Reset(fRingbufferCurSize);
176 for (
int i = 0; i < fPlaybackChannels; i++) {
177 fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize);
181 void JackAudioAdapterInterface::Reset()
187 #ifdef MY_TARGET_OS_IPHONE
188 void JackAudioAdapterInterface::Create()
191 void JackAudioAdapterInterface::Create()
194 fCaptureRingBuffer =
new JackResampler*[fCaptureChannels];
195 fPlaybackRingBuffer =
new JackResampler*[fPlaybackChannels];
198 AdaptRingBufferSize();
199 jack_info(
"Ringbuffer automatic adaptative mode size = %d frames", fRingbufferCurSize);
201 if (fRingbufferCurSize > DEFAULT_RB_SIZE) {
202 fRingbufferCurSize = DEFAULT_RB_SIZE;
204 jack_info(
"Fixed ringbuffer size = %d frames", fRingbufferCurSize);
207 for (
int i = 0; i < fCaptureChannels; i++ ) {
208 fCaptureRingBuffer[i] =
new JackLibSampleRateResampler(fQuality);
209 fCaptureRingBuffer[i]->Reset(fRingbufferCurSize);
211 for (
int i = 0; i < fPlaybackChannels; i++ ) {
212 fPlaybackRingBuffer[i] =
new JackLibSampleRateResampler(fQuality);
213 fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize);
216 if (fCaptureChannels > 0) {
217 jack_log(
"ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace());
219 if (fPlaybackChannels > 0) {
220 jack_log(
"WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace());
225 void JackAudioAdapterInterface::Destroy()
227 for (
int i = 0; i < fCaptureChannels; i++) {
228 delete(fCaptureRingBuffer[i]);
230 for (
int i = 0; i < fPlaybackChannels; i++) {
231 delete (fPlaybackRingBuffer[i]);
234 delete[] fCaptureRingBuffer;
235 delete[] fPlaybackRingBuffer;
238 int JackAudioAdapterInterface::PushAndPull(
float** inputBuffer,
float** outputBuffer,
unsigned int frames)
240 bool failure =
false;
244 int delta_frames = (fPullAndPushTime > 0) ? (
int)((float(
long(GetMicroSeconds() - fPullAndPushTime)) * float(fAdaptedSampleRate)) / 1000000.f) : 0;
249 if (fCaptureChannels > 0) {
250 ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetError() - delta_frames);
251 }
else if (fPlaybackChannels > 0) {
252 ratio = fPIControler.GetRatio(fPlaybackRingBuffer[0]->GetError() - delta_frames);
256 if (fCaptureRingBuffer && fCaptureRingBuffer[0] != NULL)
257 fTable.Write(fCaptureRingBuffer[0]->GetError(), fCaptureRingBuffer[0]->GetError() - delta_frames, ratio, 1/ratio, fCaptureRingBuffer[0]->ReadSpace(), fCaptureRingBuffer[0]->ReadSpace());
261 for (
int i = 0; i < fCaptureChannels; i++) {
262 fCaptureRingBuffer[i]->SetRatio(ratio);
263 if (inputBuffer[i]) {
264 if (fCaptureRingBuffer[i]->WriteResample(inputBuffer[i], frames) < frames) {
270 for (
int i = 0; i < fPlaybackChannels; i++) {
271 fPlaybackRingBuffer[i]->SetRatio(1/ratio);
272 if (outputBuffer[i]) {
273 if (fPlaybackRingBuffer[i]->ReadResample(outputBuffer[i], frames) < frames) {
280 jack_error(
"JackAudioAdapterInterface::PushAndPull ringbuffer failure... reset");
282 GrowRingBufferSize();
283 jack_info(
"Ringbuffer size = %d frames", fRingbufferCurSize);
292 int JackAudioAdapterInterface::PullAndPush(
float** inputBuffer,
float** outputBuffer,
unsigned int frames)
294 fPullAndPushTime = GetMicroSeconds();
301 for (
int i = 0; i < fCaptureChannels; i++) {
302 if (inputBuffer[i]) {
303 if (fCaptureRingBuffer[i]->Read(inputBuffer[i], frames) < frames) {
309 for (
int i = 0; i < fPlaybackChannels; i++) {
310 if (outputBuffer[i]) {
311 if (fPlaybackRingBuffer[i]->Write(outputBuffer[i], frames) < frames) {