Mercurial > hg > beaglert
comparison core/VirtualClock.cpp @ 150:ebbfb154351a ClockSync
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
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Tue, 22 Sep 2015 04:09:13 +0100 |
parents | 134bff10e561 |
children | 8f98b32d0e23 |
comparison
equal
deleted
inserted
replaced
149:134bff10e561 | 150:ebbfb154351a |
---|---|
8 elapsedPeriodsOffset = 0; | 8 elapsedPeriodsOffset = 0; |
9 lastSyncEstimatedTime = 0; | 9 lastSyncEstimatedTime = 0; |
10 double coefficients[IIR_FILTER_STAGE_COEFFICIENTS] = { | 10 double coefficients[IIR_FILTER_STAGE_COEFFICIENTS] = { |
11 0.000241359049041961, 0.000482718098083923, 0.000241359049041961, -1.95557824031504, 0.956543676511203 | 11 0.000241359049041961, 0.000482718098083923, 0.000241359049041961, -1.95557824031504, 0.956543676511203 |
12 }; | 12 }; |
13 iir.setNumberOfStages(4); | 13 double states[4]; |
14 for(int n = 0; n < 4; n++){ | |
15 states[n] = initialValueUs; | |
16 } | |
17 iir.setNumberOfStages(2); | |
14 iir.setCoefficients(coefficients); | 18 iir.setCoefficients(coefficients); |
15 printf("kalmanInit=%f\n",initialValueUs); | 19 iir.setStates(states); |
16 kalman.init(0.01, 158575.715009816 /*measured var() */, | 20 // printf("kalmanInit=%f\n",initialValueUs); |
17 initialValueUs | 21 // kalman.init(0.01, 158575.715009816 /*measured var() */, initialValueUs); |
18 //#ifdef USE_JUCE | 22 kalman.init(10, 1588.715009816 /*measured var() */, initialValueUs); |
19 // 5804.98866213152 /*blockSize/Fs*1e6*/ | |
20 //#else | |
21 // 5804.98866213152 /*blockSize/Fs*1e6*/ | |
22 //#endif | |
23 ); | |
24 } | 23 } |
25 | 24 |
26 VirtualClock::VirtualClock(){} | 25 VirtualClock::VirtualClock(){} |
27 void VirtualClock::sync(){ | 26 void VirtualClock::sync(){ |
28 sync(1); | 27 sync(1); |
29 } | 28 } |
29 | |
30 void VirtualClock::sync(double numPeriods){ | 30 void VirtualClock::sync(double numPeriods){ |
31 myClock_t currentTime = Clock::getTimeUs(); | 31 myClock_t currentTime = Clock::getTimeUs(); |
32 elapsedPeriods += numPeriods; | 32 elapsedPeriods += numPeriods; |
33 static int calls = 0; | 33 static int calls = 0; |
34 if(calls == 0){ | 34 if(calls == 0){ |
35 startTime = currentTime; | 35 startTime = currentTime; |
36 //AA lastSyncEstimatedTime = startTime; | |
37 lastSyncEstimatedTime = 0; | 36 lastSyncEstimatedTime = 0; |
38 } else { | 37 } else { |
39 double newBlockPeriod = (currentTime - lastSyncTime); | 38 double newBlockPeriod = (currentTime - lastSyncTime); |
40 // period = iir.process(movingAverage.add(newPeriod)); //TODO: replace with Kalman filter | 39 #ifdef USE_JUCE |
41 blockPeriod = iir.process(kalman.process(newBlockPeriod)); | 40 blockPeriod = iir.process(kalman.process(newBlockPeriod)); |
42 // period = 22.6760958210091; | 41 #else |
42 // this leverages the fact that on the Beaglebone the audio clock | |
43 // is synced to the xenomai clock. | |
44 // CAVEAT: we are actually drifting by fractions of a sample everytime | |
45 // there is a clock adjustment because we do not know exactly at what point | |
46 // time the clock change actually takes place | |
47 // Avoiding this would actually require a redesign and would anyhow produce overall | |
48 // less accurate results. | |
49 blockPeriod = numPeriods/gAudioCodec->getAudioSamplingRate()*1e6; | |
50 #endif /* USE_JUCE */ | |
51 // printf("%f %f\n", blockPeriod, newBlockPeriod); | |
43 period = blockPeriod / numPeriods; | 52 period = blockPeriod / numPeriods; |
44 lastSyncEstimatedTime += (period * numPeriods); | 53 lastSyncEstimatedTime += (period * numPeriods); |
45 // if(calls == 800) | |
46 // lastSyncEstimatedTime = lastSyncTime; | |
47 // printf("%lld, %lld\n", lastSyncTime, lastSyncEstimatedTime); | |
48 } | 54 } |
49 lastSyncTime = currentTime; | 55 lastSyncTime = currentTime; |
50 // printf("%lld\n", lastSyncTime); | 56 // printf("%lld\n", lastSyncTime); |
51 calls++; | 57 calls++; |
52 } | 58 } |
77 elapsedPeriods-=periodOffset; | 83 elapsedPeriods-=periodOffset; |
78 if(elapsedPeriods<0){ | 84 if(elapsedPeriods<0){ |
79 printf("ERROR: periodOffset adjustment of %f resulted in elapsedPeriods=%f\n", periodOffset, elapsedPeriods); | 85 printf("ERROR: periodOffset adjustment of %f resulted in elapsedPeriods=%f\n", periodOffset, elapsedPeriods); |
80 exit(1); | 86 exit(1); |
81 } | 87 } |
82 printf("this is not called\n"); | |
83 movingAverage.reset(); | 88 movingAverage.reset(); |
84 } | 89 } |
85 double VirtualClock::getPeriod(){ | 90 double VirtualClock::getPeriod(){ |
86 return blockPeriod; | 91 return blockPeriod; |
87 } | 92 } |