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();
   303         for (
int i = 0; i < fCaptureChannels; i++) {
   304             if (inputBuffer[i]) {
   305                 if (fCaptureRingBuffer[i]->Read(inputBuffer[i], frames) < frames) {
   311         for (
int i = 0; i < fPlaybackChannels; i++) {
   312             if (outputBuffer[i]) {
   313                 if (fPlaybackRingBuffer[i]->Write(outputBuffer[i], frames) < frames) {
   322     int JackAudioAdapterInterface::SetHostBufferSize(jack_nframes_t buffer_size)
   324         fHostBufferSize = buffer_size;
   326             AdaptRingBufferSize();
   331     int JackAudioAdapterInterface::SetAdaptedBufferSize(jack_nframes_t buffer_size)
   333         fAdaptedBufferSize = buffer_size;
   335             AdaptRingBufferSize();
   340     int JackAudioAdapterInterface::SetBufferSize(jack_nframes_t buffer_size)
   342         SetHostBufferSize(buffer_size);
   343         SetAdaptedBufferSize(buffer_size);
   347     int JackAudioAdapterInterface::SetHostSampleRate(jack_nframes_t sample_rate)
   349         fHostSampleRate = sample_rate;
   350         fPIControler.Init(
double(fHostSampleRate) / 
double(fAdaptedSampleRate));
   354     int JackAudioAdapterInterface::SetAdaptedSampleRate(jack_nframes_t sample_rate)
   356         fAdaptedSampleRate = sample_rate;
   357         fPIControler.Init(
double(fHostSampleRate) / 
double(fAdaptedSampleRate));
   361     int JackAudioAdapterInterface::SetSampleRate(jack_nframes_t sample_rate)
   363         SetHostSampleRate(sample_rate);
   364         SetAdaptedSampleRate(sample_rate);
   368     void JackAudioAdapterInterface::SetInputs(
int inputs)
   370         jack_log(
"JackAudioAdapterInterface::SetInputs %d", inputs);
   371         fCaptureChannels = inputs;
   374     void JackAudioAdapterInterface::SetOutputs(
int outputs)
   376         jack_log(
"JackAudioAdapterInterface::SetOutputs %d", outputs);
   377         fPlaybackChannels = outputs;
   380     int JackAudioAdapterInterface::GetInputs()
   383         return fCaptureChannels;
   386     int JackAudioAdapterInterface::GetOutputs()
   389         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,...)