comparison core/ClockSync.cpp @ 151:e9c9404e3d1f ClockSync

Pff partially working. No PID. When setting the audio clock on the bbb to 44098 the master and slave clock keep diverging instead of converging ...
author Giulio Moro <giuliomoro@yahoo.it>
date Tue, 22 Sep 2015 04:10:07 +0100
parents 134bff10e561
children 8f98b32d0e23
comparison
equal deleted inserted replaced
150:ebbfb154351a 151:e9c9404e3d1f
263 } 263 }
264 void ClockSync::processOffset(double offset){ 264 void ClockSync::processOffset(double offset){
265 static int calls=0; 265 static int calls=0;
266 // TODO: change the flow control below so that it can happen multiple times 266 // TODO: change the flow control below so that it can happen multiple times
267 //(base it upon the length of movingAverage rather than the number of calls) 267 //(base it upon the length of movingAverage rather than the number of calls)
268 if(calls<10) { //get an initial guess 268 if(calls<30){
269 // wait for the VirtualClock to stabilize and produce meaningful outputs
270 } else if(calls<50) { //get an initial guess
269 movingAverage.add(offset); 271 movingAverage.add(offset);
270 // printf("-----------OFFSET IS : %04.4f samples, average: %04.4f samples\n", 272 // printf("-----------OFFSET IS : %04.4f samples, average: %04.4f samples\n",
271 // offset, movingAverage.getAverage()); 273 // offset, movingAverage.getAverage());
272 } else if (calls==10){ //then compensate for initial offset 274 } else if (calls==50){ //then compensate for initial offset
273 printf("compensating for offset: %f\n", offset); 275 // printf("compensating for offset: %f\n", movingAverage.getAverage());
274 virtualClock->addOffset(movingAverage.getAverage()); 276 virtualClock->addOffset(movingAverage.getAverage());
275 movingAverage.reset(); 277 movingAverage.reset();
276 } else if (calls>=10){ //use IIR filter from now on 278 } else if (calls>50){ //use IIR filter from now on
277 //filter coefficients obtained from Matlab : [B,A]=butter(2,0.005); 279 //filter coefficients obtained from Matlab : [B,A]=butter(2,0.005);
278 // static float B[3]={6.10061787580662e-05, 0.000122012357516132, 6.10061787580662e-05}; 280 static IirFilter iir(1);
279 // static float A[3]={1, -1.97778648377676, 0.978030508491796}; 281 static bool init = false;
280 static float B[3]={6.10061787580662e-05, 0.000122012357516132, 6.10061787580662e-05}; 282 if(init == false){
281 static float A[3]={1, -1.97778648377676, 0.978030508491796}; 283 // double coeffs[5]={0.00554271721028068, 0.0110854344205614, 0.00554271721028068,
282 static float pastOut[3]={0,0,0}; 284 // -1.77863177782459, 0.800802646665708};
283 static float pastIn[3]={0,0,0}; 285 double coeffs[5]={0.0200833655642113, 0.0401667311284225, 0.0200833655642113,
284 float in=offset; 286 -1.56101807580072, 0.641351538057563};
285 float out= -pastOut[1]*A[1] -pastOut[2]*A[2] +in*B[0] +pastIn[1]*B[1] +pastIn[2]*B[2]; 287 iir.setCoefficients(coeffs);
286 pastOut[2]=pastOut[1]; 288 init = true;
287 pastOut[1]=out; 289 }
288 pastIn[2]=pastIn[1]; 290 float expectedOffsetDifferenceMean = 0.2432;
289 pastIn[1]=in; 291 float expectedOffsetDifferenceStd = 6.487;
290 offset=out; 292 float nlOffset;
293 static float pastOffset = 0;
294 float offsetIncrement = offset-pastOffset;
295 if ( fabsf(offsetIncrement) > 1*expectedOffsetDifferenceStd && calls>51){
296 // non-linear filtering: remove outliers
297 nlOffset = pastOffset;
298 // printf("%f %f 0,0,0,0,0,0\n", offset,pastOffset);
299 } else {
300 nlOffset=offset;
301 }
302 pastOffset=nlOffset;
303 float iirOffset = iir.process(nlOffset);
291 static float maxOffset=0; 304 static float maxOffset=0;
292 if(calls > 0 ) { 305 static float pastIirOffset=0;
293 maxOffset=fabsf(offset) > fabsf(maxOffset) ? offset : maxOffset; 306 if( calls > 0 ) {
294 pid.setError(offset); 307 maxOffset=fabsf(iirOffset) > fabsf(maxOffset) ? iirOffset : maxOffset;
295 float correction=pid.getOutput(); 308 pid.setError(iirOffset);
309 float correction=pid.getOutput()*0.0001;
296 static float oldSamplingRate=44100; 310 static float oldSamplingRate=44100;
297 printf("%10.3f, %10.3f, %10.3f, %10.3f, %10.3f, %10.3f\n", in, offset, offset-pastOut[2], maxOffset, correction, oldSamplingRate); //unfiltered, filtered 311 printf("%10.3f, %10.3f, %10.3f, %10.3f, %10.3f, %10.3f\n",
298 // if(fabsf(offset)>3 && calls>30){ 312 offset, nlOffset, iirOffset, iirOffset - pastIirOffset, correction, oldSamplingRate); //unfiltered, filtered
299 //TODO: correct for offset 313 pastIirOffset = iirOffset;
300 // float targetSamplingRate=offset>0 ? 44095 : 44105; 314 float targetSamplingRate;
301 float targetSamplingRate = oldSamplingRate - correction; 315 static int direction=1;
302 #ifndef USE_JUCE 316 float thresholdL = -1;
303 // if(oldSamplingRate != targetSamplingRate) 317 // targetSamplingRate = oldSamplingRate - correction;
304 // gAudioCodec->setAudioSamplingRate(targetSamplingRate); 318 float thresholdH = 3;
305 #endif 319
320 targetSamplingRate = 44100;
321 if(
322 (iirOffset > thresholdH && direction == 1) ||
323 (iirOffset > thresholdL && direction == -1)
324 ){
325 targetSamplingRate = 44097;
326 direction = -1;
327 }
328 else if (
329 (iirOffset < -thresholdH && direction == -1) ||
330 (iirOffset < -thresholdL && direction == 1)
331 )
332 {
333 iirOffset = 44102;
334 direction = 1;
335 }
336 #ifndef USE_JUCE
337 if(oldSamplingRate != targetSamplingRate){
338 gAudioCodec->setAudioSamplingRate(targetSamplingRate);
339 }
340 #endif
306 oldSamplingRate=targetSamplingRate; 341 oldSamplingRate=targetSamplingRate;
307 // pastOut[1]=pastOut[2]=pastIn[1]=pastIn[2]=offset;
308 // printf("------setAudioSmplingRate to %f\n", targetSamplingRate);
309 // }
310 } 342 }
311 } 343 }
312 calls++; 344 calls++;
313 } 345 }
314 int ClockSync::masterHandleMessage(){ 346 int ClockSync::masterHandleMessage(){
328 360
329 int ClockSync::sendReceiveLoop(){ 361 int ClockSync::sendReceiveLoop(){
330 if(isSlave()==true){ 362 if(isSlave()==true){
331 //printf("Waiting for a sync clockSync\n"); 363 //printf("Waiting for a sync clockSync\n");
332 } else { //if this is master 364 } else { //if this is master
333 usleep(100000); //this times (roughly) how often sync clockSyncs are being sent. 365 usleep(30000); //this times (roughly) how often sync clockSyncs are being sent.
334 int ret=masterSendSync(); 366 int ret=masterSendSync();
335 if(ret<=0) 367 if(ret<=0)
336 return -1; 368 return -1;
337 } 369 }
338 int ret=receiveLoop(); 370 int ret=receiveLoop();