From 6926652401696c38e61206bee2f25ba0e222c0c3 Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 2 Mar 2009 11:16:21 +0000 Subject: [PATCH] rebase from trunk 3353:3367 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3368 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 13 +- common/JackAudioAdapter.cpp | 107 ++++-------- common/JackAudioAdapter.h | 6 - common/JackAudioAdapterInterface.cpp | 173 ++++++++++++++++++-- common/JackAudioAdapterInterface.h | 50 +++--- common/JackLibSampleRateResampler.cpp | 4 +- common/JackLibSampleRateResampler.h | 4 +- common/JackNetAPI.cpp | 182 ++++----------------- common/JackNetAdapter.cpp | 2 +- common/JackResampler.cpp | 10 +- common/JackResampler.h | 4 +- common/jack/net.h | 25 +-- common/wscript | 10 +- linux/alsa/JackAlsaAdapter.cpp | 57 +++---- linux/alsa/JackAlsaAdapter.h | 29 +++- macosx/coreaudio/JackCoreAudioAdapter.cpp | 50 +++--- solaris/oss/JackOSSAdapter.cpp | 49 +++--- solaris/oss/JackOSSAdapter.h | 2 +- windows/portaudio/JackPortAudioAdapter.cpp | 65 +++----- 19 files changed, 388 insertions(+), 454 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3762f4fc..c2361d74 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,11 +22,22 @@ Michael Voigt --------------------------- Jackdmp changes log --------------------------- + +2009-02-27 Stephane Letz + + * Improve generated gnuplot files for adapting code. + +2009-02-25 Stephane Letz + + * Major cleanup in adapter code. 2009-02-25 Stephane Letz * Fix JackNetDriver::Close method. * For audio device reservation, add card_to_num function. + * Fix buffer size and sample rate handling in JackAlsaAdapter. + * Add control for adapter ringbuffer size. + * Fix JackAlsaAdapter.h for 64 bits compilation. 2009-02-24 Stephane Letz @@ -37,7 +48,7 @@ Michael Voigt * Another fix in systemdeps.h and types.h: jack_time_t now uniquely defined in types.h. * Move generic code and data in JackNetInterface and JackNetMasterInterface classes. - * First version of D-Bus based audio device rerservation. + * First version of D-Bus based audio device reservation. 2009-02-20 Stephane Letz diff --git a/common/JackAudioAdapter.cpp b/common/JackAudioAdapter.cpp index bffc6323..06f7e0f1 100644 --- a/common/JackAudioAdapter.cpp +++ b/common/JackAudioAdapter.cpp @@ -18,7 +18,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackAudioAdapter.h" -#include "JackLibSampleRateResampler.h" #include "JackError.h" #include "JackCompilerDeps.h" #include "JackTools.h" @@ -34,40 +33,22 @@ namespace Jack { //static methods *********************************************************** - int JackAudioAdapter::Process ( jack_nframes_t frames, void* arg ) + int JackAudioAdapter::Process (jack_nframes_t frames, void* arg) { - JackAudioAdapter* adapter = static_cast ( arg ); - float* buffer; - bool failure = false; - int i; - - if ( !adapter->fAudioAdapter->IsRunning() ) + JackAudioAdapter* adapter = static_cast(arg); + if (!adapter->fAudioAdapter->IsRunning()) return 0; - - // DLL - adapter->fAudioAdapter->SetCallbackTime (GetMicroSeconds()); - - // Push/pull from ringbuffer - for ( i = 0; i < adapter->fCaptureChannels; i++ ) - { - buffer = static_cast ( jack_port_get_buffer ( adapter->fCapturePortList[i], frames ) ); - if ( adapter->fCaptureRingBuffer[i]->Read ( buffer, frames ) < frames ) - failure = true; + + float* inputBuffer[adapter->fAudioAdapter->GetInputs()]; + float* outputBuffer[adapter->fAudioAdapter->GetOutputs()]; + for (int i = 0; i < adapter->fAudioAdapter->GetInputs(); i++) { + inputBuffer[i] = (float*)jack_port_get_buffer(adapter->fCapturePortList[i], frames); } - - for ( i = 0; i < adapter->fPlaybackChannels; i++ ) - { - buffer = static_cast ( jack_port_get_buffer ( adapter->fPlaybackPortList[i], frames ) ); - if ( adapter->fPlaybackRingBuffer[i]->Write ( buffer, frames ) < frames ) - failure = true; - } - - // Reset all ringbuffers in case of failure - if ( failure ) - { - jack_error ( "JackCallbackAudioAdapter::Process ringbuffer failure... reset" ); - adapter->Reset(); + for (int i = 0; i < adapter->fAudioAdapter->GetOutputs(); i++) { + outputBuffer[i] = (float*)jack_port_get_buffer(adapter->fPlaybackPortList[i], frames); } + + adapter->fAudioAdapter->PullAndPush(inputBuffer, outputBuffer, frames); return 0; } @@ -91,24 +72,15 @@ namespace Jack JackAudioAdapter::~JackAudioAdapter() { // When called, Close has already been used for the client, thus ports are already unregistered. - int i; - for ( i = 0; i < fCaptureChannels; i++ ) - delete ( fCaptureRingBuffer[i] ); - for ( i = 0; i < fPlaybackChannels; i++ ) - delete ( fPlaybackRingBuffer[i] ); - - delete[] fCaptureRingBuffer; - delete[] fPlaybackRingBuffer; delete fAudioAdapter; } void JackAudioAdapter::FreePorts() { - int i; - for ( i = 0; i < fCaptureChannels; i++ ) + for (int i = 0; i < fAudioAdapter->GetInputs(); i++ ) if ( fCapturePortList[i] ) jack_port_unregister ( fJackClient, fCapturePortList[i] ); - for ( i = 0; i < fCaptureChannels; i++ ) + for (int i = 0; i < fAudioAdapter->GetOutputs(); i++ ) if ( fPlaybackPortList[i] ) jack_port_unregister ( fJackClient, fPlaybackPortList[i] ); @@ -118,52 +90,30 @@ namespace Jack void JackAudioAdapter::Reset() { - int i; - for ( i = 0; i < fCaptureChannels; i++ ) - fCaptureRingBuffer[i]->Reset(); - for ( i = 0; i < fPlaybackChannels; i++ ) - fPlaybackRingBuffer[i]->Reset(); fAudioAdapter->Reset(); } int JackAudioAdapter::Open() { - int i; char name[32]; - - fCaptureChannels = fAudioAdapter->GetInputs(); - fPlaybackChannels = fAudioAdapter->GetOutputs(); - - jack_log ( "JackAudioAdapter::Open fCaptureChannels %d fPlaybackChannels %d", fCaptureChannels, fPlaybackChannels ); - - //ringbuffers - fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; - fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; - for ( i = 0; i < fCaptureChannels; i++ ) - fCaptureRingBuffer[i] = new JackLibSampleRateResampler(fAudioAdapter->GetQuality()); - for ( i = 0; i < fPlaybackChannels; i++ ) - fPlaybackRingBuffer[i] = new JackLibSampleRateResampler(fAudioAdapter->GetQuality()); - fAudioAdapter->SetRingBuffers ( fCaptureRingBuffer, fPlaybackRingBuffer ); - if (fCaptureChannels > 0) - jack_log ( "ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace() ); - if (fPlaybackChannels > 0) - jack_log ( "WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace() ); - + jack_log("JackAudioAdapter::Open fCaptureChannels %d fPlaybackChannels %d", fAudioAdapter->GetInputs(), fAudioAdapter->GetOutputs()); + fAudioAdapter->Create(); + //jack ports - fCapturePortList = new jack_port_t* [fCaptureChannels]; - fPlaybackPortList = new jack_port_t* [fPlaybackChannels]; + fCapturePortList = new jack_port_t*[fAudioAdapter->GetInputs()]; + fPlaybackPortList = new jack_port_t*[fAudioAdapter->GetOutputs()]; - for ( i = 0; i < fCaptureChannels; i++ ) + for (int i = 0; i < fAudioAdapter->GetInputs(); i++) { - sprintf ( name, "capture_%d", i+1 ); - if ( ( fCapturePortList[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ) ) == NULL ) + sprintf(name, "capture_%d", i + 1); + if ((fCapturePortList[i] = jack_port_register(fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == NULL) goto fail; } - for ( i = 0; i < fPlaybackChannels; i++ ) + for (int i = 0; i < fAudioAdapter->GetOutputs(); i++) { - sprintf ( name, "playback_%d", i+1 ); - if ( ( fPlaybackPortList[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 ) ) == NULL ) + sprintf(name, "playback_%d", i + 1); + if ((fPlaybackPortList[i] = jack_port_register(fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 )) == NULL) goto fail; } @@ -177,17 +127,20 @@ namespace Jack if ( jack_activate ( fJackClient ) < 0 ) goto fail; - //ringbuffers and jack clients are ok, we can now open the adapter driver interface + // Ring buffer are now allocated.. return fAudioAdapter->Open(); fail: FreePorts(); + fAudioAdapter->Destroy(); return -1; } int JackAudioAdapter::Close() { - return fAudioAdapter->Close(); + fAudioAdapter->Close(); + fAudioAdapter->Destroy(); + return 0; } } //namespace diff --git a/common/JackAudioAdapter.h b/common/JackAudioAdapter.h index eab6ba3d..1a15c2a0 100644 --- a/common/JackAudioAdapter.h +++ b/common/JackAudioAdapter.h @@ -37,12 +37,6 @@ namespace Jack static int BufferSize ( jack_nframes_t buffer_size, void *arg ); static int SampleRate ( jack_nframes_t sample_rate, void *arg ); - int fCaptureChannels; - int fPlaybackChannels; - - JackResampler** fCaptureRingBuffer; - JackResampler** fPlaybackRingBuffer; - jack_port_t** fCapturePortList; jack_port_t** fPlaybackPortList; diff --git a/common/JackAudioAdapterInterface.cpp b/common/JackAudioAdapterInterface.cpp index b3401b03..21bef7f0 100644 --- a/common/JackAudioAdapterInterface.cpp +++ b/common/JackAudioAdapterInterface.cpp @@ -18,6 +18,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackAudioAdapter.h" +#include +#ifndef TARGET_OS_IPHONE +#include "JackLibSampleRateResampler.h" +#endif #include "JackTime.h" #include @@ -37,7 +41,7 @@ namespace Jack fTable[pos].pos2 = pos2; } - void MeasureTable::Save() + void MeasureTable::Save(unsigned int fHostBufferSize, unsigned int fHostSampleRate, unsigned int fAdaptedSampleRate, unsigned int fAdaptedBufferSize) { char buffer[1024]; FILE* file = fopen("JackAudioAdapter.log", "w"); @@ -54,6 +58,22 @@ namespace Jack // Adapter timing 1 file = fopen("AdapterTiming1.plot", "w"); + fprintf(file, "set multiplot\n"); + fprintf(file, "set grid\n"); + fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n" + ,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize); + fprintf(file, "set xlabel \"audio cycles\"\n"); + fprintf(file, "set ylabel \"frames\"\n"); + fprintf(file, "plot "); + sprintf(buffer, "\"JackAudioAdapter.log\" using 2 title \"Consumer interrupt period\" with lines,"); + fprintf(file, buffer); + sprintf(buffer, "\"JackAudioAdapter.log\" using 3 title \"Producer interrupt period\" with lines"); + fprintf(file, buffer); + + fprintf(file, "\n unset multiplot\n"); + fprintf(file, "set output 'AdapterTiming1.pdf\n"); + fprintf(file, "set terminal pdf\n"); + fprintf(file, "set multiplot\n"); fprintf(file, "set grid\n"); fprintf(file, "set title \"Audio adapter timing\"\n"); @@ -64,10 +84,27 @@ namespace Jack fprintf(file, buffer); sprintf(buffer, "\"JackAudioAdapter.log\" using 3 title \"Producer interrupt period\" with lines"); fprintf(file, buffer); + fclose(file); // Adapter timing 2 file = fopen("AdapterTiming2.plot", "w"); + fprintf(file, "set multiplot\n"); + fprintf(file, "set grid\n"); + fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n" + ,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize); + fprintf(file, "set xlabel \"audio cycles\"\n"); + fprintf(file, "set ylabel \"resampling ratio\"\n"); + fprintf(file, "plot "); + sprintf(buffer, "\"JackAudioAdapter.log\" using 4 title \"Ratio 1\" with lines,"); + fprintf(file, buffer); + sprintf(buffer, "\"JackAudioAdapter.log\" using 5 title \"Ratio 2\" with lines"); + fprintf(file, buffer); + + fprintf(file, "\n unset multiplot\n"); + fprintf(file, "set output 'AdapterTiming2.pdf\n"); + fprintf(file, "set terminal pdf\n"); + fprintf(file, "set multiplot\n"); fprintf(file, "set grid\n"); fprintf(file, "set title \"Audio adapter timing\"\n"); @@ -78,10 +115,27 @@ namespace Jack fprintf(file, buffer); sprintf(buffer, "\"JackAudioAdapter.log\" using 5 title \"Ratio 2\" with lines"); fprintf(file, buffer); + fclose(file); // Adapter timing 3 file = fopen("AdapterTiming3.plot", "w"); + fprintf(file, "set multiplot\n"); + fprintf(file, "set grid\n"); + fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n" + ,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize); + fprintf(file, "set xlabel \"audio cycles\"\n"); + fprintf(file, "set ylabel \"frames\"\n"); + fprintf(file, "plot "); + sprintf(buffer, "\"JackAudioAdapter.log\" using 6 title \"Frames position in consumer ringbuffer\" with lines,"); + fprintf(file, buffer); + sprintf(buffer, "\"JackAudioAdapter.log\" using 7 title \"Frames position in producer ringbuffer\" with lines"); + fprintf(file, buffer); + + fprintf(file, "\n unset multiplot\n"); + fprintf(file, "set output 'AdapterTiming3.pdf\n"); + fprintf(file, "set terminal pdf\n"); + fprintf(file, "set multiplot\n"); fprintf(file, "set grid\n"); fprintf(file, "set title \"Audio adapter timing\"\n"); @@ -92,35 +146,32 @@ namespace Jack fprintf(file, buffer); sprintf(buffer, "\"JackAudioAdapter.log\" using 7 title \"Frames position in producer ringbuffer\" with lines"); fprintf(file, buffer); + fclose(file); } #endif - + void JackAudioAdapterInterface::ResetRingBuffers() { - int i; - for (i = 0; i < fCaptureChannels; i++) + for (int i = 0; i < fCaptureChannels; i++) fCaptureRingBuffer[i]->Reset(); - for (i = 0; i < fPlaybackChannels; i++) + for (int i = 0; i < fPlaybackChannels; i++) fPlaybackRingBuffer[i]->Reset(); } - void JackAudioAdapterInterface::ResampleFactor ( jack_nframes_t& frame1, jack_nframes_t& frame2 ) + void JackAudioAdapterInterface::ResampleFactor ( jack_time_t& frame1, jack_time_t& frame2 ) { jack_time_t time = GetMicroSeconds(); - if ( !fRunning ) - { + if (!fRunning) { // Init DLL fRunning = true; - fHostDLL.Init ( time ); - fAdaptedDLL.Init ( time ); + fHostDLL.Init(time); + fAdaptedDLL.Init(time); frame1 = 1; frame2 = 1; - } - else - { + } else { // DLL fAdaptedDLL.IncFrame(time); jack_nframes_t time1 = fHostDLL.Time2Frames(time); @@ -131,15 +182,103 @@ namespace Jack long(time1), long(time2), double(time1) / double(time2), double(time2) / double(time1)); } } + + void JackAudioAdapterInterface::Reset() + { + ResetRingBuffers(); + fRunning = false; + } + +#ifdef TARGET_OS_IPHONE + void JackAudioAdapterInterface::Create() + {} +#else + void JackAudioAdapterInterface::Create() + { + //ringbuffers + fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; + fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; + for (int i = 0; i < fCaptureChannels; i++ ) + fCaptureRingBuffer[i] = new JackLibSampleRateResampler(fQuality, fRingbufferSize); + for (int i = 0; i < fPlaybackChannels; i++ ) + fPlaybackRingBuffer[i] = new JackLibSampleRateResampler(fQuality, fRingbufferSize); + + if (fCaptureChannels > 0) + jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace()); + if (fPlaybackChannels > 0) + jack_log("WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace()); + } +#endif + + void JackAudioAdapterInterface::Destroy() + { + for (int i = 0; i < fCaptureChannels; i++ ) + delete ( fCaptureRingBuffer[i] ); + for (int i = 0; i < fPlaybackChannels; i++ ) + delete ( fPlaybackRingBuffer[i] ); - int JackAudioAdapterInterface::Open() + delete[] fCaptureRingBuffer; + delete[] fPlaybackRingBuffer; + } + + int JackAudioAdapterInterface::PushAndPull(float** inputBuffer, float** outputBuffer, unsigned int frames) { - return 0; + bool failure = false; + jack_time_t time1, time2; + ResampleFactor(time1, time2); + + // Push/pull from ringbuffer + for (int i = 0; i < fCaptureChannels; i++) { + fCaptureRingBuffer[i]->SetRatio(time1, time2); + if (fCaptureRingBuffer[i]->WriteResample(inputBuffer[i], frames) < frames) + failure = true; + } + + for (int i = 0; i < fPlaybackChannels; i++) { + fPlaybackRingBuffer[i]->SetRatio(time2, time1); + if (fPlaybackRingBuffer[i]->ReadResample(outputBuffer[i], frames) < frames) + failure = true; + } + + #ifdef JACK_MONITOR + fTable.Write(time1, time2, double(time1) / double(time2), double(time2) / double(time1), + fCaptureRingBuffer[0]->ReadSpace(), fPlaybackRingBuffer[0]->WriteSpace()); + #endif + + // Reset all ringbuffers in case of failure + if (failure) { + jack_error("JackAudioAdapterInterface::PushAndPull ringbuffer failure... reset"); + ResetRingBuffers(); + return -1; + } else { + return 0; + } } - int JackAudioAdapterInterface::Close() + int JackAudioAdapterInterface::PullAndPush(float** inputBuffer, float** outputBuffer, unsigned int frames) { - return 0; + bool failure = false; + fHostDLL.IncFrame(GetMicroSeconds()); + + // Push/pull from ringbuffer + for (int i = 0; i < fCaptureChannels; i++) { + if (fCaptureRingBuffer[i]->Read(inputBuffer[i], frames) < frames) + failure = true; + } + + for (int i = 0; i < fPlaybackChannels; i++) { + if (fPlaybackRingBuffer[i]->Write(outputBuffer[i], frames) < frames) + failure = true; + } + + // Reset all ringbuffers in case of failure + if (failure) { + jack_error("JackCallbackAudioAdapter::PullAndPush ringbuffer failure... reset"); + Reset(); + return -1; + } else { + return 0; + } } } // namespace diff --git a/common/JackAudioAdapterInterface.h b/common/JackAudioAdapterInterface.h index 81b6cc87..4b06d0d3 100644 --- a/common/JackAudioAdapterInterface.h +++ b/common/JackAudioAdapterInterface.h @@ -51,8 +51,8 @@ namespace Jack MeasureTable() :fCount ( 0 ) {} - void Write ( int time1, int time2, float r1, float r2, int pos1, int pos2 ); - void Save(); + void Write(int time1, int time2, float r1, float r2, int pos1, int pos2); + void Save(unsigned int fHostBufferSize, unsigned int fHostSampleRate, unsigned int fAdaptedSampleRate, unsigned int fAdaptedBufferSize); }; @@ -90,9 +90,13 @@ namespace Jack JackResampler** fPlaybackRingBuffer; unsigned int fQuality; - + unsigned int fRingbufferSize; + bool fRunning; - + + void ResetRingBuffers(); + void ResampleFactor ( jack_time_t& frame1, jack_time_t& frame2 ); + public: JackAudioAdapterInterface ( jack_nframes_t host_buffer_size, @@ -106,6 +110,7 @@ namespace Jack fHostDLL ( host_buffer_size, host_sample_rate ), fAdaptedDLL ( host_buffer_size, host_sample_rate ), fQuality(0), + fRingbufferSize(DEFAULT_RB_SIZE), fRunning ( false ) {} JackAudioAdapterInterface ( jack_nframes_t host_buffer_size, @@ -121,38 +126,33 @@ namespace Jack fHostDLL ( host_buffer_size, host_sample_rate ), fAdaptedDLL ( adapted_buffer_size, adapted_sample_rate ), fQuality(0), + fRingbufferSize(DEFAULT_RB_SIZE), fRunning ( false ) {} virtual ~JackAudioAdapterInterface() {} - void SetRingBuffers ( JackResampler** input, JackResampler** output ) - { - fCaptureRingBuffer = input; - fPlaybackRingBuffer = output; - } - bool IsRunning() { return fRunning; } - virtual void Reset() + virtual void Reset(); + + virtual void Create(); + virtual void Destroy(); + + virtual int Open() { - fRunning = false; + return 0; } - - void ResetRingBuffers(); - unsigned int GetQuality() + virtual int Close() { - return fQuality; + return 0; } - virtual int Open(); - virtual int Close(); - virtual int SetHostBufferSize ( jack_nframes_t buffer_size ) { fHostBufferSize = buffer_size; @@ -194,14 +194,7 @@ namespace Jack SetAdaptedSampleRate ( sample_rate ); return 0; } - - virtual void SetCallbackTime ( jack_time_t callback_usec ) - { - fHostDLL.IncFrame ( callback_usec ); - } - - void ResampleFactor ( jack_nframes_t& frame1, jack_nframes_t& frame2 ); - + void SetInputs ( int inputs ) { jack_log ( "JackAudioAdapterInterface::SetInputs %d", inputs ); @@ -225,6 +218,9 @@ namespace Jack jack_log ( "JackAudioAdapterInterface::GetOutputs %d", fPlaybackChannels ); return fPlaybackChannels; } + + int PushAndPull(float** inputBuffer, float** outputBuffer, unsigned int frames); + int PullAndPush(float** inputBuffer, float** outputBuffer, unsigned int frames); }; diff --git a/common/JackLibSampleRateResampler.cpp b/common/JackLibSampleRateResampler.cpp index f7d90154..a2dfb472 100644 --- a/common/JackLibSampleRateResampler.cpp +++ b/common/JackLibSampleRateResampler.cpp @@ -31,8 +31,8 @@ JackLibSampleRateResampler::JackLibSampleRateResampler() jack_error("JackLibSampleRateResampler::JackLibSampleRateResampler err = %s", src_strerror(error)); } -JackLibSampleRateResampler::JackLibSampleRateResampler(unsigned int quality) - :JackResampler(),fRatio(1) +JackLibSampleRateResampler::JackLibSampleRateResampler(unsigned int quality, unsigned int ringbuffer_size) + :JackResampler(ringbuffer_size),fRatio(1) { switch (quality) { case 0: diff --git a/common/JackLibSampleRateResampler.h b/common/JackLibSampleRateResampler.h index 480097c9..bbb85cba 100644 --- a/common/JackLibSampleRateResampler.h +++ b/common/JackLibSampleRateResampler.h @@ -46,7 +46,7 @@ class JackLibSampleRateResampler : public JackResampler public: JackLibSampleRateResampler(); - JackLibSampleRateResampler(unsigned int quality); + JackLibSampleRateResampler(unsigned int quality, unsigned int ringbuffer_size); virtual ~JackLibSampleRateResampler(); unsigned int ReadResample(float* buffer, unsigned int frames); @@ -55,7 +55,7 @@ class JackLibSampleRateResampler : public JackResampler void SetRatio(unsigned int num, unsigned int denom) { JackResampler::SetRatio(num, denom); - fRatio = Range(0.25f, 4.0f, (double(num) / double(denom))); + fRatio = Range(0.25, 4.0, (double(num) / double(denom))); } void Reset(); diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index a0fb8d89..668ea4af 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -106,18 +106,16 @@ extern "C" typedef struct _jack_adapter jack_adapter_t; - SERVER_EXPORT jack_adapter_t* jack_create_adapter(jack_nframes_t host_buffer_size, + SERVER_EXPORT jack_adapter_t* jack_create_adapter(int input, int output, + jack_nframes_t host_buffer_size, jack_nframes_t host_sample_rate, jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_sample_rate); SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter); - SERVER_EXPORT int jack_adapter_push_input(jack_adapter_t* adapter, int channels, float** buffers); - SERVER_EXPORT int jack_adapter_pull_input(jack_adapter_t* adapter, int channels, float** buffers); - - SERVER_EXPORT int jack_adapter_push_output(jack_adapter_t* adapter, int channels, float** buffers); - SERVER_EXPORT int jack_adapter_pull_output(jack_adapter_t* adapter, int channels, float** buffers); - + SERVER_EXPORT int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); + SERVER_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); + #ifdef __cplusplus } #endif @@ -734,144 +732,39 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf struct JackNetAdapter : public JackAudioAdapterInterface { - JackNetAdapter(jack_nframes_t host_buffer_size, + JackNetAdapter(int input, int output, + jack_nframes_t host_buffer_size, jack_nframes_t host_sample_rate, jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_sample_rate) :JackAudioAdapterInterface(host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate) { - fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; - fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; - - /* - for (i = 0; i < fCaptureChannels; i++) - fCaptureRingBuffer[i] = new JackLibSampleRateResampler(fAudioAdapter->GetQuality()); - for (i = 0; i < fPlaybackChannels; i++) - fPlaybackRingBuffer[i] = new JackLibSampleRateResampler(fAudioAdapter->GetQuality()); - */ - - int i; - for (i = 0; i < fCaptureChannels; i++) - fCaptureRingBuffer[i] = new JackResampler(); - for (i = 0; i < fPlaybackChannels; i++) - fPlaybackRingBuffer[i] = new JackResampler(); - } - - virtual ~JackNetAdapter() - { - int i; - for (i = 0; i < fCaptureChannels; i++) - delete (fCaptureRingBuffer[i]); - for (i = 0; i < fPlaybackChannels; i++) - delete(fPlaybackRingBuffer[i] ); - - delete[] fCaptureRingBuffer; - delete[] fPlaybackRingBuffer; - } - - void Reset() - { - int i; - for (i = 0; i < fCaptureChannels; i++) - fCaptureRingBuffer[i]->Reset(); - for (i = 0; i < fPlaybackChannels; i++) - fPlaybackRingBuffer[i]->Reset(); - } - - int PushInput(int audio_input, float** audio_input_buffer) - { - bool failure = false; - int port_index; - - // Get the resample factor, - jack_nframes_t time1, time2; - ResampleFactor(time1, time2); - - // Resample input data, - for (port_index = 0; port_index < audio_input; port_index++) { - fCaptureRingBuffer[port_index]->SetRatio(time1, time2); - if (fCaptureRingBuffer[port_index]->WriteResample(audio_input_buffer[port_index], fAdaptedBufferSize) < fAdaptedBufferSize) - failure = true; - } - - if (failure) { - ResetRingBuffers(); - return -1; - } - - return 0; + fCaptureChannels = input; + fPlaybackChannels = output; + Create(); } - int PullInput(int audio_input, float** audio_input_buffer) + void JackNetAdapter::Create() { - bool failure = false; - int port_index; - - // DLL - SetCallbackTime(GetMicroSeconds()); - - // Push/pull from ringbuffer - for (port_index = 0; port_index < audio_input; port_index++) { - if (fCaptureRingBuffer[port_index]->Read(audio_input_buffer[port_index], fHostBufferSize) < fHostBufferSize) - failure = true; - } - - // Reset all ringbuffers in case of failure - if (failure) { - Reset(); - return -1; - } - - return 0; - } - - int PushOutput(int audio_input, float** audio_input_buffer) - { - bool failure = false; - int port_index; - - // DLL - SetCallbackTime(GetMicroSeconds()); + //ringbuffers + fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; + fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; + for (int i = 0; i < fCaptureChannels; i++ ) + fCaptureRingBuffer[i] = new JackResampler(fRingbufferSize); + for (int i = 0; i < fPlaybackChannels; i++ ) + fPlaybackRingBuffer[i] = new JackResampler(fRingbufferSize); - // Push/pull from ringbuffer - for (port_index = 0; port_index < audio_input; port_index++) { - if (fPlaybackRingBuffer[port_index]->Write(audio_input_buffer[port_index], fHostBufferSize) < fHostBufferSize) - failure = true; - } - - // Reset all ringbuffers in case of failure - if (failure) { - Reset(); - return -1; - } - - return 0; + if (fCaptureChannels > 0) + jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace()); + if (fPlaybackChannels > 0) + jack_log("WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace()); } - int PullOutput(int audio_output, float** audio_output_buffer) + virtual ~JackNetAdapter() { - bool failure = false; - int port_index; - - //get the resample factor, - jack_nframes_t time1, time2; - ResampleFactor(time1, time2); - - //resample output data, - for (port_index = 0; port_index < fPlaybackChannels; port_index++) { - fPlaybackRingBuffer[port_index]->SetRatio(time2, time1); - if (fPlaybackRingBuffer[port_index]->ReadResample(audio_output_buffer[port_index], fAdaptedBufferSize) < fAdaptedBufferSize) - failure = true; - } - - if (failure) { - ResetRingBuffers(); - return -1; - } - - return 0; + Destroy(); } - + }; @@ -968,12 +861,13 @@ SERVER_EXPORT int jack_net_master_send(jack_net_master_t* net, int audio_output, // Adapter API -SERVER_EXPORT jack_adapter_t* jack_create_adapter(jack_nframes_t host_buffer_size, +SERVER_EXPORT jack_adapter_t* jack_create_adapter(int input, int output, + jack_nframes_t host_buffer_size, jack_nframes_t host_sample_rate, jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_sample_rate) { - return (jack_adapter_t*)new JackNetAdapter(host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate); + return (jack_adapter_t*)new JackNetAdapter(input, output, host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate); } SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter) @@ -982,30 +876,18 @@ SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter) return 0; } -SERVER_EXPORT int jack_adapter_push_input(jack_adapter_t * adapter, int channels, float** buffers) +SERVER_EXPORT int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames) { JackNetAdapter* slave = (JackNetAdapter*)adapter; - return slave->PushInput(channels, buffers); + return slave->PushAndPull(input, output, frames); } -SERVER_EXPORT int jack_adapter_pull_input(jack_adapter_t * adapter, int channels, float** buffers) +SERVER_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames) { JackNetAdapter* slave = (JackNetAdapter*)adapter; - return slave->PullInput(channels, buffers); -} - -SERVER_EXPORT int jack_adapter_push_output(jack_adapter_t * adapter, int channels, float** buffers) -{ - JackNetAdapter* slave = (JackNetAdapter*)adapter; - return slave->PushOutput(channels, buffers); + return slave->PullAndPush(input, output, frames); } -SERVER_EXPORT int jack_adapter_pull_output(jack_adapter_t * adapter, int channels, float** buffers) -{ - JackNetAdapter* slave = (JackNetAdapter*)adapter; - return slave->PullOutput(channels, buffers); -} - // Empty code for now.. //#ifdef TARGET_OS_IPHONE diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index 3c088eb7..a5b85b63 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -367,7 +367,7 @@ namespace Jack return SOCKET_ERROR; //get the resample factor, - jack_nframes_t time1, time2; + jack_time_t time1, time2; ResampleFactor ( time1, time2 ); //resample input data, diff --git a/common/JackResampler.cpp b/common/JackResampler.cpp index f09b0413..19945adf 100644 --- a/common/JackResampler.cpp +++ b/common/JackResampler.cpp @@ -18,6 +18,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackResampler.h" +#include namespace Jack { @@ -28,6 +29,12 @@ JackResampler::JackResampler():fNum(1),fDenom(1) jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * DEFAULT_RB_SIZE) / 2); } +JackResampler::JackResampler(unsigned int ringbuffer_size):fNum(1),fDenom(1),fRingBufferSize(ringbuffer_size) +{ + fRingBuffer = jack_ringbuffer_create(sizeof(float) * fRingBufferSize); + jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * fRingBufferSize) / 2); +} + JackResampler::~JackResampler() { if (fRingBuffer) @@ -36,7 +43,8 @@ JackResampler::~JackResampler() void JackResampler::Reset() { - jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * DEFAULT_RB_SIZE) / 2); + jack_ringbuffer_reset(fRingBuffer); + jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * fRingBufferSize) / 2); } unsigned int JackResampler::ReadSpace() diff --git a/common/JackResampler.h b/common/JackResampler.h index d656d59d..fb6e30f2 100644 --- a/common/JackResampler.h +++ b/common/JackResampler.h @@ -40,10 +40,12 @@ class JackResampler jack_ringbuffer_t* fRingBuffer; unsigned int fNum; unsigned int fDenom; - + unsigned int fRingBufferSize; + public: JackResampler(); + JackResampler(unsigned int ringbuffer_size); virtual ~JackResampler(); virtual void Reset(); diff --git a/common/jack/net.h b/common/jack/net.h index 940a0692..ba1dd0dc 100644 --- a/common/jack/net.h +++ b/common/jack/net.h @@ -255,7 +255,8 @@ typedef struct _jack_adapter jack_adapter_t; * * @return 0 on success, otherwise a non-zero error code */ -jack_adapter_t* jack_create_adapter(jack_nframes_t host_buffer_size, +jack_adapter_t* jack_create_adapter(int input, int output, + jack_nframes_t host_buffer_size, jack_nframes_t host_sample_rate, jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_sample_rate); @@ -268,32 +269,18 @@ jack_adapter_t* jack_create_adapter(jack_nframes_t host_buffer_size, int jack_destroy_adapter(jack_adapter_t* adapter); /** - * Push input to ringbuffer + * Push input to and pull output from ringbuffer * * @return 0 on success, otherwise a non-zero error code */ -int jack_adapter_push_input(jack_adapter_t * adapter, int channels, float** buffers); +int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); /** - * Pull input from ringbuffer + * Pull input to and push output from ringbuffer * * @return 0 on success, otherwise a non-zero error code */ -int jack_adapter_pull_input(jack_adapter_t * adapter, int channels, float** buffers); - -/** - * Push output to ringbuffer - * - * @return error code. - */ -int jack_adapter_push_output(jack_adapter_t * adapter, int channels, float** buffers); - -/** - * Pull output from ringbuffer - * - * @return 0 on success, otherwise a non-zero error code - */ -int jack_adapter_pull_output(jack_adapter_t * adapter, int channels, float** buffers); +int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); #ifdef __cplusplus diff --git a/common/wscript b/common/wscript index 0156c274..adddc27a 100644 --- a/common/wscript +++ b/common/wscript @@ -182,9 +182,15 @@ def build(bld): netlib.includes = includes netlib.name = 'netlib' netlib.target = 'jacknet' - netlib.uselib = uselib + netlib.uselib = 'SAMPLERATE' netlib.install_path = '${LIBDIR}' - netlib.source = ['JackNetAPI.cpp', 'JackNetInterface.cpp', 'JackNetTool.cpp', 'JackAudioAdapterInterface.cpp', 'JackResampler.cpp', 'ringbuffer.c'] + netlib.source = ['JackNetAPI.cpp', + 'JackNetInterface.cpp', + 'JackNetTool.cpp', + 'JackAudioAdapterInterface.cpp', + 'JackLibSampleRateResampler.cpp', + 'JackResampler.cpp', + 'ringbuffer.c'] if bld.env['IS_LINUX']: netlib.source += ['../posix/JackNetUnixSocket.cpp','../posix/JackPosixThread.cpp', '../linux/JackLinuxTime.c'] diff --git a/linux/alsa/JackAlsaAdapter.cpp b/linux/alsa/JackAlsaAdapter.cpp index 66de67af..b12e4ccd 100644 --- a/linux/alsa/JackAlsaAdapter.cpp +++ b/linux/alsa/JackAlsaAdapter.cpp @@ -66,14 +66,19 @@ namespace Jack fAudioInterface.fCardName = strdup ( param->value.str ); break; case 'r': + fAudioInterface.fFrequency = param->value.ui; SetAdaptedSampleRate ( param->value.ui ); break; case 'p': + fAudioInterface.fBuffering = param->value.ui; SetAdaptedBufferSize ( param->value.ui ); break; case 'q': fQuality = param->value.ui; break; + case 'g': + fRingbufferSize = param->value.ui; + break; } } @@ -106,7 +111,7 @@ namespace Jack int JackAlsaAdapter::Close() { #ifdef JACK_MONITOR - fTable.Save(); + fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize); #endif switch ( fThread.GetStatus() ) { @@ -147,46 +152,15 @@ namespace Jack bool JackAlsaAdapter::Execute() { //read data from audio interface - if ( fAudioInterface.read() < 0 ) + if (fAudioInterface.read() < 0) return false; - - bool failure = false; - - //compute resampling factor - jack_nframes_t time1, time2; - ResampleFactor ( time1, time2 ); - - //resample inputs - for ( int i = 0; i < fCaptureChannels; i++ ) - { - fCaptureRingBuffer[i]->SetRatio ( time1, time2 ); - if ( fCaptureRingBuffer[i]->WriteResample ( fAudioInterface.fInputSoftChannels[i], fAdaptedBufferSize ) < fAdaptedBufferSize ) - failure = true; - } - //resample outputs - for ( int i = 0; i < fPlaybackChannels; i++ ) - { - fPlaybackRingBuffer[i]->SetRatio ( time2, time1 ); - if ( fPlaybackRingBuffer[i]->ReadResample ( fAudioInterface.fOutputSoftChannels[i], fAdaptedBufferSize ) < fAdaptedBufferSize ) - failure = true; - } - -#ifdef JACK_MONITOR - fTable.Write ( time1, time2, double ( time1 ) / double ( time2 ), double ( time2 ) / double ( time1 ), - fCaptureRingBuffer[0]->ReadSpace(), fPlaybackRingBuffer[0]->WriteSpace() ); -#endif + + PushAndPull(fAudioInterface.fInputSoftChannels, fAudioInterface.fOutputSoftChannels, fAdaptedBufferSize); //write data to audio interface - if ( fAudioInterface.write() < 0 ) + if (fAudioInterface.write() < 0) return false; - //reset all ringbuffers in case of failure - if ( failure ) - { - jack_error ( "JackAlsaAdapter::Execute ringbuffer failure... reset" ); - ResetRingBuffers(); - } - return true; } @@ -220,7 +194,7 @@ extern "C" strcpy ( desc->name, "audioadapter" ); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy ( desc->desc, "netjack audio <==> net backend adapter" ); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - desc->nparams = 10; + desc->nparams = 11; desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) ); i = 0; @@ -299,7 +273,6 @@ extern "C" strcpy ( desc->params[i].short_desc, "Number of playback channels (defaults to hardware max)" ); strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); - i++; strcpy(desc->params[i].name, "quality"); @@ -308,6 +281,14 @@ extern "C" desc->params[i].value.ui = 0; strcpy(desc->params[i].short_desc, "Resample algorithm quality (0 - 4)"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy(desc->params[i].name, "ring-buffer"); + desc->params[i].character = 'g'; + desc->params[i].type = JackDriverParamInt; + desc->params[i].value.ui = 0; + strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 32768)"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); return desc; } diff --git a/linux/alsa/JackAlsaAdapter.h b/linux/alsa/JackAlsaAdapter.h index 65431db2..8cdde0ee 100644 --- a/linux/alsa/JackAlsaAdapter.h +++ b/linux/alsa/JackAlsaAdapter.h @@ -182,6 +182,17 @@ namespace Jack fInputParams = 0; fOutputParams = 0; fPeriod = 2; + + fInputCardBuffer = 0; + fOutputCardBuffer = 0; + + for ( int i = 0; i < 256; i++ ) + { + fInputCardChannels[i] = 0; + fOutputCardChannels[i] = 0; + fInputSoftChannels[i] = 0; + fOutputSoftChannels[i] = 0; + } } AudioInterface ( jack_nframes_t buffer_size, jack_nframes_t sample_rate ) : @@ -369,10 +380,10 @@ namespace Jack } else // SND_PCM_FORMAT_S32 { - long* buffer32b = ( long* ) fInputCardBuffer; + int32_t* buffer32b = ( int32_t* ) fInputCardBuffer; for ( s = 0; s < fBuffering; s++ ) for ( c = 0; c < fCardInputs; c++ ) - fInputSoftChannels[c][s] = float ( buffer32b[c + s*fCardInputs] ) * ( 1.0/float ( LONG_MAX ) ); + fInputSoftChannels[c][s] = float ( buffer32b[c + s*fCardInputs] ) * ( 1.0/float ( INT_MAX ) ); } break; case SND_PCM_ACCESS_RW_NONINTERLEAVED : @@ -394,12 +405,12 @@ namespace Jack } else // SND_PCM_FORMAT_S32 { - long* chan32b; + int32_t* chan32b; for ( c = 0; c < fCardInputs; c++ ) { - chan32b = ( long* ) fInputCardChannels[c]; + chan32b = ( int32_t* ) fInputCardChannels[c]; for ( s = 0; s < fBuffering; s++ ) - fInputSoftChannels[c][s] = float ( chan32b[s] ) * ( 1.0/float ( LONG_MAX ) ); + fInputSoftChannels[c][s] = float ( chan32b[s] ) * ( 1.0/float ( INT_MAX ) ); } } break; @@ -436,13 +447,13 @@ namespace Jack } else // SND_PCM_FORMAT_S32 { - long* buffer32b = ( long* ) fOutputCardBuffer; + int32_t* buffer32b = ( int32_t* ) fOutputCardBuffer; for ( f = 0; f < fBuffering; f++ ) { for ( unsigned int c = 0; c < fCardOutputs; c++ ) { float x = fOutputSoftChannels[c][f]; - buffer32b[c + f * fCardOutputs] = long ( max ( min ( x, 1.0 ), -1.0 ) * float ( LONG_MAX ) ); + buffer32b[c + f * fCardOutputs] = int32_t ( max ( min ( x, 1.0 ), -1.0 ) * float ( INT_MAX ) ); } } } @@ -472,11 +483,11 @@ namespace Jack { for ( c = 0; c < fCardOutputs; c++ ) { - long* chan32b = ( long* ) fOutputCardChannels[c]; + int32_t* chan32b = ( int32_t* ) fOutputCardChannels[c]; for ( f = 0; f < fBuffering; f++ ) { float x = fOutputSoftChannels[c][f]; - chan32b[f] = long ( max ( min ( x,1.0 ),-1.0 ) * float ( LONG_MAX ) ) ; + chan32b[f] = int32_t ( max ( min ( x,1.0 ),-1.0 ) * float ( INT_MAX ) ) ; } } } diff --git a/macosx/coreaudio/JackCoreAudioAdapter.cpp b/macosx/coreaudio/JackCoreAudioAdapter.cpp index f222e3e9..18882f9b 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.cpp +++ b/macosx/coreaudio/JackCoreAudioAdapter.cpp @@ -293,38 +293,22 @@ OSStatus JackCoreAudioAdapter::Render(void *inRefCon, { JackCoreAudioAdapter* adapter = static_cast(inRefCon); AudioUnitRender(adapter->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, adapter->fInputData); - bool failure = false; - - jack_nframes_t time1, time2; - adapter->ResampleFactor(time1, time2); - + + float* inputBuffer[adapter->fCaptureChannels]; + float* outputBuffer[adapter->fPlaybackChannels]; + for (int i = 0; i < adapter->fCaptureChannels; i++) { - adapter->fCaptureRingBuffer[i]->SetRatio(time1, time2); - if (adapter->fCaptureRingBuffer[i]->WriteResample((float*)adapter->fInputData->mBuffers[i].mData, inNumberFrames) < inNumberFrames) - failure = true; + inputBuffer[i] = (float*)adapter->fInputData->mBuffers[i].mData; } - for (int i = 0; i < adapter->fPlaybackChannels; i++) { - adapter->fPlaybackRingBuffer[i]->SetRatio(time2, time1); - if (adapter->fPlaybackRingBuffer[i]->ReadResample((float*)ioData->mBuffers[i].mData, inNumberFrames) < inNumberFrames) - failure = true; - } - -#ifdef JACK_MONITOR - adapter->fTable.Write(time1, time2, double(time1) / double(time2), double(time2) / double(time1), - adapter->fCaptureRingBuffer[0]->ReadSpace(), adapter->fPlaybackRingBuffer[0]->WriteSpace()); -#endif - - // Reset all ringbuffers in case of failure - if (failure) { - jack_error("JackCoreAudioAdapter::Render ringbuffer failure... reset"); - adapter->ResetRingBuffers(); + outputBuffer[i] = (float*)ioData->mBuffers[i].mData; } - + + adapter->PushAndPull((float**)inputBuffer, (float**)outputBuffer, inNumberFrames); return noErr; } - JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params) +JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params) :JackAudioAdapterInterface(buffer_size, sample_rate), fInputData(0), fCapturing(false), fPlaying(false), fState(false) { @@ -392,6 +376,10 @@ OSStatus JackCoreAudioAdapter::Render(void *inRefCon, case 'q': fQuality = param->value.ui; break; + + case 'g': + fRingbufferSize = param->value.ui; + break; } } @@ -960,7 +948,7 @@ int JackCoreAudioAdapter::Open() int JackCoreAudioAdapter::Close() { #ifdef JACK_MONITOR - fTable.Save(); + fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize); #endif AudioOutputUnitStop(fAUHAL); DisposeBuffers(); @@ -997,7 +985,7 @@ extern "C" strcpy(desc->name, "audioadapter"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy(desc->desc, "netjack audio <==> net backend adapter"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - desc->nparams = 11; + desc->nparams = 12; desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); i = 0; @@ -1087,6 +1075,14 @@ extern "C" desc->params[i].value.ui = 0; strcpy(desc->params[i].short_desc, "Resample algorithm quality (0 - 4)"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy(desc->params[i].name, "ring-buffer"); + desc->params[i].character = 'g'; + desc->params[i].type = JackDriverParamInt; + desc->params[i].value.ui = 0; + strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 32768)"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); return desc; } diff --git a/solaris/oss/JackOSSAdapter.cpp b/solaris/oss/JackOSSAdapter.cpp index e74b7430..69a59ec7 100644 --- a/solaris/oss/JackOSSAdapter.cpp +++ b/solaris/oss/JackOSSAdapter.cpp @@ -181,6 +181,10 @@ JackOSSAdapter::JackOSSAdapter(jack_nframes_t buffer_size, jack_nframes_t sample case 'q': fQuality = param->value.ui; break; + + case 'g': + fRingbufferSize = param->value.ui; + break; } } @@ -502,10 +506,9 @@ error: int JackOSSAdapter::Close() { -#ifdef DEBUG - fTable.Save(); +#ifdef JACK_MONITOR + fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize); #endif - fThread.Stop(); CloseAux(); return 0; @@ -600,38 +603,16 @@ int JackOSSAdapter::Write() bool JackOSSAdapter::Execute() { + //read data from audio interface if (Read() < 0) return false; - - bool failure = false; - jack_nframes_t time1, time2; - ResampleFactor(time1, time2); - - for (int i = 0; i < fCaptureChannels; i++) { - fCaptureRingBuffer[i]->SetRatio(time1, time2); - if (fCaptureRingBuffer[i]->WriteResample(fInputSampleBuffer[i], fAdaptedBufferSize) < fAdaptedBufferSize) - failure = true; - } - - for (int i = 0; i < fPlaybackChannels; i++) { - fPlaybackRingBuffer[i]->SetRatio(time2, time1); - if (fPlaybackRingBuffer[i]->ReadResample(fOutputSampleBuffer[i], fAdaptedBufferSize) < fAdaptedBufferSize) - failure = true; - } - -#ifdef DEBUG - fTable.Write(time1, time2, double(time1) / double(time2), double(time2) / double(time1), - fCaptureRingBuffer[0]->ReadSpace(), fPlaybackRingBuffer[0]->WriteSpace()); -#endif + PushAndPull(fInputSampleBuffer, fOutputSampleBuffer, fAdaptedBufferSize); + + //write data to audio interface if (Write() < 0) return false; - - // Reset all ringbuffers in case of failure - if (failure) { - jack_error("JackOSSAdapter::Execute ringbuffer failure... reset"); - ResetRingBuffers(); - } + return true; } @@ -756,6 +737,14 @@ extern "C" desc->params[i].value.ui = 0; strcpy(desc->params[i].short_desc, "Resample algorithm quality (0 - 4)"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy(desc->params[i].name, "ring-buffer"); + desc->params[i].character = 'g'; + desc->params[i].type = JackDriverParamInt; + desc->params[i].value.ui = 0; + strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 32768)"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); return desc; } diff --git a/solaris/oss/JackOSSAdapter.h b/solaris/oss/JackOSSAdapter.h index 1a6dbe21..6e739f88 100644 --- a/solaris/oss/JackOSSAdapter.h +++ b/solaris/oss/JackOSSAdapter.h @@ -34,7 +34,7 @@ namespace Jack typedef jack_default_audio_sample_t jack_sample_t; -#define OSS_DRIVER_N_PARAMS 12 +#define OSS_DRIVER_N_PARAMS 13 #define OSS_DRIVER_DEF_DEV "/dev/dsp" #define OSS_DRIVER_DEF_FS 48000 #define OSS_DRIVER_DEF_BLKSIZE 1024 diff --git a/windows/portaudio/JackPortAudioAdapter.cpp b/windows/portaudio/JackPortAudioAdapter.cpp index 2f3ba46e..a5beb232 100644 --- a/windows/portaudio/JackPortAudioAdapter.cpp +++ b/windows/portaudio/JackPortAudioAdapter.cpp @@ -27,47 +27,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { - int JackPortAudioAdapter::Render ( const void* inputBuffer, - void* outputBuffer, - unsigned long framesPerBuffer, - const PaStreamCallbackTimeInfo* timeInfo, - PaStreamCallbackFlags statusFlags, - void* userData) + int JackPortAudioAdapter::Render(const void* inputBuffer, + void* outputBuffer, + unsigned long framesPerBuffer, + const PaStreamCallbackTimeInfo* timeInfo, + PaStreamCallbackFlags statusFlags, + void* userData) { JackPortAudioAdapter* adapter = static_cast(userData); - float** paBuffer; - bool failure = false; - - jack_nframes_t time1, time2; - adapter->ResampleFactor ( time1, time2 ); - - paBuffer = (float**)inputBuffer; - for ( int i = 0; i < adapter->fCaptureChannels; i++ ) - { - adapter->fCaptureRingBuffer[i]->SetRatio ( time1, time2 ); - if (adapter->fCaptureRingBuffer[i]->WriteResample ( (float*)paBuffer[i], framesPerBuffer ) < framesPerBuffer ) - failure = true; - } - - paBuffer = (float**)outputBuffer; - for ( int i = 0; i < adapter->fPlaybackChannels; i++ ) - { - adapter->fPlaybackRingBuffer[i]->SetRatio ( time2, time1 ); - if ( adapter->fPlaybackRingBuffer[i]->ReadResample ( (float*)paBuffer[i], framesPerBuffer ) < framesPerBuffer ) - failure = true; - } - -#ifdef JACK_MONITOR - adapter->fTable.Write ( time1, time2, double(time1) / double(time2), double(time2) / double(time1), - adapter->fCaptureRingBuffer[0]->ReadSpace(), adapter->fPlaybackRingBuffer[0]->WriteSpace() ); -#endif - - // Reset all ringbuffers in case of failure - if ( failure ) - { - jack_error ( "JackPortAudioAdapter::Render ringbuffer failure... reset" ); - adapter->ResetRingBuffers(); - } + adapter->PushAndPull((float**)inputBuffer, (float**)outputBuffer, framesPerBuffer); return paContinue; } @@ -128,6 +96,9 @@ namespace Jack case 'q': fQuality = param->value.ui; break; + case 'g': + fRingbufferSize = param->value.ui; + break; } } @@ -207,7 +178,7 @@ namespace Jack int JackPortAudioAdapter::Close() { #ifdef JACK_MONITOR - fTable.Save(); + fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize); #endif jack_log ( "JackPortAudioAdapter::Close" ); Pa_StopStream ( fStream ); @@ -246,8 +217,8 @@ extern "C" strcpy(desc->name, "audioadapter"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy(desc->desc, "netjack audio <==> net backend adapter"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - - desc->nparams = 9; + + desc->nparams = 10; desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); i = 0; @@ -314,7 +285,7 @@ extern "C" desc->params[i].value.i = TRUE; strcpy(desc->params[i].short_desc, "Display available PortAudio devices"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); - + i++; strcpy(desc->params[i].name, "quality"); desc->params[i].character = 'q'; @@ -323,6 +294,14 @@ extern "C" strcpy(desc->params[i].short_desc, "Resample algorithm quality (0 - 4)"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + i++; + strcpy(desc->params[i].name, "ring-buffer"); + desc->params[i].character = 'g'; + desc->params[i].type = JackDriverParamInt; + desc->params[i].value.ui = 0; + strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 32768)"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + return desc; }