Mercurial > hg > beaglert
comparison core/ClockSynchronizer.cpp @ 133:04b1678614c9 scope-refactoring
Using moving average for clock detection during synchronization seems to be working better but audio gets worse and worse
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Thu, 27 Aug 2015 03:33:32 +0100 |
parents | e24c531220ee |
children |
comparison
equal
deleted
inserted
replaced
132:e24c531220ee | 133:04b1678614c9 |
---|---|
20 setClockTask=BeagleRT_createAuxiliaryTask(&ClockSynchronizer::setClock, priority, "setClockTask"); | 20 setClockTask=BeagleRT_createAuxiliaryTask(&ClockSynchronizer::setClock, priority, "setClockTask"); |
21 threadRunning=false; | 21 threadRunning=false; |
22 } | 22 } |
23 | 23 |
24 void ClockSynchronizer::setClock(){ | 24 void ClockSynchronizer::setClock(){ |
25 rt_printf("Setting clock to %f\n",targetSamplingRate); | 25 // rt_printf("Setting clock to %f\n",targetSamplingRate); |
26 threadRunning=true; | 26 threadRunning=true; |
27 //I2C magic | 27 //I2C magic |
28 gAudioCodec->setAudioSamplingRate(targetSamplingRate); | 28 gAudioCodec->setAudioSamplingRate(targetSamplingRate); |
29 threadRunning=false; | 29 threadRunning=false; |
30 threadWasRunning=3; | 30 threadWasRunning=1; |
31 rt_printf("Exiting thread\n"); | 31 // rt_printf("Exiting thread\n"); |
32 }; | 32 }; |
33 | 33 |
34 ClockSynchronizer::ClockSynchronizer() { | 34 ClockSynchronizer::ClockSynchronizer() { |
35 reset(); | 35 reset(); |
36 } | 36 } |
91 // (e.g.: as the program has just started), adjustClock() is called more frequently | 91 // (e.g.: as the program has just started), adjustClock() is called more frequently |
92 // but gets called less often later. | 92 // but gets called less often later. |
93 // Should also try to avoid drastic correction after a while that the program | 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. | 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 | 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); | 96 static RTIME lastlastTime=0; |
97 | 97 // rt_printf("interval: %f, \n",(double)(remoteCounter*300.0)/lastTime*1000000000.0); |
98 lastlastTime=lastTime; | |
98 currentSamplingRate=gAudioCodec->getAudioSamplingRate(); | 99 currentSamplingRate=gAudioCodec->getAudioSamplingRate(); |
99 float T=1/currentSamplingRate; | 100 float T=1/currentSamplingRate; |
100 int elapsedSamples=remoteCounter*(NetworkBuffer::bufferLength-NetworkBuffer::headerLength); | 101 int elapsedSamples=remoteCounter*(NetworkBuffer::bufferLength-NetworkBuffer::headerLength); |
101 double expectedTimeUs=T*elapsedSamples*1000000; | 102 double expectedTimeUs=T*elapsedSamples*1000000; |
103 double actualTimeS=lastTime/1000000000.0; | |
102 double actualTimeUs=lastTime/1000.0; | 104 double actualTimeUs=lastTime/1000.0; |
103 targetSamplingRate=expectedTimeUs/actualTimeUs*currentSamplingRate; | 105 static float averageBuffer[101]={0}; |
106 static int averageBufferPointer=0; | |
107 static float average=0; | |
108 static int bufferFull=0; | |
109 average-=averageBuffer[averageBufferPointer]; | |
110 averageBuffer[averageBufferPointer]=elapsedSamples/actualTimeS; | |
111 average+=averageBuffer[averageBufferPointer]; | |
112 averageBufferPointer++; | |
113 if(averageBufferPointer==101){ | |
114 averageBufferPointer=0; | |
115 bufferFull++; | |
116 } | |
117 | |
104 // rt_printf("Fs: %f, expectedTimeUs: %f, lastTime: %ul\n", expectedTimeUs, lastTime); | 118 // 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", | 119 // rt_printf("Fs: %.1f, actualTimeS: %4.6f, targetFs_ %.3f\n", |
106 gAudioCodec->getAudioSamplingRate(), expectedTimeUs/elapsedSamples, actualTimeUs/elapsedSamples, targetSamplingRate); | 120 if((averageBufferPointer&3)==0){ |
107 adjustClock(); | 121 static float oldTargetSamplingRate=0; |
122 targetSamplingRate=average/101; | |
123 if(bufferFull>=3 && fabsf(targetSamplingRate-oldTargetSamplingRate) < 1){ | |
124 rt_printf("%.1f, %4.6f, %.3f;\n", | |
125 gAudioCodec->getAudioSamplingRate(), actualTimeS, targetSamplingRate, targetSamplingRate-oldTargetSamplingRate); | |
126 adjustClock(); | |
127 } | |
128 oldTargetSamplingRate=targetSamplingRate; | |
129 } | |
108 } | 130 } |
109 | 131 |
110 void ClockSynchronizer::adjustClock(){ | 132 void ClockSynchronizer::adjustClock(){ |
111 if(currentSamplingRate!= targetSamplingRate){ //TODO: actually check that the difference is less than the quantization error in the PLL | 133 if(fabsf(currentSamplingRate-targetSamplingRate)>0.7){ //TODO: actually check that the difference is less than the quantization error in the PLL |
112 BeagleRT_scheduleAuxiliaryTask(setClockTask); | 134 BeagleRT_scheduleAuxiliaryTask(setClockTask); |
113 } | 135 } |
114 } | 136 } |