annotate src/BTrack.cpp @ 52:45231107c9d6

Reformatted comments, removed the OnsetDetectionFunction constructor with no arguments, removed a number of unused variables and made changes to the python module to fix some casting problems and removed some unused variables there also. Still getting the same results, so no overall changes to the algorithm.
author Adam Stark <adamstark@users.noreply.github.com>
date Wed, 22 Jan 2014 01:13:45 +0000
parents 68d01fea1e8d
children 338f5eb29e41
rev   line source
adamstark@46 1 //=======================================================================
adamstark@46 2 /** @file BTrack.cpp
adamstark@47 3 * @brief BTrack - a real-time beat tracker
adamstark@46 4 * @author Adam Stark
adamstark@46 5 * @copyright Copyright (C) 2008-2014 Queen Mary University of London
adamstark@46 6 *
adamstark@46 7 * This program is free software: you can redistribute it and/or modify
adamstark@46 8 * it under the terms of the GNU General Public License as published by
adamstark@46 9 * the Free Software Foundation, either version 3 of the License, or
adamstark@46 10 * (at your option) any later version.
adamstark@46 11 *
adamstark@46 12 * This program is distributed in the hope that it will be useful,
adamstark@46 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
adamstark@46 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
adamstark@46 15 * GNU General Public License for more details.
adamstark@46 16 *
adamstark@46 17 * You should have received a copy of the GNU General Public License
adamstark@46 18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
adamstark@46 19 */
adamstark@46 20 //=======================================================================
adamstark@46 21
adamstark@46 22 #include <cmath>
adamstark@52 23 #include <algorithm>
adamstark@46 24 #include "BTrack.h"
adamstark@46 25 #include "samplerate.h"
adamstark@46 26
adamstark@46 27
adamstark@51 28 //=======================================================================
adamstark@46 29 BTrack :: BTrack()
adamstark@46 30 {
adamstark@46 31 float rayparam = 43;
adamstark@46 32 float pi = 3.14159265;
adamstark@46 33
adamstark@46 34
adamstark@46 35 // initialise parameters
adamstark@46 36 tightness = 5;
adamstark@46 37 alpha = 0.9;
adamstark@46 38 tempo = 120;
adamstark@46 39 est_tempo = 120;
adamstark@46 40 p_fact = 60.*44100./512.;
adamstark@46 41
adamstark@46 42 m0 = 10;
adamstark@46 43 beat = -1;
adamstark@46 44
adamstark@46 45 playbeat = 0;
adamstark@46 46
adamstark@46 47
adamstark@46 48
adamstark@46 49
adamstark@46 50 // create rayleigh weighting vector
adamstark@46 51 for (int n = 0;n < 128;n++)
adamstark@46 52 {
adamstark@46 53 wv[n] = ((float) n / pow(rayparam,2)) * exp((-1*pow((float)-n,2)) / (2*pow(rayparam,2)));
adamstark@46 54 }
adamstark@46 55
adamstark@46 56 // initialise prev_delta
adamstark@46 57 for (int i = 0;i < 41;i++)
adamstark@46 58 {
adamstark@46 59 prev_delta[i] = 1;
adamstark@46 60 }
adamstark@46 61
adamstark@46 62 float t_mu = 41/2;
adamstark@46 63 float m_sig;
adamstark@46 64 float x;
adamstark@46 65 // create tempo transition matrix
adamstark@46 66 m_sig = 41/8;
adamstark@46 67 for (int i = 0;i < 41;i++)
adamstark@46 68 {
adamstark@46 69 for (int j = 0;j < 41;j++)
adamstark@46 70 {
adamstark@46 71 x = j+1;
adamstark@46 72 t_mu = i+1;
adamstark@46 73 t_tmat[i][j] = (1 / (m_sig * sqrt(2*pi))) * exp( (-1*pow((x-t_mu),2)) / (2*pow(m_sig,2)) );
adamstark@46 74 }
adamstark@46 75 }
adamstark@46 76
adamstark@46 77 // tempo is not fixed
adamstark@46 78 tempofix = 0;
adamstark@46 79 }
adamstark@46 80
adamstark@51 81 //=======================================================================
adamstark@46 82 BTrack :: ~BTrack()
adamstark@46 83 {
adamstark@46 84
adamstark@46 85 }
adamstark@46 86
adamstark@51 87
adamstark@51 88
adamstark@51 89 //=======================================================================
adamstark@46 90 void BTrack :: initialise(int fsize)
adamstark@46 91 {
adamstark@46 92 framesize = fsize;
adamstark@46 93 dfbuffer_size = (512*512)/fsize; // calculate df buffer size
adamstark@46 94
adamstark@46 95 bperiod = round(60/((((float) fsize)/44100)*tempo));
adamstark@46 96
adamstark@46 97 dfbuffer = new float[dfbuffer_size]; // create df_buffer
adamstark@46 98 cumscore = new float[dfbuffer_size]; // create cumscore
adamstark@46 99
adamstark@46 100
adamstark@46 101 // initialise df_buffer to zeros
adamstark@46 102 for (int i = 0;i < dfbuffer_size;i++)
adamstark@46 103 {
adamstark@46 104 dfbuffer[i] = 0;
adamstark@46 105 cumscore[i] = 0;
adamstark@46 106
adamstark@46 107
adamstark@46 108 if ((i % ((int) round(bperiod))) == 0)
adamstark@46 109 {
adamstark@46 110 dfbuffer[i] = 1;
adamstark@46 111 }
adamstark@46 112 }
adamstark@46 113 }
adamstark@46 114
adamstark@51 115 //=======================================================================
adamstark@46 116 void BTrack :: process(float df_sample)
adamstark@46 117 {
adamstark@46 118 m0--;
adamstark@46 119 beat--;
adamstark@46 120 playbeat = 0;
adamstark@46 121
adamstark@46 122 // move all samples back one step
adamstark@46 123 for (int i=0;i < (dfbuffer_size-1);i++)
adamstark@46 124 {
adamstark@46 125 dfbuffer[i] = dfbuffer[i+1];
adamstark@46 126 }
adamstark@46 127
adamstark@46 128 // add new sample at the end
adamstark@46 129 dfbuffer[dfbuffer_size-1] = df_sample;
adamstark@46 130
adamstark@46 131 // update cumulative score
adamstark@46 132 updatecumscore(df_sample);
adamstark@46 133
adamstark@46 134 // if we are halfway between beats
adamstark@46 135 if (m0 == 0)
adamstark@46 136 {
adamstark@46 137 predictbeat();
adamstark@46 138 }
adamstark@46 139
adamstark@46 140 // if we are at a beat
adamstark@46 141 if (beat == 0)
adamstark@46 142 {
adamstark@46 143 playbeat = 1; // indicate a beat should be output
adamstark@46 144
adamstark@46 145 // recalculate the tempo
adamstark@46 146 dfconvert();
adamstark@46 147 calcTempo();
adamstark@46 148 }
adamstark@46 149 }
adamstark@46 150
adamstark@51 151 //=======================================================================
adamstark@46 152 void BTrack :: settempo(float tempo)
adamstark@46 153 {
adamstark@46 154
adamstark@46 155 /////////// TEMPO INDICATION RESET //////////////////
adamstark@46 156
adamstark@46 157 // firstly make sure tempo is between 80 and 160 bpm..
adamstark@46 158 while (tempo > 160)
adamstark@46 159 {
adamstark@46 160 tempo = tempo/2;
adamstark@46 161 }
adamstark@46 162
adamstark@46 163 while (tempo < 80)
adamstark@46 164 {
adamstark@46 165 tempo = tempo * 2;
adamstark@46 166 }
adamstark@46 167
adamstark@46 168 // convert tempo from bpm value to integer index of tempo probability
adamstark@46 169 int tempo_index = (int) round((tempo - 80)/2);
adamstark@46 170
adamstark@46 171 // now set previous tempo observations to zero
adamstark@46 172 for (int i=0;i < 41;i++)
adamstark@46 173 {
adamstark@46 174 prev_delta[i] = 0;
adamstark@46 175 }
adamstark@46 176
adamstark@46 177 // set desired tempo index to 1
adamstark@46 178 prev_delta[tempo_index] = 1;
adamstark@46 179
adamstark@46 180
adamstark@46 181 /////////// CUMULATIVE SCORE ARTIFICAL TEMPO UPDATE //////////////////
adamstark@46 182
adamstark@46 183 // calculate new beat period
adamstark@46 184 int new_bperiod = (int) round(60/((((float) framesize)/44100)*tempo));
adamstark@46 185
adamstark@46 186 int bcounter = 1;
adamstark@46 187 // initialise df_buffer to zeros
adamstark@46 188 for (int i = (dfbuffer_size-1);i >= 0;i--)
adamstark@46 189 {
adamstark@46 190 if (bcounter == 1)
adamstark@46 191 {
adamstark@46 192 cumscore[i] = 150;
adamstark@46 193 dfbuffer[i] = 150;
adamstark@46 194 }
adamstark@46 195 else
adamstark@46 196 {
adamstark@46 197 cumscore[i] = 10;
adamstark@46 198 dfbuffer[i] = 10;
adamstark@46 199 }
adamstark@46 200
adamstark@46 201 bcounter++;
adamstark@46 202
adamstark@46 203 if (bcounter > new_bperiod)
adamstark@46 204 {
adamstark@46 205 bcounter = 1;
adamstark@46 206 }
adamstark@46 207 }
adamstark@46 208
adamstark@46 209 /////////// INDICATE THAT THIS IS A BEAT //////////////////
adamstark@46 210
adamstark@46 211 // beat is now
adamstark@46 212 beat = 0;
adamstark@46 213
adamstark@46 214 // offbeat is half of new beat period away
adamstark@46 215 m0 = (int) round(((float) new_bperiod)/2);
adamstark@46 216 }
adamstark@46 217
adamstark@51 218 //=======================================================================
adamstark@46 219 void BTrack :: fixtempo(float tempo)
adamstark@46 220 {
adamstark@46 221 // firstly make sure tempo is between 80 and 160 bpm..
adamstark@46 222 while (tempo > 160)
adamstark@46 223 {
adamstark@46 224 tempo = tempo/2;
adamstark@46 225 }
adamstark@46 226
adamstark@46 227 while (tempo < 80)
adamstark@46 228 {
adamstark@46 229 tempo = tempo * 2;
adamstark@46 230 }
adamstark@46 231
adamstark@46 232 // convert tempo from bpm value to integer index of tempo probability
adamstark@46 233 int tempo_index = (int) round((tempo - 80)/2);
adamstark@46 234
adamstark@46 235 // now set previous fixed previous tempo observation values to zero
adamstark@46 236 for (int i=0;i < 41;i++)
adamstark@46 237 {
adamstark@46 238 prev_delta_fix[i] = 0;
adamstark@46 239 }
adamstark@46 240
adamstark@46 241 // set desired tempo index to 1
adamstark@46 242 prev_delta_fix[tempo_index] = 1;
adamstark@46 243
adamstark@46 244 // set the tempo fix flag
adamstark@46 245 tempofix = 1;
adamstark@46 246 }
adamstark@46 247
adamstark@51 248 //=======================================================================
adamstark@46 249 void BTrack :: unfixtempo()
adamstark@46 250 {
adamstark@46 251 // set the tempo fix flag
adamstark@46 252 tempofix = 0;
adamstark@46 253 }
adamstark@46 254
adamstark@51 255 //=======================================================================
adamstark@46 256 void BTrack :: dfconvert()
adamstark@46 257 {
adamstark@46 258 float output[512];
adamstark@46 259
adamstark@46 260 double src_ratio = 512.0/((double) dfbuffer_size);
adamstark@46 261 int BUFFER_LEN = dfbuffer_size;
adamstark@46 262 int output_len;
adamstark@46 263 SRC_DATA src_data ;
adamstark@46 264
adamstark@46 265 //output_len = (int) floor (((double) BUFFER_LEN) * src_ratio) ;
adamstark@46 266 output_len = 512;
adamstark@46 267
adamstark@46 268 src_data.data_in = dfbuffer;
adamstark@46 269 src_data.input_frames = BUFFER_LEN;
adamstark@46 270
adamstark@46 271 src_data.src_ratio = src_ratio;
adamstark@46 272
adamstark@46 273 src_data.data_out = output;
adamstark@46 274 src_data.output_frames = output_len;
adamstark@46 275
adamstark@46 276 src_simple (&src_data, SRC_SINC_BEST_QUALITY, 1);
adamstark@46 277
adamstark@46 278 for (int i = 0;i < output_len;i++)
adamstark@46 279 {
adamstark@46 280 df512[i] = src_data.data_out[i];
adamstark@46 281 }
adamstark@46 282 }
adamstark@46 283
adamstark@51 284 //=======================================================================
adamstark@46 285 void BTrack :: calcTempo()
adamstark@46 286 {
adamstark@46 287 // adaptive threshold on input
adamstark@46 288 adapt_thresh(df512,512);
adamstark@46 289
adamstark@46 290 // calculate auto-correlation function of detection function
adamstark@46 291 acf_bal(df512);
adamstark@46 292
adamstark@46 293 // calculate output of comb filterbank
adamstark@46 294 getrcfoutput();
adamstark@46 295
adamstark@46 296
adamstark@46 297 // adaptive threshold on rcf
adamstark@46 298 adapt_thresh(rcf,128);
adamstark@46 299
adamstark@46 300
adamstark@46 301 int t_index;
adamstark@46 302 int t_index2;
adamstark@46 303 // calculate tempo observation vector from bperiod observation vector
adamstark@46 304 for (int i = 0;i < 41;i++)
adamstark@46 305 {
adamstark@46 306 t_index = (int) round(p_fact / ((float) ((2*i)+80)));
adamstark@46 307 t_index2 = (int) round(p_fact / ((float) ((4*i)+160)));
adamstark@46 308
adamstark@46 309
adamstark@46 310 t_obs[i] = rcf[t_index-1] + rcf[t_index2-1];
adamstark@46 311 }
adamstark@46 312
adamstark@46 313
adamstark@46 314 float maxval;
adamstark@46 315 float maxind;
adamstark@46 316 float curval;
adamstark@46 317
adamstark@46 318 // if tempo is fixed then always use a fixed set of tempi as the previous observation probability function
adamstark@46 319 if (tempofix == 1)
adamstark@46 320 {
adamstark@46 321 for (int k = 0;k < 41;k++)
adamstark@46 322 {
adamstark@46 323 prev_delta[k] = prev_delta_fix[k];
adamstark@46 324 }
adamstark@46 325 }
adamstark@46 326
adamstark@46 327 for (int j=0;j < 41;j++)
adamstark@46 328 {
adamstark@46 329 maxval = -1;
adamstark@46 330 for (int i = 0;i < 41;i++)
adamstark@46 331 {
adamstark@46 332 curval = prev_delta[i]*t_tmat[i][j];
adamstark@46 333
adamstark@46 334 if (curval > maxval)
adamstark@46 335 {
adamstark@46 336 maxval = curval;
adamstark@46 337 }
adamstark@46 338 }
adamstark@46 339
adamstark@46 340 delta[j] = maxval*t_obs[j];
adamstark@46 341 }
adamstark@46 342
adamstark@46 343
adamstark@46 344 normalise(delta,41);
adamstark@46 345
adamstark@46 346 maxind = -1;
adamstark@46 347 maxval = -1;
adamstark@46 348
adamstark@46 349 for (int j=0;j < 41;j++)
adamstark@46 350 {
adamstark@46 351 if (delta[j] > maxval)
adamstark@46 352 {
adamstark@46 353 maxval = delta[j];
adamstark@46 354 maxind = j;
adamstark@46 355 }
adamstark@46 356
adamstark@46 357 prev_delta[j] = delta[j];
adamstark@46 358 }
adamstark@46 359
adamstark@46 360 bperiod = round((60.0*44100.0)/(((2*maxind)+80)*((float) framesize)));
adamstark@46 361
adamstark@46 362 if (bperiod > 0)
adamstark@46 363 {
adamstark@46 364 est_tempo = 60.0/((((float) framesize) / 44100.0)*bperiod);
adamstark@46 365 }
adamstark@46 366
adamstark@46 367 //cout << bperiod << endl;
adamstark@46 368 }
adamstark@46 369
adamstark@51 370 //=======================================================================
adamstark@46 371 void BTrack :: adapt_thresh(float x[],int N)
adamstark@46 372 {
adamstark@46 373 //int N = 512; // length of df
adamstark@46 374 int i = 0;
adamstark@46 375 int k,t = 0;
adamstark@46 376 float x_thresh[N];
adamstark@46 377
adamstark@46 378 int p_post = 7;
adamstark@46 379 int p_pre = 8;
adamstark@46 380
adamstark@52 381 t = std::min(N,p_post); // what is smaller, p_post of df size. This is to avoid accessing outside of arrays
adamstark@46 382
adamstark@46 383 // find threshold for first 't' samples, where a full average cannot be computed yet
adamstark@46 384 for (i = 0;i <= t;i++)
adamstark@46 385 {
adamstark@52 386 k = std::min((i+p_pre),N);
adamstark@46 387 x_thresh[i] = mean_array(x,1,k);
adamstark@46 388 }
adamstark@46 389 // find threshold for bulk of samples across a moving average from [i-p_pre,i+p_post]
adamstark@46 390 for (i = t+1;i < N-p_post;i++)
adamstark@46 391 {
adamstark@46 392 x_thresh[i] = mean_array(x,i-p_pre,i+p_post);
adamstark@46 393 }
adamstark@46 394 // for last few samples calculate threshold, again, not enough samples to do as above
adamstark@46 395 for (i = N-p_post;i < N;i++)
adamstark@46 396 {
adamstark@52 397 k = std::max((i-p_post),1);
adamstark@46 398 x_thresh[i] = mean_array(x,k,N);
adamstark@46 399 }
adamstark@46 400
adamstark@46 401 // subtract the threshold from the detection function and check that it is not less than 0
adamstark@46 402 for (i = 0;i < N;i++)
adamstark@46 403 {
adamstark@46 404 x[i] = x[i] - x_thresh[i];
adamstark@46 405 if (x[i] < 0)
adamstark@46 406 {
adamstark@46 407 x[i] = 0;
adamstark@46 408 }
adamstark@46 409 }
adamstark@46 410 }
adamstark@46 411
adamstark@51 412 //=======================================================================
adamstark@46 413 void BTrack :: getrcfoutput()
adamstark@46 414 {
adamstark@46 415 int numelem;
adamstark@46 416
adamstark@46 417 for (int i = 0;i < 128;i++)
adamstark@46 418 {
adamstark@46 419 rcf[i] = 0;
adamstark@46 420 }
adamstark@46 421
adamstark@46 422 numelem = 4;
adamstark@46 423
adamstark@46 424 for (int i = 2;i <= 127;i++) // max beat period
adamstark@46 425 {
adamstark@46 426 for (int a = 1;a <= numelem;a++) // number of comb elements
adamstark@46 427 {
adamstark@46 428 for (int b = 1-a;b <= a-1;b++) // general state using normalisation of comb elements
adamstark@46 429 {
adamstark@46 430 rcf[i-1] = rcf[i-1] + (acf[(a*i+b)-1]*wv[i-1])/(2*a-1); // calculate value for comb filter row
adamstark@46 431 }
adamstark@46 432 }
adamstark@46 433 }
adamstark@46 434 }
adamstark@46 435
adamstark@51 436 //=======================================================================
adamstark@46 437 void BTrack :: acf_bal(float df_thresh[])
adamstark@46 438 {
adamstark@46 439 int l, n = 0;
adamstark@46 440 float sum, tmp;
adamstark@46 441
adamstark@46 442 // for l lags from 0-511
adamstark@46 443 for (l = 0;l < 512;l++)
adamstark@46 444 {
adamstark@46 445 sum = 0;
adamstark@46 446
adamstark@46 447 // for n samples from 0 - (512-lag)
adamstark@46 448 for (n = 0;n < (512-l);n++)
adamstark@46 449 {
adamstark@46 450 tmp = df_thresh[n] * df_thresh[n+l]; // multiply current sample n by sample (n+l)
adamstark@46 451 sum = sum + tmp; // add to sum
adamstark@46 452 }
adamstark@46 453
adamstark@46 454 acf[l] = sum / (512-l); // weight by number of mults and add to acf buffer
adamstark@46 455 }
adamstark@46 456 }
adamstark@46 457
adamstark@51 458 //=======================================================================
adamstark@46 459 float BTrack :: mean_array(float array[],int start,int end)
adamstark@46 460 {
adamstark@46 461 int i;
adamstark@47 462 double sum = 0;
adamstark@47 463
adamstark@47 464 int length = end - start;
adamstark@46 465
adamstark@46 466 // find sum
adamstark@47 467 for (i = start;i < end;i++)
adamstark@46 468 {
adamstark@46 469 sum = sum + array[i];
adamstark@46 470 }
adamstark@46 471
adamstark@47 472 if (length > 0)
adamstark@47 473 {
adamstark@47 474 return sum / length; // average and return
adamstark@47 475 }
adamstark@47 476 else
adamstark@47 477 {
adamstark@47 478 return 0;
adamstark@47 479 }
adamstark@46 480 }
adamstark@46 481
adamstark@51 482 //=======================================================================
adamstark@46 483 void BTrack :: normalise(float array[],int N)
adamstark@46 484 {
adamstark@46 485 double sum = 0;
adamstark@46 486
adamstark@46 487 for (int i = 0;i < N;i++)
adamstark@46 488 {
adamstark@46 489 if (array[i] > 0)
adamstark@46 490 {
adamstark@46 491 sum = sum + array[i];
adamstark@46 492 }
adamstark@46 493 }
adamstark@46 494
adamstark@46 495 if (sum > 0)
adamstark@46 496 {
adamstark@46 497 for (int i = 0;i < N;i++)
adamstark@46 498 {
adamstark@46 499 array[i] = array[i] / sum;
adamstark@46 500 }
adamstark@46 501 }
adamstark@46 502 }
adamstark@46 503
adamstark@51 504 //=======================================================================
adamstark@46 505 void BTrack :: updatecumscore(float df_sample)
adamstark@46 506 {
adamstark@46 507 int start, end, winsize;
adamstark@46 508 float max;
adamstark@46 509
adamstark@46 510 start = dfbuffer_size - round(2*bperiod);
adamstark@46 511 end = dfbuffer_size - round(bperiod/2);
adamstark@46 512 winsize = end-start+1;
adamstark@46 513
adamstark@46 514 float w1[winsize];
adamstark@46 515 float v = -2*bperiod;
adamstark@46 516 float wcumscore;
adamstark@46 517
adamstark@46 518
adamstark@46 519 // create window
adamstark@46 520 for (int i = 0;i < winsize;i++)
adamstark@46 521 {
adamstark@46 522 w1[i] = exp((-1*pow(tightness*log(-v/bperiod),2))/2);
adamstark@46 523 v = v+1;
adamstark@46 524 }
adamstark@46 525
adamstark@46 526 // calculate new cumulative score value
adamstark@46 527 max = 0;
adamstark@46 528 int n = 0;
adamstark@46 529 for (int i=start;i <= end;i++)
adamstark@46 530 {
adamstark@46 531 wcumscore = cumscore[i]*w1[n];
adamstark@46 532
adamstark@46 533 if (wcumscore > max)
adamstark@46 534 {
adamstark@46 535 max = wcumscore;
adamstark@46 536 }
adamstark@46 537 n++;
adamstark@46 538 }
adamstark@46 539
adamstark@46 540
adamstark@46 541 // shift cumulative score back one
adamstark@46 542 for (int i = 0;i < (dfbuffer_size-1);i++)
adamstark@46 543 {
adamstark@46 544 cumscore[i] = cumscore[i+1];
adamstark@46 545 }
adamstark@46 546
adamstark@46 547 // add new value to cumulative score
adamstark@46 548 cumscore[dfbuffer_size-1] = ((1-alpha)*df_sample) + (alpha*max);
adamstark@46 549
adamstark@46 550 cscoreval = cumscore[dfbuffer_size-1];
adamstark@46 551
adamstark@46 552 //cout << cumscore[dfbuffer_size-1] << endl;
adamstark@46 553
adamstark@46 554 }
adamstark@46 555
adamstark@51 556 //=======================================================================
adamstark@46 557 void BTrack :: predictbeat()
adamstark@46 558 {
adamstark@46 559 int winsize = (int) bperiod;
adamstark@46 560 float fcumscore[dfbuffer_size + winsize];
adamstark@46 561 float w2[winsize];
adamstark@46 562 // copy cumscore to first part of fcumscore
adamstark@46 563 for (int i = 0;i < dfbuffer_size;i++)
adamstark@46 564 {
adamstark@46 565 fcumscore[i] = cumscore[i];
adamstark@46 566 }
adamstark@46 567
adamstark@46 568 // create future window
adamstark@46 569 float v = 1;
adamstark@46 570 for (int i = 0;i < winsize;i++)
adamstark@46 571 {
adamstark@46 572 w2[i] = exp((-1*pow((v - (bperiod/2)),2)) / (2*pow((bperiod/2) ,2)));
adamstark@46 573 v++;
adamstark@46 574 }
adamstark@46 575
adamstark@46 576 // create past window
adamstark@46 577 v = -2*bperiod;
adamstark@46 578 int start = dfbuffer_size - round(2*bperiod);
adamstark@46 579 int end = dfbuffer_size - round(bperiod/2);
adamstark@46 580 int pastwinsize = end-start+1;
adamstark@46 581 float w1[pastwinsize];
adamstark@46 582
adamstark@46 583 for (int i = 0;i < pastwinsize;i++)
adamstark@46 584 {
adamstark@46 585 w1[i] = exp((-1*pow(tightness*log(-v/bperiod),2))/2);
adamstark@46 586 v = v+1;
adamstark@46 587 }
adamstark@46 588
adamstark@46 589
adamstark@46 590
adamstark@46 591 // calculate future cumulative score
adamstark@46 592 float max;
adamstark@46 593 int n;
adamstark@46 594 float wcumscore;
adamstark@46 595 for (int i = dfbuffer_size;i < (dfbuffer_size+winsize);i++)
adamstark@46 596 {
adamstark@46 597 start = i - round(2*bperiod);
adamstark@46 598 end = i - round(bperiod/2);
adamstark@46 599
adamstark@46 600 max = 0;
adamstark@46 601 n = 0;
adamstark@46 602 for (int k=start;k <= end;k++)
adamstark@46 603 {
adamstark@46 604 wcumscore = fcumscore[k]*w1[n];
adamstark@46 605
adamstark@46 606 if (wcumscore > max)
adamstark@46 607 {
adamstark@46 608 max = wcumscore;
adamstark@46 609 }
adamstark@46 610 n++;
adamstark@46 611 }
adamstark@46 612
adamstark@46 613 fcumscore[i] = max;
adamstark@46 614 }
adamstark@46 615
adamstark@46 616
adamstark@46 617 // predict beat
adamstark@46 618 max = 0;
adamstark@46 619 n = 0;
adamstark@46 620
adamstark@46 621 for (int i = dfbuffer_size;i < (dfbuffer_size+winsize);i++)
adamstark@46 622 {
adamstark@46 623 wcumscore = fcumscore[i]*w2[n];
adamstark@46 624
adamstark@46 625 if (wcumscore > max)
adamstark@46 626 {
adamstark@46 627 max = wcumscore;
adamstark@46 628 beat = n;
adamstark@46 629 }
adamstark@46 630
adamstark@46 631 n++;
adamstark@46 632 }
adamstark@46 633
adamstark@46 634
adamstark@46 635 // set beat
adamstark@51 636 //beat = beat;
adamstark@46 637
adamstark@46 638 // set next prediction time
adamstark@46 639 m0 = beat+round(bperiod/2);
adamstark@46 640
adamstark@46 641
adamstark@46 642 }