Mercurial > hg > btrack
comparison src/BTrack.cpp @ 17:a31841af2bbc develop
Before this commit, the OnsetDetectionFunction class used double precision, and the BTrack class used floats. I have now made BTrack use double precision also. This works fine and the only cost of doing this is that we have to perform one array copy into floating point format so that sample rate conversion (which has to be in floating point format) can take place.
author | Adam <adamstark.uk@gmail.com> |
---|---|
date | Wed, 22 Jan 2014 02:49:29 +0000 |
parents | 73c64ca0ed23 |
children | 450c53430540 |
comparison
equal
deleted
inserted
replaced
16:73c64ca0ed23 | 17:a31841af2bbc |
---|---|
26 | 26 |
27 | 27 |
28 //======================================================================= | 28 //======================================================================= |
29 BTrack :: BTrack() | 29 BTrack :: BTrack() |
30 { | 30 { |
31 float rayparam = 43; | 31 double rayparam = 43; |
32 float pi = 3.14159265; | 32 double pi = 3.14159265; |
33 | 33 |
34 | 34 |
35 // initialise parameters | 35 // initialise parameters |
36 tightness = 5; | 36 tightness = 5; |
37 alpha = 0.9; | 37 alpha = 0.9; |
48 | 48 |
49 | 49 |
50 // create rayleigh weighting vector | 50 // create rayleigh weighting vector |
51 for (int n = 0;n < 128;n++) | 51 for (int n = 0;n < 128;n++) |
52 { | 52 { |
53 wv[n] = ((float) n / pow(rayparam,2)) * exp((-1*pow((float)-n,2)) / (2*pow(rayparam,2))); | 53 wv[n] = ((double) n / pow(rayparam,2)) * exp((-1*pow((double)-n,2)) / (2*pow(rayparam,2))); |
54 } | 54 } |
55 | 55 |
56 // initialise prev_delta | 56 // initialise prev_delta |
57 for (int i = 0;i < 41;i++) | 57 for (int i = 0;i < 41;i++) |
58 { | 58 { |
59 prev_delta[i] = 1; | 59 prev_delta[i] = 1; |
60 } | 60 } |
61 | 61 |
62 float t_mu = 41/2; | 62 double t_mu = 41/2; |
63 float m_sig; | 63 double m_sig; |
64 float x; | 64 double x; |
65 // create tempo transition matrix | 65 // create tempo transition matrix |
66 m_sig = 41/8; | 66 m_sig = 41/8; |
67 for (int i = 0;i < 41;i++) | 67 for (int i = 0;i < 41;i++) |
68 { | 68 { |
69 for (int j = 0;j < 41;j++) | 69 for (int j = 0;j < 41;j++) |
90 void BTrack :: initialise(int fsize) | 90 void BTrack :: initialise(int fsize) |
91 { | 91 { |
92 framesize = fsize; | 92 framesize = fsize; |
93 dfbuffer_size = (512*512)/fsize; // calculate df buffer size | 93 dfbuffer_size = (512*512)/fsize; // calculate df buffer size |
94 | 94 |
95 bperiod = round(60/((((float) fsize)/44100)*tempo)); | 95 bperiod = round(60/((((double) fsize)/44100)*tempo)); |
96 | 96 |
97 dfbuffer = new float[dfbuffer_size]; // create df_buffer | 97 dfbuffer = new double[dfbuffer_size]; // create df_buffer |
98 cumscore = new float[dfbuffer_size]; // create cumscore | 98 cumscore = new double[dfbuffer_size]; // create cumscore |
99 | 99 |
100 | 100 |
101 // initialise df_buffer to zeros | 101 // initialise df_buffer to zeros |
102 for (int i = 0;i < dfbuffer_size;i++) | 102 for (int i = 0;i < dfbuffer_size;i++) |
103 { | 103 { |
111 } | 111 } |
112 } | 112 } |
113 } | 113 } |
114 | 114 |
115 //======================================================================= | 115 //======================================================================= |
116 void BTrack :: process(float df_sample) | 116 void BTrack :: process(double df_sample) |
117 { | 117 { |
118 m0--; | 118 m0--; |
119 beat--; | 119 beat--; |
120 playbeat = 0; | 120 playbeat = 0; |
121 | 121 |
147 calcTempo(); | 147 calcTempo(); |
148 } | 148 } |
149 } | 149 } |
150 | 150 |
151 //======================================================================= | 151 //======================================================================= |
152 void BTrack :: settempo(float tempo) | 152 void BTrack :: settempo(double tempo) |
153 { | 153 { |
154 | 154 |
155 /////////// TEMPO INDICATION RESET ////////////////// | 155 /////////// TEMPO INDICATION RESET ////////////////// |
156 | 156 |
157 // firstly make sure tempo is between 80 and 160 bpm.. | 157 // firstly make sure tempo is between 80 and 160 bpm.. |
179 | 179 |
180 | 180 |
181 /////////// CUMULATIVE SCORE ARTIFICAL TEMPO UPDATE ////////////////// | 181 /////////// CUMULATIVE SCORE ARTIFICAL TEMPO UPDATE ////////////////// |
182 | 182 |
183 // calculate new beat period | 183 // calculate new beat period |
184 int new_bperiod = (int) round(60/((((float) framesize)/44100)*tempo)); | 184 int new_bperiod = (int) round(60/((((double) framesize)/44100)*tempo)); |
185 | 185 |
186 int bcounter = 1; | 186 int bcounter = 1; |
187 // initialise df_buffer to zeros | 187 // initialise df_buffer to zeros |
188 for (int i = (dfbuffer_size-1);i >= 0;i--) | 188 for (int i = (dfbuffer_size-1);i >= 0;i--) |
189 { | 189 { |
210 | 210 |
211 // beat is now | 211 // beat is now |
212 beat = 0; | 212 beat = 0; |
213 | 213 |
214 // offbeat is half of new beat period away | 214 // offbeat is half of new beat period away |
215 m0 = (int) round(((float) new_bperiod)/2); | 215 m0 = (int) round(((double) new_bperiod)/2); |
216 } | 216 } |
217 | 217 |
218 //======================================================================= | 218 //======================================================================= |
219 void BTrack :: fixtempo(float tempo) | 219 void BTrack :: fixtempo(double tempo) |
220 { | 220 { |
221 // firstly make sure tempo is between 80 and 160 bpm.. | 221 // firstly make sure tempo is between 80 and 160 bpm.. |
222 while (tempo > 160) | 222 while (tempo > 160) |
223 { | 223 { |
224 tempo = tempo/2; | 224 tempo = tempo/2; |
254 | 254 |
255 //======================================================================= | 255 //======================================================================= |
256 void BTrack :: dfconvert() | 256 void BTrack :: dfconvert() |
257 { | 257 { |
258 float output[512]; | 258 float output[512]; |
259 float input[dfbuffer_size]; | |
260 | |
261 for (int i = 0;i < dfbuffer_size;i++) | |
262 { | |
263 input[i] = (float) dfbuffer[i]; | |
264 } | |
259 | 265 |
260 double src_ratio = 512.0/((double) dfbuffer_size); | 266 double src_ratio = 512.0/((double) dfbuffer_size); |
261 int BUFFER_LEN = dfbuffer_size; | 267 int BUFFER_LEN = dfbuffer_size; |
262 int output_len; | 268 int output_len; |
263 SRC_DATA src_data ; | 269 SRC_DATA src_data ; |
264 | 270 |
265 //output_len = (int) floor (((double) BUFFER_LEN) * src_ratio) ; | 271 //output_len = (int) floor (((double) BUFFER_LEN) * src_ratio) ; |
266 output_len = 512; | 272 output_len = 512; |
267 | 273 |
268 src_data.data_in = dfbuffer; | 274 src_data.data_in = input; |
269 src_data.input_frames = BUFFER_LEN; | 275 src_data.input_frames = BUFFER_LEN; |
270 | 276 |
271 src_data.src_ratio = src_ratio; | 277 src_data.src_ratio = src_ratio; |
272 | 278 |
273 src_data.data_out = output; | 279 src_data.data_out = output; |
275 | 281 |
276 src_simple (&src_data, SRC_SINC_BEST_QUALITY, 1); | 282 src_simple (&src_data, SRC_SINC_BEST_QUALITY, 1); |
277 | 283 |
278 for (int i = 0;i < output_len;i++) | 284 for (int i = 0;i < output_len;i++) |
279 { | 285 { |
280 df512[i] = src_data.data_out[i]; | 286 df512[i] = (double) src_data.data_out[i]; |
281 } | 287 } |
282 } | 288 } |
283 | 289 |
284 //======================================================================= | 290 //======================================================================= |
285 void BTrack :: calcTempo() | 291 void BTrack :: calcTempo() |
301 int t_index; | 307 int t_index; |
302 int t_index2; | 308 int t_index2; |
303 // calculate tempo observation vector from bperiod observation vector | 309 // calculate tempo observation vector from bperiod observation vector |
304 for (int i = 0;i < 41;i++) | 310 for (int i = 0;i < 41;i++) |
305 { | 311 { |
306 t_index = (int) round(p_fact / ((float) ((2*i)+80))); | 312 t_index = (int) round(p_fact / ((double) ((2*i)+80))); |
307 t_index2 = (int) round(p_fact / ((float) ((4*i)+160))); | 313 t_index2 = (int) round(p_fact / ((double) ((4*i)+160))); |
308 | 314 |
309 | 315 |
310 t_obs[i] = rcf[t_index-1] + rcf[t_index2-1]; | 316 t_obs[i] = rcf[t_index-1] + rcf[t_index2-1]; |
311 } | 317 } |
312 | 318 |
313 | 319 |
314 float maxval; | 320 double maxval; |
315 float maxind; | 321 double maxind; |
316 float curval; | 322 double curval; |
317 | 323 |
318 // if tempo is fixed then always use a fixed set of tempi as the previous observation probability function | 324 // if tempo is fixed then always use a fixed set of tempi as the previous observation probability function |
319 if (tempofix == 1) | 325 if (tempofix == 1) |
320 { | 326 { |
321 for (int k = 0;k < 41;k++) | 327 for (int k = 0;k < 41;k++) |
355 } | 361 } |
356 | 362 |
357 prev_delta[j] = delta[j]; | 363 prev_delta[j] = delta[j]; |
358 } | 364 } |
359 | 365 |
360 bperiod = round((60.0*44100.0)/(((2*maxind)+80)*((float) framesize))); | 366 bperiod = round((60.0*44100.0)/(((2*maxind)+80)*((double) framesize))); |
361 | 367 |
362 if (bperiod > 0) | 368 if (bperiod > 0) |
363 { | 369 { |
364 est_tempo = 60.0/((((float) framesize) / 44100.0)*bperiod); | 370 est_tempo = 60.0/((((double) framesize) / 44100.0)*bperiod); |
365 } | 371 } |
366 | 372 |
367 //cout << bperiod << endl; | 373 //cout << bperiod << endl; |
368 } | 374 } |
369 | 375 |
370 //======================================================================= | 376 //======================================================================= |
371 void BTrack :: adapt_thresh(float *x,int N) | 377 void BTrack :: adapt_thresh(double *x,int N) |
372 { | 378 { |
373 //int N = 512; // length of df | 379 //int N = 512; // length of df |
374 int i = 0; | 380 int i = 0; |
375 int k,t = 0; | 381 int k,t = 0; |
376 float x_thresh[N]; | 382 double x_thresh[N]; |
377 | 383 |
378 int p_post = 7; | 384 int p_post = 7; |
379 int p_pre = 8; | 385 int p_pre = 8; |
380 | 386 |
381 t = std::min(N,p_post); // what is smaller, p_post of df size. This is to avoid accessing outside of arrays | 387 t = std::min(N,p_post); // what is smaller, p_post of df size. This is to avoid accessing outside of arrays |
432 } | 438 } |
433 } | 439 } |
434 } | 440 } |
435 | 441 |
436 //======================================================================= | 442 //======================================================================= |
437 void BTrack :: acf_bal(float *df_thresh) | 443 void BTrack :: acf_bal(double *df_thresh) |
438 { | 444 { |
439 int l, n = 0; | 445 int l, n = 0; |
440 float sum, tmp; | 446 double sum, tmp; |
441 | 447 |
442 // for l lags from 0-511 | 448 // for l lags from 0-511 |
443 for (l = 0;l < 512;l++) | 449 for (l = 0;l < 512;l++) |
444 { | 450 { |
445 sum = 0; | 451 sum = 0; |
454 acf[l] = sum / (512-l); // weight by number of mults and add to acf buffer | 460 acf[l] = sum / (512-l); // weight by number of mults and add to acf buffer |
455 } | 461 } |
456 } | 462 } |
457 | 463 |
458 //======================================================================= | 464 //======================================================================= |
459 float BTrack :: mean_array(float *array,int start,int end) | 465 double BTrack :: mean_array(double *array,int start,int end) |
460 { | 466 { |
461 int i; | 467 int i; |
462 double sum = 0; | 468 double sum = 0; |
463 | 469 |
464 int length = end - start; | 470 int length = end - start; |
478 return 0; | 484 return 0; |
479 } | 485 } |
480 } | 486 } |
481 | 487 |
482 //======================================================================= | 488 //======================================================================= |
483 void BTrack :: normalise(float *array,int N) | 489 void BTrack :: normalise(double *array,int N) |
484 { | 490 { |
485 double sum = 0; | 491 double sum = 0; |
486 | 492 |
487 for (int i = 0;i < N;i++) | 493 for (int i = 0;i < N;i++) |
488 { | 494 { |
500 } | 506 } |
501 } | 507 } |
502 } | 508 } |
503 | 509 |
504 //======================================================================= | 510 //======================================================================= |
505 void BTrack :: updatecumscore(float df_sample) | 511 void BTrack :: updatecumscore(double df_sample) |
506 { | 512 { |
507 int start, end, winsize; | 513 int start, end, winsize; |
508 float max; | 514 double max; |
509 | 515 |
510 start = dfbuffer_size - round(2*bperiod); | 516 start = dfbuffer_size - round(2*bperiod); |
511 end = dfbuffer_size - round(bperiod/2); | 517 end = dfbuffer_size - round(bperiod/2); |
512 winsize = end-start+1; | 518 winsize = end-start+1; |
513 | 519 |
514 float w1[winsize]; | 520 double w1[winsize]; |
515 float v = -2*bperiod; | 521 double v = -2*bperiod; |
516 float wcumscore; | 522 double wcumscore; |
517 | 523 |
518 | 524 |
519 // create window | 525 // create window |
520 for (int i = 0;i < winsize;i++) | 526 for (int i = 0;i < winsize;i++) |
521 { | 527 { |
555 | 561 |
556 //======================================================================= | 562 //======================================================================= |
557 void BTrack :: predictbeat() | 563 void BTrack :: predictbeat() |
558 { | 564 { |
559 int winsize = (int) bperiod; | 565 int winsize = (int) bperiod; |
560 float fcumscore[dfbuffer_size + winsize]; | 566 double fcumscore[dfbuffer_size + winsize]; |
561 float w2[winsize]; | 567 double w2[winsize]; |
562 // copy cumscore to first part of fcumscore | 568 // copy cumscore to first part of fcumscore |
563 for (int i = 0;i < dfbuffer_size;i++) | 569 for (int i = 0;i < dfbuffer_size;i++) |
564 { | 570 { |
565 fcumscore[i] = cumscore[i]; | 571 fcumscore[i] = cumscore[i]; |
566 } | 572 } |
567 | 573 |
568 // create future window | 574 // create future window |
569 float v = 1; | 575 double v = 1; |
570 for (int i = 0;i < winsize;i++) | 576 for (int i = 0;i < winsize;i++) |
571 { | 577 { |
572 w2[i] = exp((-1*pow((v - (bperiod/2)),2)) / (2*pow((bperiod/2) ,2))); | 578 w2[i] = exp((-1*pow((v - (bperiod/2)),2)) / (2*pow((bperiod/2) ,2))); |
573 v++; | 579 v++; |
574 } | 580 } |
576 // create past window | 582 // create past window |
577 v = -2*bperiod; | 583 v = -2*bperiod; |
578 int start = dfbuffer_size - round(2*bperiod); | 584 int start = dfbuffer_size - round(2*bperiod); |
579 int end = dfbuffer_size - round(bperiod/2); | 585 int end = dfbuffer_size - round(bperiod/2); |
580 int pastwinsize = end-start+1; | 586 int pastwinsize = end-start+1; |
581 float w1[pastwinsize]; | 587 double w1[pastwinsize]; |
582 | 588 |
583 for (int i = 0;i < pastwinsize;i++) | 589 for (int i = 0;i < pastwinsize;i++) |
584 { | 590 { |
585 w1[i] = exp((-1*pow(tightness*log(-v/bperiod),2))/2); | 591 w1[i] = exp((-1*pow(tightness*log(-v/bperiod),2))/2); |
586 v = v+1; | 592 v = v+1; |
587 } | 593 } |
588 | 594 |
589 | 595 |
590 | 596 |
591 // calculate future cumulative score | 597 // calculate future cumulative score |
592 float max; | 598 double max; |
593 int n; | 599 int n; |
594 float wcumscore; | 600 double wcumscore; |
595 for (int i = dfbuffer_size;i < (dfbuffer_size+winsize);i++) | 601 for (int i = dfbuffer_size;i < (dfbuffer_size+winsize);i++) |
596 { | 602 { |
597 start = i - round(2*bperiod); | 603 start = i - round(2*bperiod); |
598 end = i - round(bperiod/2); | 604 end = i - round(bperiod/2); |
599 | 605 |
629 } | 635 } |
630 | 636 |
631 n++; | 637 n++; |
632 } | 638 } |
633 | 639 |
634 | |
635 // set beat | |
636 //beat = beat; | |
637 | |
638 // set next prediction time | 640 // set next prediction time |
639 m0 = beat+round(bperiod/2); | 641 m0 = beat+round(bperiod/2); |
640 | 642 |
641 | 643 |
642 } | 644 } |