# HG changeset patch # User Giulio Moro # Date 1442891353 -3600 # Node ID ebbfb154351aae06fc7492210e42e3cde29b856d # Parent 134bff10e561d58e372d8c75df8dd912487dc9dc Now leveraging BBB's lock between xenomai clock and audio clock for ultra-accurate, low-latency clocking. CAVEAT: fractions of samples drifts will occurr every time the clock is changed diff -r 134bff10e561 -r ebbfb154351a core/VirtualClock.cpp --- a/core/VirtualClock.cpp Mon Sep 21 03:12:21 2015 +0100 +++ b/core/VirtualClock.cpp Tue Sep 22 04:09:13 2015 +0100 @@ -10,41 +10,47 @@ double coefficients[IIR_FILTER_STAGE_COEFFICIENTS] = { 0.000241359049041961, 0.000482718098083923, 0.000241359049041961, -1.95557824031504, 0.956543676511203 }; - iir.setNumberOfStages(4); + double states[4]; + for(int n = 0; n < 4; n++){ + states[n] = initialValueUs; + } + iir.setNumberOfStages(2); iir.setCoefficients(coefficients); - printf("kalmanInit=%f\n",initialValueUs); - kalman.init(0.01, 158575.715009816 /*measured var() */, - initialValueUs -//#ifdef USE_JUCE -// 5804.98866213152 /*blockSize/Fs*1e6*/ -//#else -// 5804.98866213152 /*blockSize/Fs*1e6*/ -//#endif - ); + iir.setStates(states); +// printf("kalmanInit=%f\n",initialValueUs); +// kalman.init(0.01, 158575.715009816 /*measured var() */, initialValueUs); + kalman.init(10, 1588.715009816 /*measured var() */, initialValueUs); } VirtualClock::VirtualClock(){} void VirtualClock::sync(){ sync(1); } + void VirtualClock::sync(double numPeriods){ myClock_t currentTime = Clock::getTimeUs(); elapsedPeriods += numPeriods; static int calls = 0; if(calls == 0){ startTime = currentTime; -//AA lastSyncEstimatedTime = startTime; lastSyncEstimatedTime = 0; } else { double newBlockPeriod = (currentTime - lastSyncTime); -// period = iir.process(movingAverage.add(newPeriod)); //TODO: replace with Kalman filter +#ifdef USE_JUCE blockPeriod = iir.process(kalman.process(newBlockPeriod)); -// period = 22.6760958210091; +#else + // this leverages the fact that on the Beaglebone the audio clock + // is synced to the xenomai clock. + // CAVEAT: we are actually drifting by fractions of a sample everytime + // there is a clock adjustment because we do not know exactly at what point + // time the clock change actually takes place + // Avoiding this would actually require a redesign and would anyhow produce overall + // less accurate results. + blockPeriod = numPeriods/gAudioCodec->getAudioSamplingRate()*1e6; +#endif /* USE_JUCE */ + // printf("%f %f\n", blockPeriod, newBlockPeriod); period = blockPeriod / numPeriods; lastSyncEstimatedTime += (period * numPeriods); -// if(calls == 800) -// lastSyncEstimatedTime = lastSyncTime; -// printf("%lld, %lld\n", lastSyncTime, lastSyncEstimatedTime); } lastSyncTime = currentTime; // printf("%lld\n", lastSyncTime); @@ -79,7 +85,6 @@ printf("ERROR: periodOffset adjustment of %f resulted in elapsedPeriods=%f\n", periodOffset, elapsedPeriods); exit(1); } - printf("this is not called\n"); movingAverage.reset(); } double VirtualClock::getPeriod(){ diff -r 134bff10e561 -r ebbfb154351a include/VirtualClock.h --- a/include/VirtualClock.h Mon Sep 21 03:12:21 2015 +0100 +++ b/include/VirtualClock.h Tue Sep 22 04:09:13 2015 +0100 @@ -9,6 +9,8 @@ #ifdef USE_JUCE #else #include +#include +extern I2c_Codec* gAudioCodec; #endif /* USE_JUCE */ class VirtualClock{