git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2592 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.90
| @@ -34,17 +34,26 @@ int JackCallbackNetIOAdapter::Process(jack_nframes_t frames, void* arg) | |||
| float* buffer; | |||
| int i; | |||
| /* | |||
| adapter->fLastCallbackTime = adapter->fCurCallbackTime; | |||
| adapter->fCurCallbackTime = jack_get_time(); | |||
| */ | |||
| if (!adapter->fIOAdapter->IsRunning()) | |||
| return 0; | |||
| adapter->fIOAdapter->SetCallbackDeltaTime(adapter->fCurCallbackTime - adapter->fLastCallbackTime); | |||
| // adapter->fIOAdapter->SetCallbackDeltaTime(adapter->fCurCallbackTime - adapter->fLastCallbackTime); | |||
| // DLL | |||
| adapter->fIOAdapter->SetCallbackTime(jack_get_time()); | |||
| //jack_info("ReadSpace = %ld", adapter->fCaptureRingBuffer[0].ReadSpace()); | |||
| //jack_info("WriteSpace = %ld", adapter->fPlaybackRingBuffer[0].WriteSpace()); | |||
| printf("ReadSpace = %ld\n", adapter->fCaptureRingBuffer[0].ReadSpace()); | |||
| printf("WriteSpace = %ld\n", adapter->fPlaybackRingBuffer[0].WriteSpace()); | |||
| for (i = 0; i < adapter->fCaptureChannels; i++) { | |||
| buffer = static_cast<float*>(jack_port_get_buffer(adapter->fCapturePortList[i], frames)); | |||
| adapter->fCaptureRingBuffer[i].Read(buffer, frames); | |||
| @@ -21,6 +21,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| #define __JackFilters__ | |||
| #include "jack.h" | |||
| #include <math.h> | |||
| #include <stdio.h> | |||
| namespace Jack | |||
| { | |||
| @@ -54,11 +56,86 @@ namespace Jack | |||
| } | |||
| }; | |||
| class JackDelayLockedLoop | |||
| { | |||
| private: | |||
| jack_nframes_t fFrames; | |||
| jack_time_t fCurrentWakeup; | |||
| jack_time_t fCurrentCallback; | |||
| jack_time_t fNextWakeUp; | |||
| float fSecondOrderIntegrator; | |||
| jack_nframes_t fBufferSize; | |||
| jack_nframes_t fSampleRate; | |||
| jack_time_t fPeriodUsecs; | |||
| float fFilterCoefficient; /* set once, never altered */ | |||
| public: | |||
| JackDelayLockedLoop(jack_nframes_t buffer_size, jack_nframes_t sample_rate) | |||
| { | |||
| fFrames = 0; | |||
| fCurrentWakeup = 0; | |||
| fCurrentCallback = 0; | |||
| fNextWakeUp = 0; | |||
| fFilterCoefficient = 0.01f; | |||
| fSecondOrderIntegrator = 0.0f; | |||
| fBufferSize = buffer_size; | |||
| fSampleRate = sample_rate; | |||
| fPeriodUsecs = jack_time_t(1000000.f / fSampleRate * fBufferSize); // in microsec | |||
| } | |||
| void Init(jack_time_t callback_usecs) | |||
| { | |||
| fSecondOrderIntegrator = 0.0f; | |||
| fCurrentCallback = callback_usecs; | |||
| fNextWakeUp = callback_usecs + fPeriodUsecs; | |||
| } | |||
| void IncFrame(jack_time_t callback_usecs) | |||
| { | |||
| float delta = (int64_t)callback_usecs - (int64_t)fNextWakeUp; | |||
| fCurrentWakeup = fNextWakeUp; | |||
| fCurrentCallback = callback_usecs; | |||
| fFrames += fBufferSize; | |||
| fSecondOrderIntegrator += 0.5f * fFilterCoefficient * delta; | |||
| fNextWakeUp = fCurrentWakeup + fPeriodUsecs + (int64_t) floorf((fFilterCoefficient * (delta + fSecondOrderIntegrator))); | |||
| } | |||
| jack_nframes_t Time2Frames(jack_time_t time) | |||
| { | |||
| /* | |||
| long val = (long) rint(((double) (long(time - fCurrentWakeup)) / ((jack_time_t)(fNextWakeUp - fCurrentWakeup))) * fBufferSize); | |||
| if (val < 0) { | |||
| printf("Time2Frames %ld\n", val); | |||
| printf("time %ld\n", time); | |||
| printf("fCurrentWakeup %ld\n", fCurrentWakeup); | |||
| printf("fNextWakeUp %ld\n", fNextWakeUp); | |||
| } | |||
| */ | |||
| return fFrames + (long) rint(((double) (long(time - fCurrentWakeup)) / ((jack_time_t)(fNextWakeUp - fCurrentWakeup))) * fBufferSize); | |||
| } | |||
| jack_time_t Frames2Time(jack_nframes_t frames) | |||
| { | |||
| return fCurrentWakeup + (long) rint(((double) ((frames - fFrames)) * ((jack_time_t)(fNextWakeUp - fCurrentWakeup))) / fBufferSize); | |||
| } | |||
| jack_time_t CurFrame2Time() | |||
| { | |||
| return fCurrentWakeup; | |||
| } | |||
| }; | |||
| inline float Range(float min, float max, float val) | |||
| { | |||
| return (val < min) ? min : ((val > max) ? max : val); | |||
| } | |||
| } | |||
| #endif | |||
| @@ -24,6 +24,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| #include "jack.h" | |||
| #include "JackError.h" | |||
| #include "JackResampler.h" | |||
| #include "JackFilters.h" | |||
| #include <samplerate.h> | |||
| #include <stdio.h> | |||
| @@ -45,6 +46,14 @@ namespace Jack | |||
| jack_time_t fCurCallbackTime; | |||
| jack_time_t fDeltaTime; | |||
| JackFilter fProducerFilter; | |||
| JackFilter fConsumerFilter; | |||
| // DLL | |||
| JackDelayLockedLoop fConsumerDLL; | |||
| JackDelayLockedLoop fProducerDLL; | |||
| jack_time_t fCurFrames; | |||
| JackResampler* fCaptureRingBuffer; | |||
| JackResampler* fPlaybackRingBuffer; | |||
| bool fRunning; | |||
| @@ -59,6 +68,8 @@ namespace Jack | |||
| fLastCallbackTime(0), | |||
| fCurCallbackTime(0), | |||
| fDeltaTime(0), | |||
| fProducerDLL(buffer_size, sample_rate), | |||
| fConsumerDLL(buffer_size, sample_rate), | |||
| fRunning(false) | |||
| {} | |||
| virtual ~JackIOAdapterInterface() | |||
| @@ -86,6 +97,13 @@ namespace Jack | |||
| //printf("SetCallbackDeltaTime %ld\n", delta_usec); | |||
| fDeltaTime = delta_usec; | |||
| } | |||
| virtual void SetCallbackTime(jack_time_t callback_usec) | |||
| { | |||
| jack_log("SetCallbackTime %ld", callback_usec); | |||
| //printf("SetCallbackDeltaTime %ld\n", delta_usec); | |||
| fConsumerDLL.IncFrame(callback_usec); | |||
| } | |||
| }; | |||
| } | |||
| @@ -115,14 +115,15 @@ extern "C" | |||
| return 1; | |||
| } else { | |||
| jack_log("Loading NetAudio Adapter"); | |||
| /* | |||
| adapter = new Jack::JackCallbackNetIOAdapter(jack_client, | |||
| new Jack::JackPortAudioIOAdapter(2, 2, jack_get_buffer_size(jack_client), jack_get_sample_rate(jack_client)), 2, 2); | |||
| */ | |||
| /* | |||
| #ifdef __APPLE__ | |||
| adapter = new Jack::JackCallbackNetIOAdapter(jack_client, | |||
| new Jack::JackCoreAudioIOAdapter(2, 2, jack_get_buffer_size(jack_client), jack_get_sample_rate(jack_client)), 2, 2); | |||
| #endif | |||
| */ | |||
| assert(adapter); | |||
| if (adapter->Open() == 0) { | |||
| @@ -194,8 +194,8 @@ def build(bld): | |||
| create_jack_process_obj(bld, 'netmanager', 'JackNetManager.cpp', serverlib) | |||
| process = create_jack_process_obj(bld, 'netioadapter', 'JackResampler.cpp JackIOAdapter.cpp JackNetIOAdapter.cpp JackCallbackNetIOAdapter.cpp ../macosx/JackCoreAudioIOAdapter.cpp', serverlib) | |||
| #process = create_jack_process_obj(bld, 'netioadapter', 'JackResampler.cpp JackIOAdapter.cpp JackNetIOAdapter.cpp JackCallbackNetIOAdapter.cpp ../windows/JackPortAudioIOAdapter.cpp', serverlib) | |||
| #process = create_jack_process_obj(bld, 'netioadapter', 'JackResampler.cpp JackIOAdapter.cpp JackNetIOAdapter.cpp JackCallbackNetIOAdapter.cpp ../macosx/JackCoreAudioIOAdapter.cpp', serverlib) | |||
| process = create_jack_process_obj(bld, 'netioadapter', 'JackResampler.cpp JackIOAdapter.cpp JackNetIOAdapter.cpp JackCallbackNetIOAdapter.cpp ../windows/JackPortAudioIOAdapter.cpp', serverlib) | |||
| process.env.append_value("LINKFLAGS", "-lsamplerate") | |||
| if bld.env()['IS_MACOSX']: | |||
| @@ -127,22 +127,50 @@ OSStatus JackCoreAudioIOAdapter::Render(void *inRefCon, | |||
| AudioUnitRender(adapter->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, adapter->fInputData); | |||
| /* | |||
| adapter->fLastCallbackTime = adapter->fCurCallbackTime; | |||
| adapter->fCurCallbackTime = jack_get_time(); | |||
| adapter->fConsumerFilter.AddValue(adapter->fCurCallbackTime - adapter->fLastCallbackTime); | |||
| adapter->fProducerFilter.AddValue(adapter->fDeltaTime); | |||
| */ | |||
| jack_log("JackCoreAudioIOAdapter::Render delta %ld", adapter->fCurCallbackTime - adapter->fLastCallbackTime); | |||
| //printf("JackCoreAudioIOAdapter::Render delta %ld\n", adapter->fCurCallbackTime - adapter->fLastCallbackTime); | |||
| if (!adapter->fRunning) | |||
| if (!adapter->fRunning) { | |||
| adapter->fRunning = true; | |||
| jack_time_t time = jack_get_time(); | |||
| adapter->fProducerDLL.Init(time); | |||
| adapter->fConsumerDLL.Init(time); | |||
| adapter->fCurFrames = 0; | |||
| } | |||
| // DLL based | |||
| //adapter->fConsumerDLL.IncFrame(adapter->fConsumerTime); | |||
| jack_time_t time = jack_get_time(); | |||
| adapter->fProducerDLL.IncFrame(time); | |||
| adapter->fCurFrames += inNumberFrames; | |||
| /* | |||
| jack_time_t time1 = adapter->fConsumerDLL.CurFrame2Time(); | |||
| jack_time_t time2 = adapter->fProducerDLL.CurFrame2Time(); | |||
| */ | |||
| jack_nframes_t time1 = adapter->fConsumerDLL.Time2Frames(time); | |||
| jack_nframes_t time2 = adapter->fProducerDLL.Time2Frames(time); | |||
| printf("time1 %ld time2 %ld\n",time1, time2); | |||
| double src_ratio_output = double(time2) / double(time1); | |||
| double src_ratio_input = double(time1) / double(time2); | |||
| /* | |||
| jack_time_t val2 = adapter->fConsumerFilter.GetVal(); | |||
| jack_time_t val1 = adapter->fProducerFilter.GetVal(); | |||
| double src_ratio_output = double(val1) / double(val2); | |||
| double src_ratio_input = double(val2) / double(val1); | |||
| */ | |||
| if (src_ratio_input < 0.8f || src_ratio_input > 1.2f) { | |||
| jack_error("src_ratio_input = %f", src_ratio_input); | |||
| @@ -159,6 +187,7 @@ OSStatus JackCoreAudioIOAdapter::Render(void *inRefCon, | |||
| //jack_log("Callback resampler src_ratio_input = %f src_ratio_output = %f", src_ratio_input, src_ratio_output); | |||
| //jack_info("Callback resampler src_ratio_input = %f src_ratio_output = %f", src_ratio_input, src_ratio_output); | |||
| printf("Callback resampler src_ratio_input = %f src_ratio_output = %f\n", src_ratio_input, src_ratio_output); | |||
| for (int i = 0; i < adapter->fCaptureChannels; i++) { | |||
| adapter->fCaptureRingBuffer[i].SetRatio(src_ratio_input); | |||
| @@ -21,7 +21,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| #define __JackCoreAudioIOAdapter__ | |||
| #include "JackIOAdapter.h" | |||
| #include "JackFilters.h" | |||
| #include "jack.h" | |||
| #include <AudioToolbox/AudioConverter.h> | |||
| #include <CoreAudio/CoreAudio.h> | |||
| @@ -42,17 +42,44 @@ int JackPortAudioIOAdapter::Render(const void* inputBuffer, void* outputBuffer, | |||
| jack_log("JackPortAudioIOAdapter::Render delta %ld", adapter->fCurCallbackTime - adapter->fLastCallbackTime); | |||
| if (!adapter->fRunning) | |||
| if (!adapter->fRunning) { | |||
| adapter->fRunning = true; | |||
| jack_time_t time = jack_get_time(); | |||
| adapter->fProducerDLL.Init(time); | |||
| adapter->fConsumerDLL.Init(time); | |||
| adapter->fCurFrames = 0; | |||
| } | |||
| /* | |||
| double src_ratio_output = double(adapter->fCurCallbackTime - adapter->fLastCallbackTime) / double(adapter->fDeltaTime); | |||
| double src_ratio_input = double(adapter->fDeltaTime) / double(adapter->fCurCallbackTime - adapter->fLastCallbackTime); | |||
| */ | |||
| // DLL based | |||
| //adapter->fConsumerDLL.IncFrame(adapter->fConsumerTime); | |||
| jack_time_t time = jack_get_time(); | |||
| adapter->fProducerDLL.IncFrame(time); | |||
| adapter->fCurFrames += framesPerBuffer; | |||
| /* | |||
| jack_time_t time1 = adapter->fConsumerDLL.CurFrame2Time(); | |||
| jack_time_t time2 = adapter->fProducerDLL.CurFrame2Time(); | |||
| */ | |||
| jack_nframes_t time1 = adapter->fConsumerDLL.Time2Frames(time); | |||
| jack_nframes_t time2 = adapter->fProducerDLL.Time2Frames(time); | |||
| printf("time1 %ld time2 %ld\n",time1, time2); | |||
| double src_ratio_output = double(time2) / double(time1); | |||
| double src_ratio_input = double(time1) / double(time2); | |||
| /* | |||
| jack_time_t val2 = adapter->fConsumerFilter.GetVal(); | |||
| jack_time_t val1 = adapter->fProducerFilter.GetVal(); | |||
| double src_ratio_output = double(val1) / double(val2); | |||
| double src_ratio_input = double(val2) / double(val1); | |||
| */ | |||
| if (src_ratio_input < 0.8f || src_ratio_input > 1.2f) { | |||
| jack_error("src_ratio_input = %f", src_ratio_input); | |||
| @@ -21,7 +21,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| #define __JackPortAudioIOAdapter__ | |||
| #include "JackIOAdapter.h" | |||
| #include "JackFilters.h" | |||
| #include "portaudio.h" | |||
| namespace Jack | |||
| @@ -36,9 +35,6 @@ namespace Jack | |||
| PaDeviceIndex fInputDevice; | |||
| PaDeviceIndex fOutputDevice; | |||
| JackFilter fProducerFilter; | |||
| JackFilter fConsumerFilter; | |||
| static int Render(const void* inputBuffer, void* outputBuffer, | |||
| unsigned long framesPerBuffer, | |||
| const PaStreamCallbackTimeInfo* timeInfo, | |||