annotate src/OnsetDetectionFunction.cpp @ 15:2b94d3d2fb9d develop

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 <adamstark.uk@gmail.com>
date Wed, 22 Jan 2014 01:13:45 +0000
parents bd2c405d4a06
children 73c64ca0ed23
rev   line source
adamstark@5 1 //=======================================================================
adamstark@5 2 /** @file OnsetDetectionFunction.cpp
adamstark@5 3 * @brief A class for calculating onset detection functions
adamstark@5 4 * @author Adam Stark
adamstark@5 5 * @copyright Copyright (C) 2008-2014 Queen Mary University of London
adamstark@5 6 *
adamstark@5 7 * This program is free software: you can redistribute it and/or modify
adamstark@5 8 * it under the terms of the GNU General Public License as published by
adamstark@5 9 * the Free Software Foundation, either version 3 of the License, or
adamstark@5 10 * (at your option) any later version.
adamstark@5 11 *
adamstark@5 12 * This program is distributed in the hope that it will be useful,
adamstark@5 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
adamstark@5 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
adamstark@5 15 * GNU General Public License for more details.
adamstark@5 16 *
adamstark@5 17 * You should have received a copy of the GNU General Public License
adamstark@5 18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
adamstark@5 19 */
adamstark@5 20 //=======================================================================
adamstark@5 21
adamstark@5 22 #include <math.h>
adamstark@5 23 #include "OnsetDetectionFunction.h"
adamstark@5 24
adamstark@15 25 //=======================================================================
adamstark@5 26 OnsetDetectionFunction :: OnsetDetectionFunction(int arg_hsize,int arg_fsize,int arg_df_type,int arg_win_type)
adamstark@5 27 {
adamstark@5 28 // indicate that we have not initialised yet
adamstark@5 29 initialised = 0;
adamstark@5 30
adamstark@5 31 // set pi
adamstark@5 32 pi = 3.14159265358979;
adamstark@5 33
adamstark@5 34 // initialise with arguments to constructor
adamstark@5 35 initialise(arg_hsize,arg_fsize,arg_df_type,arg_win_type);
adamstark@5 36 }
adamstark@5 37
adamstark@5 38
adamstark@15 39 //=======================================================================
adamstark@5 40 OnsetDetectionFunction :: ~OnsetDetectionFunction()
adamstark@5 41 {
adamstark@5 42 // destroy fft plan
adamstark@5 43 fftw_destroy_plan(p);
adamstark@5 44 fftw_free(in);
adamstark@5 45 fftw_free(out);
adamstark@5 46
adamstark@5 47 // deallocate memory
adamstark@5 48 delete [] frame;
adamstark@5 49 frame = NULL;
adamstark@5 50 delete [] window;
adamstark@5 51 window = NULL;
adamstark@5 52 delete [] wframe;
adamstark@5 53 wframe = NULL;
adamstark@5 54 delete [] mag;
adamstark@5 55 mag = NULL;
adamstark@5 56 delete [] mag_old;
adamstark@5 57 mag_old = NULL;
adamstark@5 58 delete [] phase;
adamstark@5 59 phase = NULL;
adamstark@5 60 delete [] phase_old;
adamstark@5 61 phase_old = NULL;
adamstark@5 62 delete [] phase_old_2;
adamstark@5 63 phase_old_2 = NULL;
adamstark@5 64 }
adamstark@5 65
adamstark@15 66 //=======================================================================
adamstark@5 67 void OnsetDetectionFunction :: initialise(int arg_hsize,int arg_fsize,int arg_df_type,int arg_win_type)
adamstark@5 68 {
adamstark@5 69 if (initialised == 1) // if we have already initialised some buffers and an FFT plan
adamstark@5 70 {
adamstark@5 71 //////////////////////////////////
adamstark@5 72 // TIDY UP FIRST - If initialise is called after the class has been initialised
adamstark@5 73 // then we want to free up memory and cancel existing FFT plans
adamstark@5 74
adamstark@5 75 // destroy fft plan
adamstark@5 76 fftw_destroy_plan(p);
adamstark@5 77 fftw_free(in);
adamstark@5 78 fftw_free(out);
adamstark@5 79
adamstark@5 80
adamstark@5 81 // deallocate memory
adamstark@5 82 delete [] frame;
adamstark@5 83 frame = NULL;
adamstark@5 84 delete [] window;
adamstark@5 85 window = NULL;
adamstark@5 86 delete [] wframe;
adamstark@5 87 wframe = NULL;
adamstark@5 88 delete [] mag;
adamstark@5 89 mag = NULL;
adamstark@5 90 delete [] mag_old;
adamstark@5 91 mag_old = NULL;
adamstark@5 92 delete [] phase;
adamstark@5 93 phase = NULL;
adamstark@5 94 delete [] phase_old;
adamstark@5 95 phase_old = NULL;
adamstark@5 96 delete [] phase_old_2;
adamstark@5 97 phase_old_2 = NULL;
adamstark@5 98
adamstark@5 99 ////// END TIDY UP ///////////////
adamstark@5 100 //////////////////////////////////
adamstark@5 101 }
adamstark@5 102
adamstark@5 103 hopsize = arg_hsize; // set hopsize
adamstark@5 104 framesize = arg_fsize; // set framesize
adamstark@5 105
adamstark@5 106 df_type = arg_df_type; // set detection function type
adamstark@5 107
adamstark@5 108 // initialise buffers
adamstark@5 109 frame = new double[framesize];
adamstark@5 110 window = new double[framesize];
adamstark@5 111 wframe = new double[framesize];
adamstark@5 112
adamstark@5 113 mag = new double[framesize];
adamstark@5 114 mag_old = new double[framesize];
adamstark@5 115
adamstark@5 116 phase = new double[framesize];
adamstark@5 117 phase_old = new double[framesize];
adamstark@5 118 phase_old_2 = new double[framesize];
adamstark@5 119
adamstark@5 120
adamstark@5 121 // set the window to the specified type
adamstark@5 122 switch (arg_win_type){
adamstark@5 123 case 0:
adamstark@5 124 set_win_rectangular(); // Rectangular window
adamstark@5 125 break;
adamstark@5 126 case 1:
adamstark@5 127 set_win_hanning(); // Hanning Window
adamstark@5 128 break;
adamstark@5 129 case 2:
adamstark@5 130 set_win_hamming(); // Hamming Window
adamstark@5 131 break;
adamstark@5 132 case 3:
adamstark@5 133 set_win_blackman(); // Blackman Window
adamstark@5 134 break;
adamstark@5 135 case 4:
adamstark@5 136 set_win_tukey(); // Tukey Window
adamstark@5 137 break;
adamstark@5 138 default:
adamstark@5 139 set_win_hanning(); // DEFAULT: Hanning Window
adamstark@5 140 }
adamstark@5 141
adamstark@5 142
adamstark@5 143
adamstark@5 144
adamstark@5 145 // initialise previous magnitude spectrum to zero
adamstark@5 146 for (int i = 0;i < framesize;i++)
adamstark@5 147 {
adamstark@5 148 mag_old[i] = 0.0;
adamstark@5 149 phase_old[i] = 0.0;
adamstark@5 150 phase_old_2[i] = 0.0;
adamstark@5 151 frame[i] = 0.0;
adamstark@5 152 }
adamstark@5 153
adamstark@5 154 energy_sum_old = 0.0; // initialise previous energy sum value to zero
adamstark@5 155
adamstark@5 156 /* Init fft */
adamstark@5 157 in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * framesize); // complex array to hold fft data
adamstark@5 158 out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * framesize); // complex array to hold fft data
adamstark@5 159 p = fftw_plan_dft_1d(framesize, in, out, FFTW_FORWARD, FFTW_ESTIMATE); // FFT plan initialisation
adamstark@5 160
adamstark@5 161 initialised = 1;
adamstark@5 162 }
adamstark@5 163
adamstark@15 164 //=======================================================================
adamstark@5 165 void OnsetDetectionFunction :: set_df_type(int arg_df_type)
adamstark@5 166 {
adamstark@5 167 df_type = arg_df_type; // set detection function type
adamstark@5 168 }
adamstark@5 169
adamstark@15 170 //=======================================================================
adamstark@5 171 double OnsetDetectionFunction :: getDFsample(double inputbuffer[])
adamstark@5 172 {
adamstark@5 173 double df_sample;
adamstark@5 174
adamstark@5 175 // shift audio samples back in frame by hop size
adamstark@5 176 for (int i = 0; i < (framesize-hopsize);i++)
adamstark@5 177 {
adamstark@5 178 frame[i] = frame[i+hopsize];
adamstark@5 179 }
adamstark@5 180
adamstark@5 181 // add new samples to frame from input buffer
adamstark@5 182 int j = 0;
adamstark@5 183 for (int i = (framesize-hopsize);i < framesize;i++)
adamstark@5 184 {
adamstark@5 185 frame[i] = inputbuffer[j];
adamstark@5 186 j++;
adamstark@5 187 }
adamstark@5 188
adamstark@5 189 switch (df_type){
adamstark@5 190 case 0:
adamstark@5 191 df_sample = energy_envelope(); // calculate energy envelope detection function sample
adamstark@5 192 break;
adamstark@5 193 case 1:
adamstark@5 194 df_sample = energy_difference(); // calculate half-wave rectified energy difference detection function sample
adamstark@5 195 break;
adamstark@5 196 case 2:
adamstark@5 197 df_sample = spectral_difference(); // calculate spectral difference detection function sample
adamstark@5 198 break;
adamstark@5 199 case 3:
adamstark@5 200 df_sample = spectral_difference_hwr(); // calculate spectral difference detection function sample (half wave rectified)
adamstark@5 201 break;
adamstark@5 202 case 4:
adamstark@5 203 df_sample = phase_deviation(); // calculate phase deviation detection function sample (half wave rectified)
adamstark@5 204 break;
adamstark@5 205 case 5:
adamstark@5 206 df_sample = complex_spectral_difference(); // calcualte complex spectral difference detection function sample
adamstark@5 207 break;
adamstark@5 208 case 6:
adamstark@5 209 df_sample = complex_spectral_difference_hwr(); // calcualte complex spectral difference detection function sample (half-wave rectified)
adamstark@5 210 break;
adamstark@5 211 case 7:
adamstark@5 212 df_sample = high_frequency_content(); // calculate high frequency content detection function sample
adamstark@5 213 break;
adamstark@5 214 case 8:
adamstark@5 215 df_sample = high_frequency_spectral_difference(); // calculate high frequency spectral difference detection function sample
adamstark@5 216 break;
adamstark@5 217 case 9:
adamstark@5 218 df_sample = high_frequency_spectral_difference_hwr(); // calculate high frequency spectral difference detection function (half-wave rectified)
adamstark@5 219 break;
adamstark@5 220 default:
adamstark@5 221 df_sample = 1.0;
adamstark@5 222 }
adamstark@5 223
adamstark@5 224 return df_sample;
adamstark@5 225 }
adamstark@5 226
adamstark@5 227
adamstark@15 228 //=======================================================================
adamstark@5 229 void OnsetDetectionFunction :: perform_FFT()
adamstark@5 230 {
adamstark@5 231 int fsize2 = (framesize/2);
adamstark@5 232
adamstark@5 233 // window frame and copy to complex array, swapping the first and second half of the signal
adamstark@5 234 for (int i = 0;i < fsize2;i++)
adamstark@5 235 {
adamstark@5 236 in[i][0] = frame[i+fsize2] * window[i+fsize2];
adamstark@5 237 in[i][1] = 0.0;
adamstark@5 238 in[i+fsize2][0] = frame[i] * window[i];
adamstark@5 239 in[i+fsize2][1] = 0.0;
adamstark@5 240 }
adamstark@5 241
adamstark@5 242 // perform the fft
adamstark@5 243 fftw_execute(p);
adamstark@5 244 }
adamstark@5 245
adamstark@5 246 ////////////////////////////////////////////////////////////////////////////////////////////////
adamstark@5 247 ////////////////////////////////////////////////////////////////////////////////////////////////
adamstark@5 248 ////////////////////////////// Methods for Detection Functions /////////////////////////////////
adamstark@5 249
adamstark@15 250 //=======================================================================
adamstark@5 251 double OnsetDetectionFunction :: energy_envelope()
adamstark@5 252 {
adamstark@5 253 double sum;
adamstark@5 254
adamstark@5 255 sum = 0; // initialise sum
adamstark@5 256
adamstark@5 257 // sum the squares of the samples
adamstark@5 258 for (int i = 0;i < framesize;i++)
adamstark@5 259 {
adamstark@5 260 sum = sum + (frame[i]*frame[i]);
adamstark@5 261 }
adamstark@5 262
adamstark@5 263 return sum; // return sum
adamstark@5 264 }
adamstark@5 265
adamstark@15 266 //=======================================================================
adamstark@5 267 double OnsetDetectionFunction :: energy_difference()
adamstark@5 268 {
adamstark@5 269 double sum;
adamstark@5 270 double sample;
adamstark@5 271
adamstark@5 272 sum = 0; // initialise sum
adamstark@5 273
adamstark@5 274 // sum the squares of the samples
adamstark@5 275 for (int i = 0;i < framesize;i++)
adamstark@5 276 {
adamstark@5 277 sum = sum + (frame[i]*frame[i]);
adamstark@5 278 }
adamstark@5 279
adamstark@5 280 sample = sum - energy_sum_old; // sample is first order difference in energy
adamstark@5 281
adamstark@5 282 energy_sum_old = sum; // store energy value for next calculation
adamstark@5 283
adamstark@5 284 if (sample > 0)
adamstark@5 285 {
adamstark@5 286 return sample; // return difference
adamstark@5 287 }
adamstark@5 288 else
adamstark@5 289 {
adamstark@5 290 return 0;
adamstark@5 291 }
adamstark@5 292 }
adamstark@5 293
adamstark@15 294 //=======================================================================
adamstark@5 295 double OnsetDetectionFunction :: spectral_difference()
adamstark@5 296 {
adamstark@5 297 double diff;
adamstark@5 298 double sum;
adamstark@5 299
adamstark@5 300 // perform the FFT
adamstark@5 301 perform_FFT();
adamstark@5 302
adamstark@5 303 // compute first (N/2)+1 mag values
adamstark@5 304 for (int i = 0;i < (framesize/2)+1;i++)
adamstark@5 305 {
adamstark@5 306 mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2));
adamstark@5 307 }
adamstark@5 308 // mag spec symmetric above (N/2)+1 so copy previous values
adamstark@5 309 for (int i = (framesize/2)+1;i < framesize;i++)
adamstark@5 310 {
adamstark@5 311 mag[i] = mag[framesize-i];
adamstark@5 312 }
adamstark@5 313
adamstark@5 314 sum = 0; // initialise sum to zero
adamstark@5 315
adamstark@5 316 for (int i = 0;i < framesize;i++)
adamstark@5 317 {
adamstark@5 318 // calculate difference
adamstark@5 319 diff = mag[i] - mag_old[i];
adamstark@5 320
adamstark@5 321 // ensure all difference values are positive
adamstark@5 322 if (diff < 0)
adamstark@5 323 {
adamstark@5 324 diff = diff*-1;
adamstark@5 325 }
adamstark@5 326
adamstark@5 327 // add difference to sum
adamstark@5 328 sum = sum+diff;
adamstark@5 329
adamstark@5 330 // store magnitude spectrum bin for next detection function sample calculation
adamstark@5 331 mag_old[i] = mag[i];
adamstark@5 332 }
adamstark@5 333
adamstark@5 334 return sum;
adamstark@5 335 }
adamstark@5 336
adamstark@15 337 //=======================================================================
adamstark@5 338 double OnsetDetectionFunction :: spectral_difference_hwr()
adamstark@5 339 {
adamstark@5 340 double diff;
adamstark@5 341 double sum;
adamstark@5 342
adamstark@5 343 // perform the FFT
adamstark@5 344 perform_FFT();
adamstark@5 345
adamstark@5 346 // compute first (N/2)+1 mag values
adamstark@5 347 for (int i = 0;i < (framesize/2)+1;i++)
adamstark@5 348 {
adamstark@5 349 mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2));
adamstark@5 350 }
adamstark@5 351 // mag spec symmetric above (N/2)+1 so copy previous values
adamstark@5 352 for (int i = (framesize/2)+1;i < framesize;i++)
adamstark@5 353 {
adamstark@5 354 mag[i] = mag[framesize-i];
adamstark@5 355 }
adamstark@5 356
adamstark@5 357 sum = 0; // initialise sum to zero
adamstark@5 358
adamstark@5 359 for (int i = 0;i < framesize;i++)
adamstark@5 360 {
adamstark@5 361 // calculate difference
adamstark@5 362 diff = mag[i] - mag_old[i];
adamstark@5 363
adamstark@5 364 // only add up positive differences
adamstark@5 365 if (diff > 0)
adamstark@5 366 {
adamstark@5 367 // add difference to sum
adamstark@5 368 sum = sum+diff;
adamstark@5 369 }
adamstark@5 370
adamstark@5 371
adamstark@5 372
adamstark@5 373 // store magnitude spectrum bin for next detection function sample calculation
adamstark@5 374 mag_old[i] = mag[i];
adamstark@5 375 }
adamstark@5 376
adamstark@5 377 return sum;
adamstark@5 378 }
adamstark@5 379
adamstark@5 380
adamstark@15 381 //=======================================================================
adamstark@5 382 double OnsetDetectionFunction :: phase_deviation()
adamstark@5 383 {
adamstark@5 384 double dev,pdev;
adamstark@5 385 double sum;
adamstark@5 386
adamstark@5 387 // perform the FFT
adamstark@5 388 perform_FFT();
adamstark@5 389
adamstark@5 390 sum = 0; // initialise sum to zero
adamstark@5 391
adamstark@5 392 // compute phase values from fft output and sum deviations
adamstark@5 393 for (int i = 0;i < framesize;i++)
adamstark@5 394 {
adamstark@5 395 // calculate phase value
adamstark@5 396 phase[i] = atan2(out[i][1],out[i][0]);
adamstark@5 397
adamstark@5 398 // calculate magnitude value
adamstark@5 399 mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2));
adamstark@5 400
adamstark@5 401
adamstark@5 402 // if bin is not just a low energy bin then examine phase deviation
adamstark@5 403 if (mag[i] > 0.1)
adamstark@5 404 {
adamstark@5 405 dev = phase[i] - (2*phase_old[i]) + phase_old_2[i]; // phase deviation
adamstark@5 406 pdev = princarg(dev); // wrap into [-pi,pi] range
adamstark@5 407
adamstark@5 408 // make all values positive
adamstark@5 409 if (pdev < 0)
adamstark@5 410 {
adamstark@5 411 pdev = pdev*-1;
adamstark@5 412 }
adamstark@5 413
adamstark@5 414 // add to sum
adamstark@5 415 sum = sum + pdev;
adamstark@5 416 }
adamstark@5 417
adamstark@5 418 // store values for next calculation
adamstark@5 419 phase_old_2[i] = phase_old[i];
adamstark@5 420 phase_old[i] = phase[i];
adamstark@5 421 }
adamstark@5 422
adamstark@5 423 return sum;
adamstark@5 424 }
adamstark@5 425
adamstark@15 426 //=======================================================================
adamstark@5 427 double OnsetDetectionFunction :: complex_spectral_difference()
adamstark@5 428 {
adamstark@5 429 double dev,pdev;
adamstark@5 430 double sum;
adamstark@5 431 double mag_diff,phase_diff;
adamstark@5 432 double value;
adamstark@5 433
adamstark@5 434 // perform the FFT
adamstark@5 435 perform_FFT();
adamstark@5 436
adamstark@5 437 sum = 0; // initialise sum to zero
adamstark@5 438
adamstark@5 439 // compute phase values from fft output and sum deviations
adamstark@5 440 for (int i = 0;i < framesize;i++)
adamstark@5 441 {
adamstark@5 442 // calculate phase value
adamstark@5 443 phase[i] = atan2(out[i][1],out[i][0]);
adamstark@5 444
adamstark@5 445 // calculate magnitude value
adamstark@5 446 mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2));
adamstark@5 447
adamstark@5 448
adamstark@5 449 // phase deviation
adamstark@5 450 dev = phase[i] - (2*phase_old[i]) + phase_old_2[i];
adamstark@5 451
adamstark@5 452 // wrap into [-pi,pi] range
adamstark@5 453 pdev = princarg(dev);
adamstark@5 454
adamstark@5 455
adamstark@5 456 // calculate magnitude difference (real part of Euclidean distance between complex frames)
adamstark@5 457 mag_diff = mag[i] - mag_old[i];
adamstark@5 458
adamstark@5 459 // calculate phase difference (imaginary part of Euclidean distance between complex frames)
adamstark@5 460 phase_diff = -mag[i]*sin(pdev);
adamstark@5 461
adamstark@5 462
adamstark@5 463
adamstark@5 464 // square real and imaginary parts, sum and take square root
adamstark@5 465 value = sqrt(pow(mag_diff,2) + pow(phase_diff,2));
adamstark@5 466
adamstark@5 467
adamstark@5 468 // add to sum
adamstark@5 469 sum = sum + value;
adamstark@5 470
adamstark@5 471
adamstark@5 472 // store values for next calculation
adamstark@5 473 phase_old_2[i] = phase_old[i];
adamstark@5 474 phase_old[i] = phase[i];
adamstark@5 475 mag_old[i] = mag[i];
adamstark@5 476 }
adamstark@5 477
adamstark@5 478 return sum;
adamstark@5 479 }
adamstark@5 480
adamstark@15 481 //=======================================================================
adamstark@5 482 double OnsetDetectionFunction :: complex_spectral_difference_hwr()
adamstark@5 483 {
adamstark@5 484 double dev,pdev;
adamstark@5 485 double sum;
adamstark@5 486 double mag_diff,phase_diff;
adamstark@5 487 double value;
adamstark@5 488
adamstark@5 489 // perform the FFT
adamstark@5 490 perform_FFT();
adamstark@5 491
adamstark@5 492 sum = 0; // initialise sum to zero
adamstark@5 493
adamstark@5 494 // compute phase values from fft output and sum deviations
adamstark@5 495 for (int i = 0;i < framesize;i++)
adamstark@5 496 {
adamstark@5 497 // calculate phase value
adamstark@5 498 phase[i] = atan2(out[i][1],out[i][0]);
adamstark@5 499
adamstark@5 500 // calculate magnitude value
adamstark@5 501 mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2));
adamstark@5 502
adamstark@5 503
adamstark@5 504 // phase deviation
adamstark@5 505 dev = phase[i] - (2*phase_old[i]) + phase_old_2[i];
adamstark@5 506
adamstark@5 507 // wrap into [-pi,pi] range
adamstark@5 508 pdev = princarg(dev);
adamstark@5 509
adamstark@5 510
adamstark@5 511 // calculate magnitude difference (real part of Euclidean distance between complex frames)
adamstark@5 512 mag_diff = mag[i] - mag_old[i];
adamstark@5 513
adamstark@5 514 // if we have a positive change in magnitude, then include in sum, otherwise ignore (half-wave rectification)
adamstark@5 515 if (mag_diff > 0)
adamstark@5 516 {
adamstark@5 517 // calculate phase difference (imaginary part of Euclidean distance between complex frames)
adamstark@5 518 phase_diff = -mag[i]*sin(pdev);
adamstark@5 519
adamstark@5 520 // square real and imaginary parts, sum and take square root
adamstark@5 521 value = sqrt(pow(mag_diff,2) + pow(phase_diff,2));
adamstark@5 522
adamstark@5 523 // add to sum
adamstark@5 524 sum = sum + value;
adamstark@5 525 }
adamstark@5 526
adamstark@5 527 // store values for next calculation
adamstark@5 528 phase_old_2[i] = phase_old[i];
adamstark@5 529 phase_old[i] = phase[i];
adamstark@5 530 mag_old[i] = mag[i];
adamstark@5 531 }
adamstark@5 532
adamstark@5 533 return sum;
adamstark@5 534 }
adamstark@5 535
adamstark@5 536
adamstark@15 537 //=======================================================================
adamstark@5 538 double OnsetDetectionFunction :: high_frequency_content()
adamstark@5 539 {
adamstark@5 540 double sum;
adamstark@5 541
adamstark@5 542 // perform the FFT
adamstark@5 543 perform_FFT();
adamstark@5 544
adamstark@5 545 sum = 0; // initialise sum to zero
adamstark@5 546
adamstark@5 547 // compute phase values from fft output and sum deviations
adamstark@5 548 for (int i = 0;i < framesize;i++)
adamstark@5 549 {
adamstark@5 550 // calculate magnitude value
adamstark@5 551 mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2));
adamstark@5 552
adamstark@5 553
adamstark@5 554 sum = sum + (mag[i]*((double) (i+1)));
adamstark@5 555
adamstark@5 556 // store values for next calculation
adamstark@5 557 mag_old[i] = mag[i];
adamstark@5 558 }
adamstark@5 559
adamstark@5 560 return sum;
adamstark@5 561 }
adamstark@5 562
adamstark@15 563 //=======================================================================
adamstark@5 564 double OnsetDetectionFunction :: high_frequency_spectral_difference()
adamstark@5 565 {
adamstark@5 566 double sum;
adamstark@5 567 double mag_diff;
adamstark@5 568
adamstark@5 569 // perform the FFT
adamstark@5 570 perform_FFT();
adamstark@5 571
adamstark@5 572 sum = 0; // initialise sum to zero
adamstark@5 573
adamstark@5 574 // compute phase values from fft output and sum deviations
adamstark@5 575 for (int i = 0;i < framesize;i++)
adamstark@5 576 {
adamstark@5 577 // calculate magnitude value
adamstark@5 578 mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2));
adamstark@5 579
adamstark@5 580 // calculate difference
adamstark@5 581 mag_diff = mag[i] - mag_old[i];
adamstark@5 582
adamstark@5 583 if (mag_diff < 0)
adamstark@5 584 {
adamstark@5 585 mag_diff = -mag_diff;
adamstark@5 586 }
adamstark@5 587
adamstark@5 588 sum = sum + (mag_diff*((double) (i+1)));
adamstark@5 589
adamstark@5 590 // store values for next calculation
adamstark@5 591 mag_old[i] = mag[i];
adamstark@5 592 }
adamstark@5 593
adamstark@5 594 return sum;
adamstark@5 595 }
adamstark@5 596
adamstark@15 597 //=======================================================================
adamstark@5 598 double OnsetDetectionFunction :: high_frequency_spectral_difference_hwr()
adamstark@5 599 {
adamstark@5 600 double sum;
adamstark@5 601 double mag_diff;
adamstark@5 602
adamstark@5 603 // perform the FFT
adamstark@5 604 perform_FFT();
adamstark@5 605
adamstark@5 606 sum = 0; // initialise sum to zero
adamstark@5 607
adamstark@5 608 // compute phase values from fft output and sum deviations
adamstark@5 609 for (int i = 0;i < framesize;i++)
adamstark@5 610 {
adamstark@5 611 // calculate magnitude value
adamstark@5 612 mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2));
adamstark@5 613
adamstark@5 614 // calculate difference
adamstark@5 615 mag_diff = mag[i] - mag_old[i];
adamstark@5 616
adamstark@5 617 if (mag_diff > 0)
adamstark@5 618 {
adamstark@5 619 sum = sum + (mag_diff*((double) (i+1)));
adamstark@5 620 }
adamstark@5 621
adamstark@5 622 // store values for next calculation
adamstark@5 623 mag_old[i] = mag[i];
adamstark@5 624 }
adamstark@5 625
adamstark@5 626 return sum;
adamstark@5 627 }
adamstark@5 628
adamstark@5 629
adamstark@5 630 ////////////////////////////////////////////////////////////////////////////////////////////////
adamstark@5 631 ////////////////////////////////////////////////////////////////////////////////////////////////
adamstark@5 632 ////////////////////////////// Methods to Calculate Windows ////////////////////////////////////
adamstark@5 633
adamstark@15 634 //=======================================================================
adamstark@5 635 void OnsetDetectionFunction :: set_win_hanning()
adamstark@5 636 {
adamstark@5 637 double N; // variable to store framesize minus 1
adamstark@5 638
adamstark@5 639 N = (double) (framesize-1); // framesize minus 1
adamstark@5 640
adamstark@5 641 // Hanning window calculation
adamstark@5 642 for (int n = 0;n < framesize;n++)
adamstark@5 643 {
adamstark@5 644 window[n] = 0.5*(1-cos(2*pi*(n/N)));
adamstark@5 645 }
adamstark@5 646 }
adamstark@5 647
adamstark@15 648 //=======================================================================
adamstark@5 649 void OnsetDetectionFunction :: set_win_hamming()
adamstark@5 650 {
adamstark@5 651 double N; // variable to store framesize minus 1
adamstark@5 652 double n_val; // double version of index 'n'
adamstark@5 653
adamstark@5 654 N = (double) (framesize-1); // framesize minus 1
adamstark@5 655 n_val = 0;
adamstark@5 656
adamstark@5 657 // Hamming window calculation
adamstark@5 658 for (int n = 0;n < framesize;n++)
adamstark@5 659 {
adamstark@5 660 window[n] = 0.54 - (0.46*cos(2*pi*(n_val/N)));
adamstark@5 661 n_val = n_val+1;
adamstark@5 662 }
adamstark@5 663 }
adamstark@5 664
adamstark@15 665 //=======================================================================
adamstark@5 666 void OnsetDetectionFunction :: set_win_blackman()
adamstark@5 667 {
adamstark@5 668 double N; // variable to store framesize minus 1
adamstark@5 669 double n_val; // double version of index 'n'
adamstark@5 670
adamstark@5 671 N = (double) (framesize-1); // framesize minus 1
adamstark@5 672 n_val = 0;
adamstark@5 673
adamstark@5 674 // Blackman window calculation
adamstark@5 675 for (int n = 0;n < framesize;n++)
adamstark@5 676 {
adamstark@5 677 window[n] = 0.42 - (0.5*cos(2*pi*(n_val/N))) + (0.08*cos(4*pi*(n_val/N)));
adamstark@5 678 n_val = n_val+1;
adamstark@5 679 }
adamstark@5 680 }
adamstark@5 681
adamstark@15 682 //=======================================================================
adamstark@5 683 void OnsetDetectionFunction :: set_win_tukey()
adamstark@5 684 {
adamstark@5 685 double N; // variable to store framesize minus 1
adamstark@5 686 double n_val; // double version of index 'n'
adamstark@5 687 double alpha; // alpha [default value = 0.5];
adamstark@5 688
adamstark@5 689 alpha = 0.5;
adamstark@5 690
adamstark@5 691 N = (double) (framesize-1); // framesize minus 1
adamstark@5 692
adamstark@5 693 // Tukey window calculation
adamstark@5 694
adamstark@5 695 n_val = (double) (-1*((framesize/2)))+1;
adamstark@5 696
adamstark@5 697 for (int n = 0;n < framesize;n++) // left taper
adamstark@5 698 {
adamstark@5 699 if ((n_val >= 0) && (n_val <= (alpha*(N/2))))
adamstark@5 700 {
adamstark@5 701 window[n] = 1.0;
adamstark@5 702 }
adamstark@5 703 else if ((n_val <= 0) && (n_val >= (-1*alpha*(N/2))))
adamstark@5 704 {
adamstark@5 705 window[n] = 1.0;
adamstark@5 706 }
adamstark@5 707 else
adamstark@5 708 {
adamstark@5 709 window[n] = 0.5*(1+cos(pi*(((2*n_val)/(alpha*N))-1)));
adamstark@5 710 }
adamstark@5 711
adamstark@5 712 n_val = n_val+1;
adamstark@5 713 }
adamstark@5 714
adamstark@5 715 }
adamstark@5 716
adamstark@15 717 //=======================================================================
adamstark@5 718 void OnsetDetectionFunction :: set_win_rectangular()
adamstark@5 719 {
adamstark@5 720 // Rectangular window calculation
adamstark@5 721 for (int n = 0;n < framesize;n++)
adamstark@5 722 {
adamstark@5 723 window[n] = 1.0;
adamstark@5 724 }
adamstark@5 725 }
adamstark@5 726
adamstark@5 727
adamstark@5 728
adamstark@5 729 ////////////////////////////////////////////////////////////////////////////////////////////////
adamstark@5 730 ////////////////////////////////////////////////////////////////////////////////////////////////
adamstark@5 731 ///////////////////////////////// Other Handy Methods //////////////////////////////////////////
adamstark@5 732
adamstark@15 733 //=======================================================================
adamstark@5 734 double OnsetDetectionFunction :: princarg(double phaseval)
adamstark@5 735 {
adamstark@5 736 // if phase value is less than or equal to -pi then add 2*pi
adamstark@5 737 while (phaseval <= (-pi))
adamstark@5 738 {
adamstark@5 739 phaseval = phaseval + (2*pi);
adamstark@5 740 }
adamstark@5 741
adamstark@5 742 // if phase value is larger than pi, then subtract 2*pi
adamstark@5 743 while (phaseval > pi)
adamstark@5 744 {
adamstark@5 745 phaseval = phaseval - (2*pi);
adamstark@5 746 }
adamstark@5 747
adamstark@5 748 return phaseval;
adamstark@5 749 }
adamstark@5 750
adamstark@5 751
adamstark@5 752
adamstark@5 753
adamstark@5 754
adamstark@5 755
adamstark@5 756
adamstark@5 757
adamstark@5 758
adamstark@5 759
adamstark@5 760
adamstark@5 761
adamstark@5 762