annotate src/BTrack.cpp @ 54:9699024bb3d0

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 Stark <adamstark@users.noreply.github.com>
date Wed, 22 Jan 2014 02:49:29 +0000
parents 338f5eb29e41
children 5e520f59127f
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@54 31 double rayparam = 43;
adamstark@54 32 double 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@54 53 wv[n] = ((double) n / pow(rayparam,2)) * exp((-1*pow((double)-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@54 62 double t_mu = 41/2;
adamstark@54 63 double m_sig;
adamstark@54 64 double 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@54 95 bperiod = round(60/((((double) fsize)/44100)*tempo));
adamstark@46 96
adamstark@54 97 dfbuffer = new double[dfbuffer_size]; // create df_buffer
adamstark@54 98 cumscore = new double[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@54 116 void BTrack :: process(double 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@54 152 void BTrack :: settempo(double 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@54 184 int new_bperiod = (int) round(60/((((double) 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@54 215 m0 = (int) round(((double) new_bperiod)/2);
adamstark@46 216 }
adamstark@46 217
adamstark@51 218 //=======================================================================
adamstark@54 219 void BTrack :: fixtempo(double 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@54 259 float input[dfbuffer_size];
adamstark@54 260
adamstark@54 261 for (int i = 0;i < dfbuffer_size;i++)
adamstark@54 262 {
adamstark@54 263 input[i] = (float) dfbuffer[i];
adamstark@54 264 }
adamstark@46 265
adamstark@46 266 double src_ratio = 512.0/((double) dfbuffer_size);
adamstark@46 267 int BUFFER_LEN = dfbuffer_size;
adamstark@46 268 int output_len;
adamstark@46 269 SRC_DATA src_data ;
adamstark@46 270
adamstark@46 271 //output_len = (int) floor (((double) BUFFER_LEN) * src_ratio) ;
adamstark@46 272 output_len = 512;
adamstark@46 273
adamstark@54 274 src_data.data_in = input;
adamstark@46 275 src_data.input_frames = BUFFER_LEN;
adamstark@46 276
adamstark@46 277 src_data.src_ratio = src_ratio;
adamstark@46 278
adamstark@46 279 src_data.data_out = output;
adamstark@46 280 src_data.output_frames = output_len;
adamstark@46 281
adamstark@46 282 src_simple (&src_data, SRC_SINC_BEST_QUALITY, 1);
adamstark@46 283
adamstark@46 284 for (int i = 0;i < output_len;i++)
adamstark@46 285 {
adamstark@54 286 df512[i] = (double) src_data.data_out[i];
adamstark@46 287 }
adamstark@46 288 }
adamstark@46 289
adamstark@51 290 //=======================================================================
adamstark@46 291 void BTrack :: calcTempo()
adamstark@46 292 {
adamstark@46 293 // adaptive threshold on input
adamstark@46 294 adapt_thresh(df512,512);
adamstark@46 295
adamstark@46 296 // calculate auto-correlation function of detection function
adamstark@46 297 acf_bal(df512);
adamstark@46 298
adamstark@46 299 // calculate output of comb filterbank
adamstark@46 300 getrcfoutput();
adamstark@46 301
adamstark@46 302
adamstark@46 303 // adaptive threshold on rcf
adamstark@46 304 adapt_thresh(rcf,128);
adamstark@46 305
adamstark@46 306
adamstark@46 307 int t_index;
adamstark@46 308 int t_index2;
adamstark@46 309 // calculate tempo observation vector from bperiod observation vector
adamstark@46 310 for (int i = 0;i < 41;i++)
adamstark@46 311 {
adamstark@54 312 t_index = (int) round(p_fact / ((double) ((2*i)+80)));
adamstark@54 313 t_index2 = (int) round(p_fact / ((double) ((4*i)+160)));
adamstark@46 314
adamstark@46 315
adamstark@46 316 t_obs[i] = rcf[t_index-1] + rcf[t_index2-1];
adamstark@46 317 }
adamstark@46 318
adamstark@46 319
adamstark@54 320 double maxval;
adamstark@54 321 double maxind;
adamstark@54 322 double curval;
adamstark@46 323
adamstark@46 324 // if tempo is fixed then always use a fixed set of tempi as the previous observation probability function
adamstark@46 325 if (tempofix == 1)
adamstark@46 326 {
adamstark@46 327 for (int k = 0;k < 41;k++)
adamstark@46 328 {
adamstark@46 329 prev_delta[k] = prev_delta_fix[k];
adamstark@46 330 }
adamstark@46 331 }
adamstark@46 332
adamstark@46 333 for (int j=0;j < 41;j++)
adamstark@46 334 {
adamstark@46 335 maxval = -1;
adamstark@46 336 for (int i = 0;i < 41;i++)
adamstark@46 337 {
adamstark@46 338 curval = prev_delta[i]*t_tmat[i][j];
adamstark@46 339
adamstark@46 340 if (curval > maxval)
adamstark@46 341 {
adamstark@46 342 maxval = curval;
adamstark@46 343 }
adamstark@46 344 }
adamstark@46 345
adamstark@46 346 delta[j] = maxval*t_obs[j];
adamstark@46 347 }
adamstark@46 348
adamstark@46 349
adamstark@46 350 normalise(delta,41);
adamstark@46 351
adamstark@46 352 maxind = -1;
adamstark@46 353 maxval = -1;
adamstark@46 354
adamstark@46 355 for (int j=0;j < 41;j++)
adamstark@46 356 {
adamstark@46 357 if (delta[j] > maxval)
adamstark@46 358 {
adamstark@46 359 maxval = delta[j];
adamstark@46 360 maxind = j;
adamstark@46 361 }
adamstark@46 362
adamstark@46 363 prev_delta[j] = delta[j];
adamstark@46 364 }
adamstark@46 365
adamstark@54 366 bperiod = round((60.0*44100.0)/(((2*maxind)+80)*((double) framesize)));
adamstark@46 367
adamstark@46 368 if (bperiod > 0)
adamstark@46 369 {
adamstark@54 370 est_tempo = 60.0/((((double) framesize) / 44100.0)*bperiod);
adamstark@46 371 }
adamstark@46 372
adamstark@46 373 //cout << bperiod << endl;
adamstark@46 374 }
adamstark@46 375
adamstark@51 376 //=======================================================================
adamstark@54 377 void BTrack :: adapt_thresh(double *x,int N)
adamstark@46 378 {
adamstark@46 379 //int N = 512; // length of df
adamstark@46 380 int i = 0;
adamstark@46 381 int k,t = 0;
adamstark@54 382 double x_thresh[N];
adamstark@46 383
adamstark@46 384 int p_post = 7;
adamstark@46 385 int p_pre = 8;
adamstark@46 386
adamstark@52 387 t = std::min(N,p_post); // what is smaller, p_post of df size. This is to avoid accessing outside of arrays
adamstark@46 388
adamstark@46 389 // find threshold for first 't' samples, where a full average cannot be computed yet
adamstark@46 390 for (i = 0;i <= t;i++)
adamstark@46 391 {
adamstark@52 392 k = std::min((i+p_pre),N);
adamstark@46 393 x_thresh[i] = mean_array(x,1,k);
adamstark@46 394 }
adamstark@46 395 // find threshold for bulk of samples across a moving average from [i-p_pre,i+p_post]
adamstark@46 396 for (i = t+1;i < N-p_post;i++)
adamstark@46 397 {
adamstark@46 398 x_thresh[i] = mean_array(x,i-p_pre,i+p_post);
adamstark@46 399 }
adamstark@46 400 // for last few samples calculate threshold, again, not enough samples to do as above
adamstark@46 401 for (i = N-p_post;i < N;i++)
adamstark@46 402 {
adamstark@52 403 k = std::max((i-p_post),1);
adamstark@46 404 x_thresh[i] = mean_array(x,k,N);
adamstark@46 405 }
adamstark@46 406
adamstark@46 407 // subtract the threshold from the detection function and check that it is not less than 0
adamstark@46 408 for (i = 0;i < N;i++)
adamstark@46 409 {
adamstark@46 410 x[i] = x[i] - x_thresh[i];
adamstark@46 411 if (x[i] < 0)
adamstark@46 412 {
adamstark@46 413 x[i] = 0;
adamstark@46 414 }
adamstark@46 415 }
adamstark@46 416 }
adamstark@46 417
adamstark@51 418 //=======================================================================
adamstark@46 419 void BTrack :: getrcfoutput()
adamstark@46 420 {
adamstark@46 421 int numelem;
adamstark@46 422
adamstark@46 423 for (int i = 0;i < 128;i++)
adamstark@46 424 {
adamstark@46 425 rcf[i] = 0;
adamstark@46 426 }
adamstark@46 427
adamstark@46 428 numelem = 4;
adamstark@46 429
adamstark@46 430 for (int i = 2;i <= 127;i++) // max beat period
adamstark@46 431 {
adamstark@46 432 for (int a = 1;a <= numelem;a++) // number of comb elements
adamstark@46 433 {
adamstark@46 434 for (int b = 1-a;b <= a-1;b++) // general state using normalisation of comb elements
adamstark@46 435 {
adamstark@46 436 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 437 }
adamstark@46 438 }
adamstark@46 439 }
adamstark@46 440 }
adamstark@46 441
adamstark@51 442 //=======================================================================
adamstark@54 443 void BTrack :: acf_bal(double *df_thresh)
adamstark@46 444 {
adamstark@46 445 int l, n = 0;
adamstark@54 446 double sum, tmp;
adamstark@46 447
adamstark@46 448 // for l lags from 0-511
adamstark@46 449 for (l = 0;l < 512;l++)
adamstark@46 450 {
adamstark@46 451 sum = 0;
adamstark@46 452
adamstark@46 453 // for n samples from 0 - (512-lag)
adamstark@46 454 for (n = 0;n < (512-l);n++)
adamstark@46 455 {
adamstark@46 456 tmp = df_thresh[n] * df_thresh[n+l]; // multiply current sample n by sample (n+l)
adamstark@46 457 sum = sum + tmp; // add to sum
adamstark@46 458 }
adamstark@46 459
adamstark@46 460 acf[l] = sum / (512-l); // weight by number of mults and add to acf buffer
adamstark@46 461 }
adamstark@46 462 }
adamstark@46 463
adamstark@51 464 //=======================================================================
adamstark@54 465 double BTrack :: mean_array(double *array,int start,int end)
adamstark@46 466 {
adamstark@46 467 int i;
adamstark@47 468 double sum = 0;
adamstark@47 469
adamstark@47 470 int length = end - start;
adamstark@46 471
adamstark@46 472 // find sum
adamstark@47 473 for (i = start;i < end;i++)
adamstark@46 474 {
adamstark@46 475 sum = sum + array[i];
adamstark@46 476 }
adamstark@46 477
adamstark@47 478 if (length > 0)
adamstark@47 479 {
adamstark@47 480 return sum / length; // average and return
adamstark@47 481 }
adamstark@47 482 else
adamstark@47 483 {
adamstark@47 484 return 0;
adamstark@47 485 }
adamstark@46 486 }
adamstark@46 487
adamstark@51 488 //=======================================================================
adamstark@54 489 void BTrack :: normalise(double *array,int N)
adamstark@46 490 {
adamstark@46 491 double sum = 0;
adamstark@46 492
adamstark@46 493 for (int i = 0;i < N;i++)
adamstark@46 494 {
adamstark@46 495 if (array[i] > 0)
adamstark@46 496 {
adamstark@46 497 sum = sum + array[i];
adamstark@46 498 }
adamstark@46 499 }
adamstark@46 500
adamstark@46 501 if (sum > 0)
adamstark@46 502 {
adamstark@46 503 for (int i = 0;i < N;i++)
adamstark@46 504 {
adamstark@46 505 array[i] = array[i] / sum;
adamstark@46 506 }
adamstark@46 507 }
adamstark@46 508 }
adamstark@46 509
adamstark@51 510 //=======================================================================
adamstark@54 511 void BTrack :: updatecumscore(double df_sample)
adamstark@46 512 {
adamstark@46 513 int start, end, winsize;
adamstark@54 514 double max;
adamstark@46 515
adamstark@46 516 start = dfbuffer_size - round(2*bperiod);
adamstark@46 517 end = dfbuffer_size - round(bperiod/2);
adamstark@46 518 winsize = end-start+1;
adamstark@46 519
adamstark@54 520 double w1[winsize];
adamstark@54 521 double v = -2*bperiod;
adamstark@54 522 double wcumscore;
adamstark@46 523
adamstark@46 524
adamstark@46 525 // create window
adamstark@46 526 for (int i = 0;i < winsize;i++)
adamstark@46 527 {
adamstark@46 528 w1[i] = exp((-1*pow(tightness*log(-v/bperiod),2))/2);
adamstark@46 529 v = v+1;
adamstark@46 530 }
adamstark@46 531
adamstark@46 532 // calculate new cumulative score value
adamstark@46 533 max = 0;
adamstark@46 534 int n = 0;
adamstark@46 535 for (int i=start;i <= end;i++)
adamstark@46 536 {
adamstark@46 537 wcumscore = cumscore[i]*w1[n];
adamstark@46 538
adamstark@46 539 if (wcumscore > max)
adamstark@46 540 {
adamstark@46 541 max = wcumscore;
adamstark@46 542 }
adamstark@46 543 n++;
adamstark@46 544 }
adamstark@46 545
adamstark@46 546
adamstark@46 547 // shift cumulative score back one
adamstark@46 548 for (int i = 0;i < (dfbuffer_size-1);i++)
adamstark@46 549 {
adamstark@46 550 cumscore[i] = cumscore[i+1];
adamstark@46 551 }
adamstark@46 552
adamstark@46 553 // add new value to cumulative score
adamstark@46 554 cumscore[dfbuffer_size-1] = ((1-alpha)*df_sample) + (alpha*max);
adamstark@46 555
adamstark@46 556 cscoreval = cumscore[dfbuffer_size-1];
adamstark@46 557
adamstark@46 558 //cout << cumscore[dfbuffer_size-1] << endl;
adamstark@46 559
adamstark@46 560 }
adamstark@46 561
adamstark@51 562 //=======================================================================
adamstark@46 563 void BTrack :: predictbeat()
adamstark@46 564 {
adamstark@46 565 int winsize = (int) bperiod;
adamstark@54 566 double fcumscore[dfbuffer_size + winsize];
adamstark@54 567 double w2[winsize];
adamstark@46 568 // copy cumscore to first part of fcumscore
adamstark@46 569 for (int i = 0;i < dfbuffer_size;i++)
adamstark@46 570 {
adamstark@46 571 fcumscore[i] = cumscore[i];
adamstark@46 572 }
adamstark@46 573
adamstark@46 574 // create future window
adamstark@54 575 double v = 1;
adamstark@46 576 for (int i = 0;i < winsize;i++)
adamstark@46 577 {
adamstark@46 578 w2[i] = exp((-1*pow((v - (bperiod/2)),2)) / (2*pow((bperiod/2) ,2)));
adamstark@46 579 v++;
adamstark@46 580 }
adamstark@46 581
adamstark@46 582 // create past window
adamstark@46 583 v = -2*bperiod;
adamstark@46 584 int start = dfbuffer_size - round(2*bperiod);
adamstark@46 585 int end = dfbuffer_size - round(bperiod/2);
adamstark@46 586 int pastwinsize = end-start+1;
adamstark@54 587 double w1[pastwinsize];
adamstark@46 588
adamstark@46 589 for (int i = 0;i < pastwinsize;i++)
adamstark@46 590 {
adamstark@46 591 w1[i] = exp((-1*pow(tightness*log(-v/bperiod),2))/2);
adamstark@46 592 v = v+1;
adamstark@46 593 }
adamstark@46 594
adamstark@46 595
adamstark@46 596
adamstark@46 597 // calculate future cumulative score
adamstark@54 598 double max;
adamstark@46 599 int n;
adamstark@54 600 double wcumscore;
adamstark@46 601 for (int i = dfbuffer_size;i < (dfbuffer_size+winsize);i++)
adamstark@46 602 {
adamstark@46 603 start = i - round(2*bperiod);
adamstark@46 604 end = i - round(bperiod/2);
adamstark@46 605
adamstark@46 606 max = 0;
adamstark@46 607 n = 0;
adamstark@46 608 for (int k=start;k <= end;k++)
adamstark@46 609 {
adamstark@46 610 wcumscore = fcumscore[k]*w1[n];
adamstark@46 611
adamstark@46 612 if (wcumscore > max)
adamstark@46 613 {
adamstark@46 614 max = wcumscore;
adamstark@46 615 }
adamstark@46 616 n++;
adamstark@46 617 }
adamstark@46 618
adamstark@46 619 fcumscore[i] = max;
adamstark@46 620 }
adamstark@46 621
adamstark@46 622
adamstark@46 623 // predict beat
adamstark@46 624 max = 0;
adamstark@46 625 n = 0;
adamstark@46 626
adamstark@46 627 for (int i = dfbuffer_size;i < (dfbuffer_size+winsize);i++)
adamstark@46 628 {
adamstark@46 629 wcumscore = fcumscore[i]*w2[n];
adamstark@46 630
adamstark@46 631 if (wcumscore > max)
adamstark@46 632 {
adamstark@46 633 max = wcumscore;
adamstark@46 634 beat = n;
adamstark@46 635 }
adamstark@46 636
adamstark@46 637 n++;
adamstark@46 638 }
adamstark@46 639
adamstark@46 640 // set next prediction time
adamstark@46 641 m0 = beat+round(bperiod/2);
adamstark@46 642
adamstark@46 643
adamstark@46 644 }