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, | |||