Mercurial > hg > beaglert
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(); |