Mercurial > hg > beaglert
changeset 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 | e77e2e712fbc |
files | core/ClockSynchronizer.cpp core/ReceiveAudioThread.cpp projects/scope/render.cpp |
diffstat | 3 files changed, 43 insertions(+), 14 deletions(-) [+] |
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); } }
--- a/core/ReceiveAudioThread.cpp Thu Aug 27 01:42:04 2015 +0100 +++ b/core/ReceiveAudioThread.cpp Thu Aug 27 03:33:32 2015 +0100 @@ -202,11 +202,18 @@ return -2; if(isListening()==false) return -1; - if(writePointer<0){ //if writePointer has not been initalized yet ... + static int numCalls=0; + if(writePointer<0 || (numCalls&16383)==0){ //if writePointer has not been initalized yet ... +#ifdef USE_JUCE +#else //debug + rt_printf("reinit the writePointer, readPointer: %f;\n",readPointer); + readPointer=0; +#endif /* USE_JUCE */ writePointer=2*length; // do it, so that it starts writing at a safety margin from where we write. // This will help keeping them in sync. //TODO: handle what happens when the remote stream is interrupted and then restarted } + numCalls++; if(length>lastValidPointer) { //not enough samples available, we fill the buffer with what is available, but the destination buffer will not be filled completely //at this very moment the other thread might be writing at most one payload into the buffer.
--- a/projects/scope/render.cpp Thu Aug 27 01:42:04 2015 +0100 +++ b/projects/scope/render.cpp Thu Aug 27 03:33:32 2015 +0100 @@ -54,7 +54,7 @@ static int count=0; // if((count&262143)==0){ // static int nextCall=160000; - if( ((count&(16384-1))==0 /*&& count>200000*/)){ + if( ((count&(2047-1))==0 /*&& count>200000*/)){ // rt_printf("b %d\n", count); clockSynchronizer.update(networkSend.getTimestamp(), receiveAudio0.getTimestamp(), receiveAudio0.getLastTime()); // nextCall=count+100000; @@ -64,8 +64,8 @@ // clockSynchronizer.update(networkSend.getTimestamp(), receiveAudio0.getTimestamp(), receiveAudio0.getLastTime()); // } if(count==0){ - gAudioCodec->setAudioSamplingRate(44080); - printf("startHread\n"); + gAudioCodec->setAudioSamplingRate( 44101); + rt_printf("startHread\n"); ReceiveAudioThread::startThread(); } for(unsigned int n = 0; n < context->audioFrames; n++) {