diff --git a/ChangeLog b/ChangeLog index e23d51ba..f650afa5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,12 +17,21 @@ Nedko Arnaudov Fernando Lopez-Lezcano Romain Moret Florian Faber -Michael Voigt +Michael Voigt +Torben Hohn --------------------------- Jackdmp changes log --------------------------- +2009-03-10 Stephane Letz + + * Add -g (ring-buffer) parameter to netadapter. + +2009-03-09 Stephane Letz + + * Use Torben Hohn PI controler code for adapters (in progress). + 2009-03-05 Stephane Letz * Support for BIG_ENDIAN machines in NetJack2 for transport data. diff --git a/common/JackAudioAdapterInterface.cpp b/common/JackAudioAdapterInterface.cpp index 0e666f3b..364e70f5 100644 --- a/common/JackAudioAdapterInterface.cpp +++ b/common/JackAudioAdapterInterface.cpp @@ -58,6 +58,7 @@ namespace Jack } fclose(file); + /* No used for now // Adapter timing 1 file = fopen("AdapterTiming1.plot", "w"); fprintf(file, "set multiplot\n"); @@ -88,6 +89,7 @@ namespace Jack fprintf(file, buffer); fclose(file); + */ // Adapter timing 2 file = fopen("AdapterTiming2.plot", "w"); @@ -162,30 +164,7 @@ namespace Jack fPlaybackRingBuffer[i]->Reset(); } - void JackAudioAdapterInterface::ResampleFactor ( jack_time_t& frame1, jack_time_t& frame2 ) - { - jack_time_t time = GetMicroSeconds(); - - if (!fRunning) { - // Init DLL - fRunning = true; - fHostDLL.Init(time); - fAdaptedDLL.Init(time); - frame1 = 1; - frame2 = 1; - } else { - // DLL - fAdaptedDLL.IncFrame(time); - jack_nframes_t time1 = fHostDLL.Time2Frames(time); - jack_nframes_t time2 = fAdaptedDLL.Time2Frames(time); - frame1 = time1; - frame2 = time2; - jack_log("JackAudioAdapterInterface::ResampleFactor time1 = %ld time2 = %ld src_ratio_input = %f src_ratio_output = %f", - long(time1), long(time2), double(time1) / double(time2), double(time2) / double(time1)); - } - } - - void JackAudioAdapterInterface::Reset() + void JackAudioAdapterInterface::Reset() { ResetRingBuffers(); fRunning = false; @@ -226,25 +205,31 @@ namespace Jack int JackAudioAdapterInterface::PushAndPull(float** inputBuffer, float** outputBuffer, unsigned int frames) { bool failure = false; - jack_time_t time1, time2; - ResampleFactor(time1, time2); - + fRunning = true; + + /* + Finer estimation of the position in the ringbuffer ?? + int delta_frames = (int)(float(long(GetMicroSeconds() - fPullAndPushTime)) * float(fAdaptedSampleRate)) / 1000000.f; + double ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetOffset() - delta_frames); + */ + + double ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetOffset()); + // Push/pull from ringbuffer for (int i = 0; i < fCaptureChannels; i++) { - fCaptureRingBuffer[i]->SetRatio(time1, time2); + fCaptureRingBuffer[i]->SetRatio(ratio); if (fCaptureRingBuffer[i]->WriteResample(inputBuffer[i], frames) < frames) failure = true; } for (int i = 0; i < fPlaybackChannels; i++) { - fPlaybackRingBuffer[i]->SetRatio(time2, time1); + fPlaybackRingBuffer[i]->SetRatio(1 / ratio); 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()); + fTable.Write(0, 0, ratio, 1/ratio, fCaptureRingBuffer[0]->ReadSpace(), fPlaybackRingBuffer[0]->WriteSpace()); #endif // Reset all ringbuffers in case of failure @@ -260,8 +245,8 @@ namespace Jack int JackAudioAdapterInterface::PullAndPush(float** inputBuffer, float** outputBuffer, unsigned int frames) { bool failure = false; - fHostDLL.IncFrame(GetMicroSeconds()); - + fPullAndPushTime = GetMicroSeconds(); + // Push/pull from ringbuffer for (int i = 0; i < fCaptureChannels; i++) { if (fCaptureRingBuffer[i]->Read(inputBuffer[i], frames) < frames) diff --git a/common/JackAudioAdapterInterface.h b/common/JackAudioAdapterInterface.h index 4b06d0d3..e843a453 100644 --- a/common/JackAudioAdapterInterface.h +++ b/common/JackAudioAdapterInterface.h @@ -82,36 +82,34 @@ namespace Jack jack_nframes_t fAdaptedBufferSize; jack_nframes_t fAdaptedSampleRate; - //delay locked loop - JackAtomicDelayLockedLoop fHostDLL; - JackAtomicDelayLockedLoop fAdaptedDLL; + //PI controler + JackPIControler fPIControler; JackResampler** fCaptureRingBuffer; JackResampler** fPlaybackRingBuffer; unsigned int fQuality; unsigned int fRingbufferSize; + jack_time_t fPullAndPushTime; bool fRunning; void ResetRingBuffers(); - void ResampleFactor ( jack_time_t& frame1, jack_time_t& frame2 ); public: - JackAudioAdapterInterface ( jack_nframes_t host_buffer_size, - jack_nframes_t host_sample_rate) : - fCaptureChannels ( 0 ), - fPlaybackChannels ( 0 ), - fHostBufferSize ( host_buffer_size ), - fHostSampleRate ( host_sample_rate ), - fAdaptedBufferSize ( host_buffer_size), - fAdaptedSampleRate ( host_sample_rate ), - 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 buffer_size, jack_nframes_t sample_rate ): + fCaptureChannels ( 0 ), + fPlaybackChannels ( 0 ), + fHostBufferSize ( buffer_size ), + fHostSampleRate ( sample_rate ), + fAdaptedBufferSize ( buffer_size), + fAdaptedSampleRate ( sample_rate ), + fPIControler(sample_rate / sample_rate, 256), + fCaptureRingBuffer(NULL), fPlaybackRingBuffer(NULL), + fQuality(0), fRingbufferSize(DEFAULT_RB_SIZE), + fPullAndPushTime(0), + fRunning(false) {} JackAudioAdapterInterface ( jack_nframes_t host_buffer_size, jack_nframes_t host_sample_rate, @@ -123,10 +121,10 @@ namespace Jack fHostSampleRate ( host_sample_rate ), fAdaptedBufferSize ( adapted_buffer_size), fAdaptedSampleRate ( adapted_sample_rate ), - fHostDLL ( host_buffer_size, host_sample_rate ), - fAdaptedDLL ( adapted_buffer_size, adapted_sample_rate ), + fPIControler(host_sample_rate / host_sample_rate, 256), fQuality(0), fRingbufferSize(DEFAULT_RB_SIZE), + fPullAndPushTime(0), fRunning ( false ) {} @@ -156,14 +154,12 @@ namespace Jack virtual int SetHostBufferSize ( jack_nframes_t buffer_size ) { fHostBufferSize = buffer_size; - fHostDLL.Init ( fHostBufferSize, fHostSampleRate ); return 0; } virtual int SetAdaptedBufferSize ( jack_nframes_t buffer_size ) { fAdaptedBufferSize = buffer_size; - fAdaptedDLL.Init ( fAdaptedBufferSize, fAdaptedSampleRate ); return 0; } @@ -177,14 +173,14 @@ namespace Jack virtual int SetHostSampleRate ( jack_nframes_t sample_rate ) { fHostSampleRate = sample_rate; - fHostDLL.Init ( fHostBufferSize, fHostSampleRate ); + fPIControler.Init(double(fHostSampleRate) / double(fAdaptedSampleRate)); return 0; } virtual int SetAdaptedSampleRate ( jack_nframes_t sample_rate ) { fAdaptedSampleRate = sample_rate; - fAdaptedDLL.Init ( fAdaptedBufferSize, fAdaptedSampleRate ); + fPIControler.Init(double(fHostSampleRate) / double(fAdaptedSampleRate)); return 0; } diff --git a/common/JackEngineProfiling.h b/common/JackEngineProfiling.h index 71abca1b..bc82627f 100644 --- a/common/JackEngineProfiling.h +++ b/common/JackEngineProfiling.h @@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -#define TIME_POINTS 250000 +#define TIME_POINTS 125000 #define FAILURE_TIME_POINTS 10000 #define FAILURE_WINDOW 10 #define MEASURED_CLIENTS 32 diff --git a/common/JackFilters.h b/common/JackFilters.h index a7fb3366..dada7204 100644 --- a/common/JackFilters.h +++ b/common/JackFilters.h @@ -23,6 +23,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "jack.h" #include "JackAtomicState.h" #include +#include namespace Jack { @@ -201,6 +202,117 @@ namespace Jack return res; } }; + + /* + Torben Hohn PI controler from JACK1 + */ + + struct JackPIControler { + + double resample_mean; + double static_resample_factor; + + double* offset_array; + double* window_array; + int offset_differential_index; + + double offset_integral; + + double catch_factor; + double catch_factor2; + double pclamp; + double controlquant; + int smooth_size; + + double hann(double x) + { + return 0.5 * (1.0 - cos(2 * M_PI * x)); + } + + JackPIControler(double resample_factor, int fir_size) + { + resample_mean = resample_factor; + static_resample_factor = resample_factor; + offset_array = new double[fir_size]; + window_array = new double[fir_size]; + offset_differential_index = 0; + offset_integral = 0.0; + smooth_size = fir_size; + + for (int i = 0; i < fir_size; i++) { + offset_array[i] = 0.0; + window_array[i] = hann(double(i) / (double(fir_size) - 1.0)); + } + + // These values could be configurable + catch_factor = 100000; + catch_factor2 = 10000; + pclamp = 15.0; + controlquant = 10000.0; + } + + ~JackPIControler() + { + delete[] offset_array; + delete[] window_array; + } + + void Init(double resample_factor) + { + resample_mean = resample_factor; + static_resample_factor = resample_factor; + } + + double GetRatio(int fill_level) + { + double offset = fill_level; + + // Save offset. + offset_array[(offset_differential_index++) % smooth_size] = offset; + + // Build the mean of the windowed offset array basically fir lowpassing. + double smooth_offset = 0.0; + for (int i = 0; i < smooth_size; i++) { + smooth_offset += offset_array[(i + offset_differential_index - 1) % smooth_size] * window_array[i]; + } + smooth_offset /= double(smooth_size); + + // This is the integral of the smoothed_offset + offset_integral += smooth_offset; + + // Clamp offset : the smooth offset still contains unwanted noise which would go straigth onto the resample coeff. + // It only used in the P component and the I component is used for the fine tuning anyways. + if (fabs(smooth_offset) < pclamp) + smooth_offset = 0.0; + + // Ok, now this is the PI controller. + // u(t) = K * (e(t) + 1/T \int e(t') dt') + // Kp = 1/catch_factor and T = catch_factor2 Ki = Kp/T + double current_resample_factor + = static_resample_factor - smooth_offset / catch_factor - offset_integral / catch_factor / catch_factor2; + + // Now quantize this value around resample_mean, so that the noise which is in the integral component doesnt hurt. + current_resample_factor = floor((current_resample_factor - resample_mean) * controlquant + 0.5) / controlquant + resample_mean; + + // Calculate resample_mean so we can init ourselves to saner values. + resample_mean = 0.9999 * resample_mean + 0.0001 * current_resample_factor; + return current_resample_factor; + } + + void OurOfBounds() + { + int i; + // Set the resample_rate... we need to adjust the offset integral, to do this. + // first look at the PI controller, this code is just a special case, which should never execute once + // everything is swung in. + offset_integral = - (resample_mean - static_resample_factor) * catch_factor * catch_factor2; + // Also clear the array. we are beginning a new control cycle. + for (i = 0; i < smooth_size; i++) { + offset_array[i] = 0.0; + } + } + + }; } diff --git a/common/JackGraphManager.cpp b/common/JackGraphManager.cpp index 922b9b5b..c34ea5d4 100644 --- a/common/JackGraphManager.cpp +++ b/common/JackGraphManager.cpp @@ -542,7 +542,7 @@ int JackGraphManager::Connect(jack_port_id_t port_src, jack_port_id_t port_dst) jack_error("JackGraphManager::Connect failed port_src = %ld port_dst = %ld", port_src, port_dst); goto end; } - manager->Connect(port_dst, port_src); + res = manager->Connect(port_dst, port_src); if (res < 0) { jack_error("JackGraphManager::Connect failed port_dst = %ld port_src = %ld", port_dst, port_src); goto end; @@ -583,12 +583,12 @@ int JackGraphManager::Disconnect(jack_port_id_t port_src, jack_port_id_t port_ds goto end; } - manager->Disconnect(port_src, port_dst); + res = manager->Disconnect(port_src, port_dst); if (res < 0) { jack_error("JackGraphManager::Disconnect failed port_src = %ld port_dst = %ld", port_src, port_dst); goto end; } - manager->Disconnect(port_dst, port_src); + res = manager->Disconnect(port_dst, port_src); if (res < 0) { jack_error("JackGraphManager::Disconnect failed port_dst = %ld port_src = %ld", port_dst, port_src); goto end; diff --git a/common/JackLibSampleRateResampler.cpp b/common/JackLibSampleRateResampler.cpp index a2dfb472..e2486749 100644 --- a/common/JackLibSampleRateResampler.cpp +++ b/common/JackLibSampleRateResampler.cpp @@ -23,7 +23,7 @@ namespace Jack { JackLibSampleRateResampler::JackLibSampleRateResampler() - :JackResampler(),fRatio(1) + :JackResampler() { int error; fResampler = src_new(SRC_LINEAR, 1, &error); @@ -32,7 +32,7 @@ JackLibSampleRateResampler::JackLibSampleRateResampler() } JackLibSampleRateResampler::JackLibSampleRateResampler(unsigned int quality, unsigned int ringbuffer_size) - :JackResampler(ringbuffer_size),fRatio(1) + :JackResampler(ringbuffer_size) { switch (quality) { case 0: diff --git a/common/JackLibSampleRateResampler.h b/common/JackLibSampleRateResampler.h index bbb85cba..3abc1619 100644 --- a/common/JackLibSampleRateResampler.h +++ b/common/JackLibSampleRateResampler.h @@ -26,11 +26,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { -inline float Range(float min, float max, float val) -{ - return (val < min) ? min : ((val > max) ? max : val); -} - /*! \brief Resampler using "libsamplerate" (http://www.mega-nerd.com/SRC/). */ @@ -41,7 +36,6 @@ class JackLibSampleRateResampler : public JackResampler private: SRC_STATE* fResampler; - double fRatio; public: @@ -51,12 +45,6 @@ class JackLibSampleRateResampler : public JackResampler unsigned int ReadResample(float* buffer, unsigned int frames); unsigned int WriteResample(float* buffer, unsigned int frames); - - void SetRatio(unsigned int num, unsigned int denom) - { - JackResampler::SetRatio(num, denom); - fRatio = Range(0.25, 4.0, (double(num) / double(denom))); - } void Reset(); diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index 2ce50cbf..f5512eb5 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -95,6 +95,9 @@ namespace Jack case 'q': fQuality = param->value.ui; break; + case 'g': + fRingbufferSize = param->value.ui; + break; } } @@ -151,6 +154,10 @@ namespace Jack { jack_log ( "JackNetAdapter::Close" ); +#ifdef JACK_MONITOR + fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize); +#endif + switch ( fThread.GetStatus() ) { // Kill the thread in Init phase @@ -386,7 +393,7 @@ extern "C" strcpy(desc->name, "netadapter"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy(desc->desc, "netjack net <==> audio 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 ) ); int i = 0; @@ -414,7 +421,7 @@ extern "C" strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); i++; - strcpy ( desc->params[i].name, "input_ports" ); + strcpy ( desc->params[i].name, "input-ports" ); desc->params[i].character = 'C'; desc->params[i].type = JackDriverParamInt; desc->params[i].value.i = 2; @@ -422,7 +429,7 @@ extern "C" strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); i++; - strcpy ( desc->params[i].name, "output_ports" ); + strcpy ( desc->params[i].name, "output-ports" ); desc->params[i].character = 'P'; desc->params[i].type = JackDriverParamInt; desc->params[i].value.i = 2; @@ -430,7 +437,7 @@ extern "C" strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); i++; - strcpy ( desc->params[i].name, "client_name" ); + strcpy ( desc->params[i].name, "client-name" ); desc->params[i].character = 'n'; desc->params[i].type = JackDriverParamString; strcpy ( desc->params[i].value.str, "'hostname'" ); @@ -438,7 +445,7 @@ extern "C" strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); i++; - strcpy ( desc->params[i].name, "transport_sync" ); + strcpy ( desc->params[i].name, "transport-sync" ); desc->params[i].character = 't'; desc->params[i].type = JackDriverParamUInt; desc->params[i].value.ui = 1U; @@ -462,13 +469,21 @@ extern "C" strcpy(desc->params[i].long_desc, desc->params[i].short_desc); i++; - strcpy ( desc->params[i].name, "auto_connect" ); + 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 = 16384)"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy ( desc->params[i].name, "auto-connect" ); desc->params[i].character = 'c'; desc->params[i].type = JackDriverParamBool; desc->params[i].value.i = false; strcpy ( desc->params[i].short_desc, "Auto connect netmaster to system ports" ); strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); - + return desc; } diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index b35af904..0d63f33d 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -421,14 +421,14 @@ namespace Jack dst_params->fPosition.beat = htonl(src_params->fPosition.beat); dst_params->fPosition.tick = htonl(src_params->fPosition.tick); dst_params->fPosition.bar_start_tick = htonll((uint64_t)src_params->fPosition.bar_start_tick); - dst_params->fPosition.beats_per_bar = htonl(src_params->fPosition.beats_per_bar); - dst_params->fPosition.beat_type = htonl(src_params->fPosition.beat_type); + dst_params->fPosition.beats_per_bar = htonl((uint32_t)src_params->fPosition.beats_per_bar); + dst_params->fPosition.beat_type = htonl((uint32_t)src_params->fPosition.beat_type); dst_params->fPosition.ticks_per_beat = htonll((uint64_t)src_params->fPosition.ticks_per_beat); dst_params->fPosition.beats_per_minute = htonll((uint64_t)src_params->fPosition.beats_per_minute); dst_params->fPosition.frame_time = htonll((uint64_t)src_params->fPosition.frame_time); dst_params->fPosition.next_time = htonll((uint64_t)src_params->fPosition.next_time); dst_params->fPosition.bbt_offset = htonl(src_params->fPosition.bbt_offset); - dst_params->fPosition.audio_frames_per_video_frame = htonl(src_params->fPosition.audio_frames_per_video_frame); + dst_params->fPosition.audio_frames_per_video_frame = htonl((uint32_t)src_params->fPosition.audio_frames_per_video_frame); dst_params->fPosition.video_offset = htonl(src_params->fPosition.video_offset); dst_params->fPosition.unique_2 = htonll(src_params->fPosition.unique_2); } @@ -446,14 +446,14 @@ namespace Jack dst_params->fPosition.beat = ntohl(src_params->fPosition.beat); dst_params->fPosition.tick = ntohl(src_params->fPosition.tick); dst_params->fPosition.bar_start_tick = ntohll((uint64_t)src_params->fPosition.bar_start_tick); - dst_params->fPosition.beats_per_bar = ntohl(src_params->fPosition.beats_per_bar); - dst_params->fPosition.beat_type = ntohl(src_params->fPosition.beat_type); + dst_params->fPosition.beats_per_bar = ntohl((uint32_t)src_params->fPosition.beats_per_bar); + dst_params->fPosition.beat_type = ntohl((uint32_t)src_params->fPosition.beat_type); dst_params->fPosition.ticks_per_beat = ntohll((uint64_t)src_params->fPosition.ticks_per_beat); dst_params->fPosition.beats_per_minute = ntohll((uint64_t)src_params->fPosition.beats_per_minute); dst_params->fPosition.frame_time = ntohll((uint64_t)src_params->fPosition.frame_time); dst_params->fPosition.next_time = ntohll((uint64_t)src_params->fPosition.next_time); dst_params->fPosition.bbt_offset = ntohl(src_params->fPosition.bbt_offset); - dst_params->fPosition.audio_frames_per_video_frame = ntohl(src_params->fPosition.audio_frames_per_video_frame); + dst_params->fPosition.audio_frames_per_video_frame = ntohl((uint32_t)src_params->fPosition.audio_frames_per_video_frame); dst_params->fPosition.video_offset = ntohl(src_params->fPosition.video_offset); dst_params->fPosition.unique_2 = ntohll(src_params->fPosition.unique_2); } diff --git a/common/JackResampler.cpp b/common/JackResampler.cpp index 19945adf..86798d9e 100644 --- a/common/JackResampler.cpp +++ b/common/JackResampler.cpp @@ -23,13 +23,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { -JackResampler::JackResampler():fNum(1),fDenom(1) +JackResampler::JackResampler() + :fRatio(1),fRingBufferSize(DEFAULT_RB_SIZE) { - fRingBuffer = jack_ringbuffer_create(sizeof(float) * DEFAULT_RB_SIZE); - jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * DEFAULT_RB_SIZE) / 2); + fRingBuffer = jack_ringbuffer_create(sizeof(float) * fRingBufferSize); + jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * fRingBufferSize) / 2); } -JackResampler::JackResampler(unsigned int ringbuffer_size):fNum(1),fDenom(1),fRingBufferSize(ringbuffer_size) +JackResampler::JackResampler(unsigned int ringbuffer_size) + :fRatio(1),fRingBufferSize(ringbuffer_size) { fRingBuffer = jack_ringbuffer_create(sizeof(float) * fRingBufferSize); jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * fRingBufferSize) / 2); diff --git a/common/JackResampler.h b/common/JackResampler.h index fb6e30f2..d8d2e42c 100644 --- a/common/JackResampler.h +++ b/common/JackResampler.h @@ -26,8 +26,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { -#define DEFAULT_RB_SIZE 16384 * 2 +#define DEFAULT_RB_SIZE 16384 +inline float Range(float min, float max, float val) +{ + return (val < min) ? min : ((val > max) ? max : val); +} + /*! \brief Base class for Resampler. */ @@ -38,8 +43,7 @@ class JackResampler protected: jack_ringbuffer_t* fRingBuffer; - unsigned int fNum; - unsigned int fDenom; + double fRatio; unsigned int fRingBufferSize; public: @@ -58,16 +62,20 @@ class JackResampler virtual unsigned int ReadSpace(); virtual unsigned int WriteSpace(); + + unsigned int GetOffset() + { + return (jack_ringbuffer_read_space(fRingBuffer) / sizeof(float)) - (fRingBufferSize / 2); + } - virtual void SetRatio(unsigned int num, unsigned int denom) + void SetRatio(double ratio) { - fNum = num; - fDenom = denom; + fRatio = Range(0.25, 4.0, ratio); } - virtual void GetRatio(unsigned int& num, unsigned int& denom) + + double GetRatio() { - num = fNum; - denom = fDenom; + return fRatio; } }; diff --git a/common/memops.c b/common/memops.c index fff41f1f..520b3dc8 100644 --- a/common/memops.c +++ b/common/memops.c @@ -342,7 +342,7 @@ void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigne int i4 = *((int *) src); src+= src_skip; - __m128i src = _mm_set_epi32(i1, i2, i3, i4); + __m128i src = _mm_set_epi32(i4, i3, i2, i1); __m128i shifted = _mm_srai_epi32(src, 8); __m128 as_float = _mm_cvtepi32_ps(shifted); diff --git a/linux/alsa/JackAlsaAdapter.cpp b/linux/alsa/JackAlsaAdapter.cpp index b12e4ccd..0e9fb4ce 100644 --- a/linux/alsa/JackAlsaAdapter.cpp +++ b/linux/alsa/JackAlsaAdapter.cpp @@ -287,7 +287,7 @@ extern "C" 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].short_desc, "Resampling ringbuffer size in frames (default = 16384)"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); return desc; diff --git a/macosx/coreaudio/JackCoreAudioAdapter.cpp b/macosx/coreaudio/JackCoreAudioAdapter.cpp index 18882f9b..dd238b7b 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.cpp +++ b/macosx/coreaudio/JackCoreAudioAdapter.cpp @@ -377,7 +377,7 @@ JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nfra fQuality = param->value.ui; break; - case 'g': + case 'g': fRingbufferSize = param->value.ui; break; } @@ -1081,7 +1081,7 @@ extern "C" 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].short_desc, "Resampling ringbuffer size in frames (default = 16384)"); 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 69a59ec7..cbb3e549 100644 --- a/solaris/oss/JackOSSAdapter.cpp +++ b/solaris/oss/JackOSSAdapter.cpp @@ -743,7 +743,7 @@ extern "C" 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].short_desc, "Resampling ringbuffer size in frames (default = 16384)"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); return desc; diff --git a/windows/JackNetWinSocket.cpp b/windows/JackNetWinSocket.cpp index c154ea65..30420b49 100644 --- a/windows/JackNetWinSocket.cpp +++ b/windows/JackNetWinSocket.cpp @@ -286,7 +286,13 @@ namespace Jack //local loop********************************************************************************************************* int JackNetWinSocket::SetLocalLoop() { - char disable = 0; + //char disable = 0; + /* + see http://msdn.microsoft.com/en-us/library/aa916098.aspx + Default value is TRUE. When TRUE, data that is sent from the local interface to the multicast group to + which the socket is joined, including data sent from the same socket, will be echoed to its receive buffer. + */ + char disable = 1; return SetOption ( IPPROTO_IP, IP_MULTICAST_LOOP, &disable, sizeof ( disable ) ); } diff --git a/windows/Setup/src/README b/windows/Setup/src/README index eef08432..eafc21ae 100644 --- a/windows/Setup/src/README +++ b/windows/Setup/src/README @@ -50,10 +50,10 @@ JackRouter is an ASIO driver that allows any ASIO compatible application to beco ============================================= -Known problems: +Known problems ============================================= -- starting/stopping the server several times in QJACKCTL does not work correctly. You'll have to quit qjacckctl and launch it again. +- starting/stopping the server several times in QJACKCTL does not work correctly. You'll have to quit qjackctl and launch it again. ============================================= diff --git a/windows/portaudio/JackPortAudioAdapter.cpp b/windows/portaudio/JackPortAudioAdapter.cpp index a5beb232..17972e6b 100644 --- a/windows/portaudio/JackPortAudioAdapter.cpp +++ b/windows/portaudio/JackPortAudioAdapter.cpp @@ -299,7 +299,7 @@ extern "C" 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].short_desc, "Resampling ringbuffer size in frames (default = 16384)"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); return desc;