21 #include <TargetConditionals.h>
24 #include "JackAudioAdapter.h"
25 #ifndef MY_TARGET_OS_IPHONE
26 #include "JackLibSampleRateResampler.h"
29 #include "JackError.h"
37 void MeasureTable::Write(
int time1,
int time2,
float r1,
float r2,
int pos1,
int pos2)
39 int pos = (++fCount) % TABLE_MAX;
40 fTable[pos].time1 = time1;
41 fTable[pos].time2 = time2;
44 fTable[pos].pos1 = pos1;
45 fTable[pos].pos2 = pos2;
48 void MeasureTable::Save(
unsigned int fHostBufferSize,
unsigned int fHostSampleRate,
unsigned int fAdaptedSampleRate,
unsigned int fAdaptedBufferSize)
50 FILE* file = fopen(
"JackAudioAdapter.log",
"w");
52 int max = (fCount) % TABLE_MAX - 1;
53 for (
int i = 1; i < max; i++) {
54 fprintf(file,
"%d \t %d \t %d \t %f \t %f \t %d \t %d \n",
55 fTable[i].delta, fTable[i].time1, fTable[i].time2,
56 fTable[i].r1, fTable[i].r2, fTable[i].pos1, fTable[i].pos2);
62 file = fopen(
"AdapterTiming1.plot",
"w");
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 \"Ringbuffer error\" with lines,");
71 fprintf(file,
"\"JackAudioAdapter.log\" using 3 title \"Ringbuffer error with timing correction\" with lines");
73 fprintf(file,
"\n unset multiplot\n");
74 fprintf(file,
"set output 'AdapterTiming1.svg\n");
75 fprintf(file,
"set terminal svg\n");
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 \"frames\"\n");
83 fprintf(file,
"plot ");
84 fprintf(file,
"\"JackAudioAdapter.log\" using 2 title \"Consumer interrupt period\" with lines,");
85 fprintf(file,
"\"JackAudioAdapter.log\" using 3 title \"Producer interrupt period\" with lines\n");
86 fprintf(file,
"unset multiplot\n");
87 fprintf(file,
"unset output\n");
92 file = fopen(
"AdapterTiming2.plot",
"w");
93 fprintf(file,
"set multiplot\n");
94 fprintf(file,
"set grid\n");
95 fprintf(file,
"set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n"
96 ,
float(fHostSampleRate)/1000.f, fHostBufferSize,
float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize);
97 fprintf(file,
"set xlabel \"audio cycles\"\n");
98 fprintf(file,
"set ylabel \"resampling ratio\"\n");
99 fprintf(file,
"plot ");
100 fprintf(file,
"\"JackAudioAdapter.log\" using 4 title \"Ratio 1\" with lines,");
101 fprintf(file,
"\"JackAudioAdapter.log\" using 5 title \"Ratio 2\" with lines");
103 fprintf(file,
"\n unset multiplot\n");
104 fprintf(file,
"set output 'AdapterTiming2.svg\n");
105 fprintf(file,
"set terminal svg\n");
107 fprintf(file,
"set multiplot\n");
108 fprintf(file,
"set grid\n");
109 fprintf(file,
"set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n"
110 ,
float(fHostSampleRate)/1000.f, fHostBufferSize,
float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize);
111 fprintf(file,
"set xlabel \"audio cycles\"\n");
112 fprintf(file,
"set ylabel \"resampling ratio\"\n");
113 fprintf(file,
"plot ");
114 fprintf(file,
"\"JackAudioAdapter.log\" using 4 title \"Ratio 1\" with lines,");
115 fprintf(file,
"\"JackAudioAdapter.log\" using 5 title \"Ratio 2\" with lines\n");
116 fprintf(file,
"unset multiplot\n");
117 fprintf(file,
"unset output\n");
122 file = fopen(
"AdapterTiming3.plot",
"w");
123 fprintf(file,
"set multiplot\n");
124 fprintf(file,
"set grid\n");
125 fprintf(file,
"set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n"
126 ,
float(fHostSampleRate)/1000.f, fHostBufferSize,
float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize);
127 fprintf(file,
"set xlabel \"audio cycles\"\n");
128 fprintf(file,
"set ylabel \"frames\"\n");
129 fprintf(file,
"plot ");
130 fprintf(file,
"\"JackAudioAdapter.log\" using 6 title \"Frames position in consumer ringbuffer\" with lines,");
131 fprintf(file,
"\"JackAudioAdapter.log\" using 7 title \"Frames position in producer ringbuffer\" with lines");
133 fprintf(file,
"\n unset multiplot\n");
134 fprintf(file,
"set output 'AdapterTiming3.svg\n");
135 fprintf(file,
"set terminal svg\n");
137 fprintf(file,
"set multiplot\n");
138 fprintf(file,
"set grid\n");
139 fprintf(file,
"set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n"
140 ,
float(fHostSampleRate)/1000.f, fHostBufferSize,
float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize);
141 fprintf(file,
"set xlabel \"audio cycles\"\n");
142 fprintf(file,
"set ylabel \"frames\"\n");
143 fprintf(file,
"plot ");
144 fprintf(file,
"\"JackAudioAdapter.log\" using 6 title \"Frames position in consumer ringbuffer\" with lines,");
145 fprintf(file,
"\"JackAudioAdapter.log\" using 7 title \"Frames position in producer ringbuffer\" with lines\n");
146 fprintf(file,
"unset multiplot\n");
147 fprintf(file,
"unset output\n");
154 void JackAudioAdapterInterface::GrowRingBufferSize()
156 fRingbufferCurSize *= 2;
159 void JackAudioAdapterInterface::AdaptRingBufferSize()
161 if (fHostBufferSize > fAdaptedBufferSize) {
162 fRingbufferCurSize = 4 * fHostBufferSize;
164 fRingbufferCurSize = 4 * fAdaptedBufferSize;
168 void JackAudioAdapterInterface::ResetRingBuffers()
170 if (fRingbufferCurSize > DEFAULT_RB_SIZE) {
171 fRingbufferCurSize = DEFAULT_RB_SIZE;
174 for (
int i = 0; i < fCaptureChannels; i++) {
175 fCaptureRingBuffer[i]->Reset(fRingbufferCurSize);
177 for (
int i = 0; i < fPlaybackChannels; i++) {
178 fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize);
182 void JackAudioAdapterInterface::Reset()
188 #ifdef MY_TARGET_OS_IPHONE
189 void JackAudioAdapterInterface::Create()
192 void JackAudioAdapterInterface::Create()
195 fCaptureRingBuffer =
new JackResampler*[fCaptureChannels];
196 fPlaybackRingBuffer =
new JackResampler*[fPlaybackChannels];
199 AdaptRingBufferSize();
200 jack_info(
"Ringbuffer automatic adaptative mode size = %d frames", fRingbufferCurSize);
202 if (fRingbufferCurSize > DEFAULT_RB_SIZE) {
203 fRingbufferCurSize = DEFAULT_RB_SIZE;
205 jack_info(
"Fixed ringbuffer size = %d frames", fRingbufferCurSize);
208 for (
int i = 0; i < fCaptureChannels; i++ ) {
209 fCaptureRingBuffer[i] =
new JackLibSampleRateResampler(fQuality);
210 fCaptureRingBuffer[i]->Reset(fRingbufferCurSize);
212 for (
int i = 0; i < fPlaybackChannels; i++ ) {
213 fPlaybackRingBuffer[i] =
new JackLibSampleRateResampler(fQuality);
214 fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize);
217 if (fCaptureChannels > 0) {
218 jack_log(
"ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace());
220 if (fPlaybackChannels > 0) {
221 jack_log(
"WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace());
226 void JackAudioAdapterInterface::Destroy()
228 for (
int i = 0; i < fCaptureChannels; i++) {
229 delete(fCaptureRingBuffer[i]);
231 for (
int i = 0; i < fPlaybackChannels; i++) {
232 delete (fPlaybackRingBuffer[i]);
235 delete[] fCaptureRingBuffer;
236 delete[] fPlaybackRingBuffer;
239 int JackAudioAdapterInterface::PushAndPull(
float** inputBuffer,
float** outputBuffer,
unsigned int frames)
241 bool failure =
false;
245 int delta_frames = (fPullAndPushTime > 0) ? (
int)((float(
long(GetMicroSeconds() - fPullAndPushTime)) * float(fAdaptedSampleRate)) / 1000000.f) : 0;
250 if (fCaptureChannels > 0) {
251 ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetError() - delta_frames);
252 }
else if (fPlaybackChannels > 0) {
253 ratio = fPIControler.GetRatio(fPlaybackRingBuffer[0]->GetError() - delta_frames);
257 if (fCaptureRingBuffer && fCaptureRingBuffer[0] != NULL)
258 fTable.Write(fCaptureRingBuffer[0]->GetError(), fCaptureRingBuffer[0]->GetError() - delta_frames, ratio, 1/ratio, fCaptureRingBuffer[0]->ReadSpace(), fCaptureRingBuffer[0]->ReadSpace());
262 for (
int i = 0; i < fCaptureChannels; i++) {
263 fCaptureRingBuffer[i]->SetRatio(ratio);
264 if (inputBuffer[i]) {
265 if (fCaptureRingBuffer[i]->WriteResample(inputBuffer[i], frames) < frames) {
271 for (
int i = 0; i < fPlaybackChannels; i++) {
272 fPlaybackRingBuffer[i]->SetRatio(1/ratio);
273 if (outputBuffer[i]) {
274 if (fPlaybackRingBuffer[i]->ReadResample(outputBuffer[i], frames) < frames) {
281 jack_error(
"JackAudioAdapterInterface::PushAndPull ringbuffer failure... reset");
283 GrowRingBufferSize();
284 jack_info(
"Ringbuffer size = %d frames", fRingbufferCurSize);
293 int JackAudioAdapterInterface::PullAndPush(
float** inputBuffer,
float** outputBuffer,
unsigned int frames)
295 fPullAndPushTime = GetMicroSeconds();
302 for (
int i = 0; i < fCaptureChannels; i++) {
303 if (inputBuffer[i]) {
304 if (fCaptureRingBuffer[i]->Read(inputBuffer[i], frames) < frames) {
310 for (
int i = 0; i < fPlaybackChannels; i++) {
311 if (outputBuffer[i]) {
312 if (fPlaybackRingBuffer[i]->Write(outputBuffer[i], frames) < frames) {
321 int JackAudioAdapterInterface::SetHostBufferSize(jack_nframes_t buffer_size)
323 fHostBufferSize = buffer_size;
325 AdaptRingBufferSize();
330 int JackAudioAdapterInterface::SetAdaptedBufferSize(jack_nframes_t buffer_size)
332 fAdaptedBufferSize = buffer_size;
334 AdaptRingBufferSize();
339 int JackAudioAdapterInterface::SetBufferSize(jack_nframes_t buffer_size)
341 SetHostBufferSize(buffer_size);
342 SetAdaptedBufferSize(buffer_size);
346 int JackAudioAdapterInterface::SetHostSampleRate(jack_nframes_t sample_rate)
348 fHostSampleRate = sample_rate;
349 fPIControler.Init(
double(fHostSampleRate) /
double(fAdaptedSampleRate));
353 int JackAudioAdapterInterface::SetAdaptedSampleRate(jack_nframes_t sample_rate)
355 fAdaptedSampleRate = sample_rate;
356 fPIControler.Init(
double(fHostSampleRate) /
double(fAdaptedSampleRate));
360 int JackAudioAdapterInterface::SetSampleRate(jack_nframes_t sample_rate)
362 SetHostSampleRate(sample_rate);
363 SetAdaptedSampleRate(sample_rate);
367 void JackAudioAdapterInterface::SetInputs(
int inputs)
369 jack_log(
"JackAudioAdapterInterface::SetInputs %d", inputs);
370 fCaptureChannels = inputs;
373 void JackAudioAdapterInterface::SetOutputs(
int outputs)
375 jack_log(
"JackAudioAdapterInterface::SetOutputs %d", outputs);
376 fPlaybackChannels = outputs;
379 int JackAudioAdapterInterface::GetInputs()
382 return fCaptureChannels;
385 int JackAudioAdapterInterface::GetOutputs()
388 return fPlaybackChannels;
SERVER_EXPORT void jack_error(const char *fmt,...)
SERVER_EXPORT void jack_info(const char *fmt,...)
SERVER_EXPORT void jack_log(const char *fmt,...)