diff 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
line wrap: on
line diff
--- a/core/ClockSynchronizer.cpp	Thu Aug 27 01:42:04 2015 +0100
+++ b/core/ClockSynchronizer.cpp	Thu Aug 27 03:33:32 2015 +0100
@@ -22,13 +22,13 @@
 }
 
 void ClockSynchronizer::setClock(){
-	rt_printf("Setting clock to %f\n",targetSamplingRate);
+//	rt_printf("Setting clock to %f\n",targetSamplingRate);
 	threadRunning=true;
 //I2C magic
 	gAudioCodec->setAudioSamplingRate(targetSamplingRate);
 	threadRunning=false;
-	threadWasRunning=3;
-	rt_printf("Exiting thread\n");
+	threadWasRunning=1;
+//	rt_printf("Exiting thread\n");
 };
 
 ClockSynchronizer::ClockSynchronizer() {
@@ -93,22 +93,44 @@
 	// Should also try to avoid drastic correction after a while that the program
 	// has started, so to avoid glitches. But this can maybe be handled by the thread itself.
 	// TODO: should keep a log and maybe compensate for (and prevent) overshoot according to previous changes
-	rt_printf("lastTime: %llu, remoteCounter: %d\n", lastTime, remoteCounter);
-
+	static RTIME lastlastTime=0;
+//	rt_printf("interval: %f, \n",(double)(remoteCounter*300.0)/lastTime*1000000000.0);
+	lastlastTime=lastTime;
 	currentSamplingRate=gAudioCodec->getAudioSamplingRate();
 	float T=1/currentSamplingRate;
 	int elapsedSamples=remoteCounter*(NetworkBuffer::bufferLength-NetworkBuffer::headerLength);
 	double expectedTimeUs=T*elapsedSamples*1000000;
+	double actualTimeS=lastTime/1000000000.0;
 	double actualTimeUs=lastTime/1000.0;
-	targetSamplingRate=expectedTimeUs/actualTimeUs*currentSamplingRate;
+	static float averageBuffer[101]={0};
+	static int averageBufferPointer=0;
+	static float average=0;
+	static int bufferFull=0;
+	average-=averageBuffer[averageBufferPointer];
+	averageBuffer[averageBufferPointer]=elapsedSamples/actualTimeS;
+	average+=averageBuffer[averageBufferPointer];
+	averageBufferPointer++;
+	if(averageBufferPointer==101){
+		averageBufferPointer=0;
+		bufferFull++;
+	}
+
 //	rt_printf("Fs: %f, expectedTimeUs: %f, lastTime: %ul\n", expectedTimeUs, lastTime);
-	rt_printf("Fs: %.1f, expectedTimeUs: %4.3f, actualTimeUs: %4.3f, targetFs_ %.3f\n",
-			gAudioCodec->getAudioSamplingRate(), expectedTimeUs/elapsedSamples, actualTimeUs/elapsedSamples, targetSamplingRate);
-	adjustClock();
+//	rt_printf("Fs: %.1f, actualTimeS: %4.6f, targetFs_ %.3f\n",
+	if((averageBufferPointer&3)==0){
+		static float oldTargetSamplingRate=0;
+		targetSamplingRate=average/101;
+		if(bufferFull>=3 && fabsf(targetSamplingRate-oldTargetSamplingRate) < 1){
+			rt_printf("%.1f, %4.6f, %.3f;\n",
+				gAudioCodec->getAudioSamplingRate(),  actualTimeS, targetSamplingRate, targetSamplingRate-oldTargetSamplingRate);
+			adjustClock();
+		}
+		oldTargetSamplingRate=targetSamplingRate;
+	}
 }
 
 void ClockSynchronizer::adjustClock(){
-	if(currentSamplingRate!= targetSamplingRate){ //TODO: actually check that the difference is less than the quantization error in the PLL
+	if(fabsf(currentSamplingRate-targetSamplingRate)>0.7){ //TODO: actually check that the difference is less than the quantization error in the PLL
 		BeagleRT_scheduleAuxiliaryTask(setClockTask);
 	}
 }