annotate core/VirtualClock.cpp @ 151:e9c9404e3d1f ClockSync

Pff partially working. No PID. When setting the audio clock on the bbb to 44098 the master and slave clock keep diverging instead of converging ...
author Giulio Moro <giuliomoro@yahoo.it>
date Tue, 22 Sep 2015 04:10:07 +0100
parents ebbfb154351a
children 8f98b32d0e23
rev   line source
giuliomoro@135 1 #include "VirtualClock.h"
giuliomoro@149 2 void VirtualClock::init(float initialValueUs){
giuliomoro@135 3 firstRun=true;
giuliomoro@141 4 movingAverage.setLength(101); //TODO: a better filtering algorithm ( Did you say Kalman?)
giuliomoro@149 5 blockPeriod=-1;
giuliomoro@141 6 elapsedPeriods=0;
giuliomoro@141 7 startTime=0;
giuliomoro@149 8 elapsedPeriodsOffset = 0;
giuliomoro@149 9 lastSyncEstimatedTime = 0;
giuliomoro@149 10 double coefficients[IIR_FILTER_STAGE_COEFFICIENTS] = {
giuliomoro@149 11 0.000241359049041961, 0.000482718098083923, 0.000241359049041961, -1.95557824031504, 0.956543676511203
giuliomoro@149 12 };
giuliomoro@150 13 double states[4];
giuliomoro@150 14 for(int n = 0; n < 4; n++){
giuliomoro@150 15 states[n] = initialValueUs;
giuliomoro@150 16 }
giuliomoro@150 17 iir.setNumberOfStages(2);
giuliomoro@149 18 iir.setCoefficients(coefficients);
giuliomoro@150 19 iir.setStates(states);
giuliomoro@150 20 // printf("kalmanInit=%f\n",initialValueUs);
giuliomoro@150 21 // kalman.init(0.01, 158575.715009816 /*measured var() */, initialValueUs);
giuliomoro@150 22 kalman.init(10, 1588.715009816 /*measured var() */, initialValueUs);
giuliomoro@135 23 }
giuliomoro@135 24
giuliomoro@149 25 VirtualClock::VirtualClock(){}
giuliomoro@135 26 void VirtualClock::sync(){
giuliomoro@135 27 sync(1);
giuliomoro@135 28 }
giuliomoro@150 29
giuliomoro@141 30 void VirtualClock::sync(double numPeriods){
giuliomoro@149 31 myClock_t currentTime = Clock::getTimeUs();
giuliomoro@149 32 elapsedPeriods += numPeriods;
giuliomoro@149 33 static int calls = 0;
giuliomoro@149 34 if(calls == 0){
giuliomoro@149 35 startTime = currentTime;
giuliomoro@149 36 lastSyncEstimatedTime = 0;
giuliomoro@149 37 } else {
giuliomoro@149 38 double newBlockPeriod = (currentTime - lastSyncTime);
giuliomoro@150 39 #ifdef USE_JUCE
giuliomoro@149 40 blockPeriod = iir.process(kalman.process(newBlockPeriod));
giuliomoro@150 41 #else
giuliomoro@150 42 // this leverages the fact that on the Beaglebone the audio clock
giuliomoro@150 43 // is synced to the xenomai clock.
giuliomoro@150 44 // CAVEAT: we are actually drifting by fractions of a sample everytime
giuliomoro@150 45 // there is a clock adjustment because we do not know exactly at what point
giuliomoro@150 46 // time the clock change actually takes place
giuliomoro@150 47 // Avoiding this would actually require a redesign and would anyhow produce overall
giuliomoro@150 48 // less accurate results.
giuliomoro@150 49 blockPeriod = numPeriods/gAudioCodec->getAudioSamplingRate()*1e6;
giuliomoro@150 50 #endif /* USE_JUCE */
giuliomoro@150 51 // printf("%f %f\n", blockPeriod, newBlockPeriod);
giuliomoro@149 52 period = blockPeriod / numPeriods;
giuliomoro@149 53 lastSyncEstimatedTime += (period * numPeriods);
giuliomoro@141 54 }
giuliomoro@149 55 lastSyncTime = currentTime;
giuliomoro@149 56 // printf("%lld\n", lastSyncTime);
giuliomoro@141 57 calls++;
giuliomoro@135 58 }
giuliomoro@135 59
giuliomoro@135 60 double VirtualClock::getNow(){
giuliomoro@139 61 myClock_t currentSystemTime=Clock::getTimeUs();
giuliomoro@149 62 if(blockPeriod<=0){
giuliomoro@141 63 return currentSystemTime; // TODO: this is not very meaningful.
giuliomoro@135 64 }
giuliomoro@149 65 double elapsed = (currentSystemTime - startTime) - lastSyncEstimatedTime;
giuliomoro@149 66 double now = elapsedPeriods + elapsed / (double)period;
giuliomoro@149 67 // if(now>currentSystemTime+10*1e6)
giuliomoro@149 68 // now=0;
giuliomoro@149 69 // static long long int pastSy=0;
giuliomoro@149 70 // printf("%lld\n", currentSystemTime-pastSy);
giuliomoro@149 71 // pastSy=currentSystemTime;
giuliomoro@149 72 static int count=0;
giuliomoro@149 73 count++;
giuliomoro@149 74 // if(count&1)
giuliomoro@149 75 #ifdef USE_JUCE
giuliomoro@149 76 #else
giuliomoro@149 77 // printf("%f %f %f\n", (currentSystemTime - startTime)/1e6*44100.0, blockPeriod, now);
giuliomoro@149 78 #endif
giuliomoro@139 79 return now;
giuliomoro@135 80 }
giuliomoro@135 81
giuliomoro@141 82 void VirtualClock::addOffset(double periodOffset){
giuliomoro@141 83 elapsedPeriods-=periodOffset;
giuliomoro@141 84 if(elapsedPeriods<0){
giuliomoro@141 85 printf("ERROR: periodOffset adjustment of %f resulted in elapsedPeriods=%f\n", periodOffset, elapsedPeriods);
giuliomoro@141 86 exit(1);
giuliomoro@141 87 }
giuliomoro@141 88 movingAverage.reset();
giuliomoro@141 89 }
giuliomoro@135 90 double VirtualClock::getPeriod(){
giuliomoro@149 91 return blockPeriod;
giuliomoro@135 92 }