Mercurial > hg > beaglert
view core/VirtualClock.cpp @ 152:8f98b32d0e23 ClockSync
Last commit on this branch for a while. Overall not very succesful
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Mon, 05 Oct 2015 13:06:14 +0100 |
parents | ebbfb154351a |
children |
line wrap: on
line source
#include "VirtualClock.h" void VirtualClock::init(float initialValueUs){ firstRun=true; movingAverage.setLength(101); //TODO: a better filtering algorithm ( Did you say Kalman?) blockPeriod=-1; elapsedPeriods=0; startTime=0; elapsedPeriodsOffset = 0; lastSyncEstimatedTime = 0; double coefficients[IIR_FILTER_STAGE_COEFFICIENTS] = { 0.000241359049041961, 0.000482718098083923, 0.000241359049041961, -1.95557824031504, 0.956543676511203 }; double states[4]; for(int n = 0; n < 4; n++){ states[n] = initialValueUs; } iir.setNumberOfStages(2); iir.setCoefficients(coefficients); 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; lastSyncEstimatedTime = 0; } else { double newBlockPeriod = (currentTime - lastSyncTime); #ifdef USE_JUCE blockPeriod = iir.process(kalman.process(newBlockPeriod)); #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); } lastSyncTime = currentTime; // printf("%lld\n", lastSyncTime); calls++; } double VirtualClock::getNow(){ myClock_t currentSystemTime=Clock::getTimeUs(); if(blockPeriod<=0){ return currentSystemTime; // TODO: this is not very meaningful. } double elapsed = (currentSystemTime - startTime) - lastSyncEstimatedTime; double now = elapsedPeriods + elapsed / (double)period; // if(now>currentSystemTime+10*1e6) // now=0; // static long long int pastSy=0; // printf("%lld\n", currentSystemTime-pastSy); // pastSy=currentSystemTime; static int count=0; count++; // if(count&1) #ifdef USE_JUCE #else // printf("%f %f %f\n", (currentSystemTime - startTime)/1e6*44100.0, blockPeriod, now); #endif return now; } void VirtualClock::addOffset(double periodOffset){ // printf("Clock was : %f ", elapsedPeriods); elapsedPeriods-=periodOffset; if(elapsedPeriods<0){ printf("ERROR: periodOffset adjustment of %f resulted in elapsedPeriods=%f\n", periodOffset, elapsedPeriods); exit(1); } // printf("and now is: %f after a correction of %f", elapsedPeriods, periodOffset); movingAverage.reset(); } double VirtualClock::getPeriod(){ return blockPeriod; }