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 }