Mercurial > hg > beaglert
comparison core/ClockSynchronizer.cpp @ 132:e24c531220ee scope-refactoring
Added some sort of synchronization, not working great though
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Thu, 27 Aug 2015 01:42:04 +0100 |
parents | |
children | 04b1678614c9 |
comparison
equal
deleted
inserted
replaced
131:ff28e56e5b7e | 132:e24c531220ee |
---|---|
1 /* | |
2 * ClockSynchronizer.cpp | |
3 * | |
4 * Created on: 26 Aug 2015 | |
5 * Author: giulio | |
6 */ | |
7 | |
8 #include "ClockSynchronizer.h" | |
9 | |
10 // declare static members | |
11 float ClockSynchronizer::targetSamplingRate; | |
12 float ClockSynchronizer::currentSamplingRate; | |
13 bool ClockSynchronizer::threadRunning; | |
14 int ClockSynchronizer::threadWasRunning; | |
15 bool ClockSynchronizer::staticConstructed=false; | |
16 AuxiliaryTask ClockSynchronizer::setClockTask; | |
17 | |
18 void ClockSynchronizer::staticConstructor(){ | |
19 int priority=90; | |
20 setClockTask=BeagleRT_createAuxiliaryTask(&ClockSynchronizer::setClock, priority, "setClockTask"); | |
21 threadRunning=false; | |
22 } | |
23 | |
24 void ClockSynchronizer::setClock(){ | |
25 rt_printf("Setting clock to %f\n",targetSamplingRate); | |
26 threadRunning=true; | |
27 //I2C magic | |
28 gAudioCodec->setAudioSamplingRate(targetSamplingRate); | |
29 threadRunning=false; | |
30 threadWasRunning=3; | |
31 rt_printf("Exiting thread\n"); | |
32 }; | |
33 | |
34 ClockSynchronizer::ClockSynchronizer() { | |
35 reset(); | |
36 } | |
37 | |
38 ClockSynchronizer::~ClockSynchronizer(){}; | |
39 | |
40 void ClockSynchronizer::setup(){ | |
41 if(staticConstructed==false) //This should be called in the constructor, but because of the current limitations of | |
42 // BeagleRT, it is here and setup() needs to be called in BeagleRT setup(); | |
43 staticConstructor(); | |
44 } | |
45 void ClockSynchronizer::reset(){ | |
46 localCounter=0; | |
47 remoteCounter=0; | |
48 lastTime=0; | |
49 localOffset=-1; | |
50 remoteOffset=-1; | |
51 timeOffset=-1; | |
52 currentSamplingRate=44100; | |
53 } | |
54 | |
55 void ClockSynchronizer::update(int aLocalCounter, int aRemoteCounter, RTIME aLastTime){ | |
56 if(threadRunning==true){ //do nothing if clock is being adjusted | |
57 rt_printf("do nothing if clock is being adjusted\n"); | |
58 return; | |
59 } | |
60 if(threadWasRunning > 0){ //reset variables after clock has been adjusted | |
61 threadWasRunning--; // wait a few calls to make sure the clock stabilizes | |
62 rt_printf("wait a few calls to make sure the clock stabilizes\n"); | |
63 return; | |
64 }/* | |
65 if(threadWasRunning==1){ | |
66 threadWasRunning=0; | |
67 // reset offsets after a correction | |
68 localOffset=aLocalCounter; | |
69 remoteOffset=aRemoteCounter; | |
70 timeOffset=aLastTime; | |
71 rt_printf("reset variables after clock has been adjusted\n"); | |
72 return; | |
73 }*/ | |
74 if (localOffset<=0 || remoteOffset<=0){ // probably this is the first run | |
75 localOffset=aLocalCounter; | |
76 remoteOffset=aRemoteCounter; | |
77 timeOffset=aLastTime; | |
78 rt_printf("First run of update(), localOffset: %d, remoteOffset: %d, timeOffset: %llu\n", | |
79 localOffset, remoteOffset, timeOffset); | |
80 return; | |
81 } | |
82 localCounter=aLocalCounter-localOffset; | |
83 remoteCounter=aRemoteCounter-remoteOffset; | |
84 lastTime=aLastTime-timeOffset; | |
85 if (localCounter<=0 || remoteCounter<=0 || timeOffset<=0) {// did anything wrong happened? | |
86 rt_printf("fourth\n"); | |
87 return; | |
88 } | |
89 // TODO: make sure we do not get actually adjust the clock too often (e.g.: limits on the timestamp) | |
90 // Should keep track of last time a change has been made, so that when a large compensation is needed | |
91 // (e.g.: as the program has just started), adjustClock() is called more frequently | |
92 // but gets called less often later. | |
93 // Should also try to avoid drastic correction after a while that the program | |
94 // has started, so to avoid glitches. But this can maybe be handled by the thread itself. | |
95 // TODO: should keep a log and maybe compensate for (and prevent) overshoot according to previous changes | |
96 rt_printf("lastTime: %llu, remoteCounter: %d\n", lastTime, remoteCounter); | |
97 | |
98 currentSamplingRate=gAudioCodec->getAudioSamplingRate(); | |
99 float T=1/currentSamplingRate; | |
100 int elapsedSamples=remoteCounter*(NetworkBuffer::bufferLength-NetworkBuffer::headerLength); | |
101 double expectedTimeUs=T*elapsedSamples*1000000; | |
102 double actualTimeUs=lastTime/1000.0; | |
103 targetSamplingRate=expectedTimeUs/actualTimeUs*currentSamplingRate; | |
104 // rt_printf("Fs: %f, expectedTimeUs: %f, lastTime: %ul\n", expectedTimeUs, lastTime); | |
105 rt_printf("Fs: %.1f, expectedTimeUs: %4.3f, actualTimeUs: %4.3f, targetFs_ %.3f\n", | |
106 gAudioCodec->getAudioSamplingRate(), expectedTimeUs/elapsedSamples, actualTimeUs/elapsedSamples, targetSamplingRate); | |
107 adjustClock(); | |
108 } | |
109 | |
110 void ClockSynchronizer::adjustClock(){ | |
111 if(currentSamplingRate!= targetSamplingRate){ //TODO: actually check that the difference is less than the quantization error in the PLL | |
112 BeagleRT_scheduleAuxiliaryTask(setClockTask); | |
113 } | |
114 } |