comparison src/OnsetDetectionFunction.cpp @ 96:c58f01834337

Merge branch 'release/1.0.4'
author Adam Stark <adamstark.uk@gmail.com>
date Sat, 18 Jun 2016 10:50:06 +0100
parents 4aa362058011
children 6aea5918992d
comparison
equal deleted inserted replaced
87:496d12635af8 96:c58f01834337
20 //======================================================================= 20 //=======================================================================
21 21
22 #include <math.h> 22 #include <math.h>
23 #include "OnsetDetectionFunction.h" 23 #include "OnsetDetectionFunction.h"
24 24
25 25 //=======================================================================
26 //======================================================================= 26 OnsetDetectionFunction::OnsetDetectionFunction (int hopSize_,int frameSize_)
27 OnsetDetectionFunction::OnsetDetectionFunction(int hopSize_,int frameSize_) : onsetDetectionFunctionType(ComplexSpectralDifferenceHWR), windowType(HanningWindow) 27 : onsetDetectionFunctionType (ComplexSpectralDifferenceHWR), windowType (HanningWindow)
28 { 28 {
29 // indicate that we have not initialised yet 29 // indicate that we have not initialised yet
30 initialised = false; 30 initialised = false;
31 31
32 // set pi 32 // set pi
33 pi = 3.14159265358979; 33 pi = 3.14159265358979;
34 34
35 // initialise with arguments to constructor 35 // initialise with arguments to constructor
36 initialise(hopSize_,frameSize_,ComplexSpectralDifferenceHWR,HanningWindow); 36 initialise (hopSize_, frameSize_, ComplexSpectralDifferenceHWR, HanningWindow);
37 } 37 }
38 38
39 //======================================================================= 39 //=======================================================================
40 OnsetDetectionFunction::OnsetDetectionFunction(int hopSize_,int frameSize_,int onsetDetectionFunctionType_,int windowType_) : onsetDetectionFunctionType(ComplexSpectralDifferenceHWR), windowType(HanningWindow) 40 OnsetDetectionFunction::OnsetDetectionFunction(int hopSize_,int frameSize_,int onsetDetectionFunctionType_,int windowType_)
41 : onsetDetectionFunctionType (ComplexSpectralDifferenceHWR), windowType (HanningWindow)
41 { 42 {
42 // indicate that we have not initialised yet 43 // indicate that we have not initialised yet
43 initialised = false; 44 initialised = false;
44 45
45 // set pi 46 // set pi
46 pi = 3.14159265358979; 47 pi = 3.14159265358979;
47 48
48 // initialise with arguments to constructor 49 // initialise with arguments to constructor
49 initialise(hopSize_,frameSize_,onsetDetectionFunctionType_,windowType_); 50 initialise (hopSize_, frameSize_, onsetDetectionFunctionType_, windowType_);
50 } 51 }
51 52
52 53
53 //======================================================================= 54 //=======================================================================
54 OnsetDetectionFunction::~OnsetDetectionFunction() 55 OnsetDetectionFunction::~OnsetDetectionFunction()
55 { 56 {
56 if (initialised) 57 if (initialised)
57 { 58 {
58 // destroy fft plan 59 freeFFT();
59 fftw_destroy_plan(p);
60 fftw_free(complexIn);
61 fftw_free(complexOut);
62 } 60 }
63 } 61 }
64 62
65 //======================================================================= 63 //=======================================================================
66 void OnsetDetectionFunction::initialise(int hopSize_,int frameSize_) 64 void OnsetDetectionFunction::initialise (int hopSize_, int frameSize_)
67 { 65 {
68 // use the already initialised onset detection function and window type and 66 // use the already initialised onset detection function and window type and
69 // pass the new frame and hop size to the main initialisation function 67 // pass the new frame and hop size to the main initialisation function
70 initialise(hopSize_, frameSize_, onsetDetectionFunctionType, windowType); 68 initialise (hopSize_, frameSize_, onsetDetectionFunctionType, windowType);
71 } 69 }
72 70
73 //======================================================================= 71 //=======================================================================
74 void OnsetDetectionFunction::initialise(int hopSize_,int frameSize_,int onsetDetectionFunctionType_,int windowType_) 72 void OnsetDetectionFunction::initialise(int hopSize_,int frameSize_,int onsetDetectionFunctionType_,int windowType_)
75 { 73 {
76 if (initialised) // if we have already initialised FFT plan
77 {
78 // destroy fft plan
79 fftw_destroy_plan(p);
80 fftw_free(complexIn);
81 fftw_free(complexOut);
82
83 }
84
85 hopSize = hopSize_; // set hopsize 74 hopSize = hopSize_; // set hopsize
86 frameSize = frameSize_; // set framesize 75 frameSize = frameSize_; // set framesize
87 76
88 onsetDetectionFunctionType = onsetDetectionFunctionType_; // set detection function type 77 onsetDetectionFunctionType = onsetDetectionFunctionType_; // set detection function type
89 windowType = windowType_; // set window type 78 windowType = windowType_; // set window type
90 79
91 // initialise buffers 80 // initialise buffers
92 frame.resize(frameSize); 81 frame.resize (frameSize);
93 window.resize(frameSize); 82 window.resize (frameSize);
94 magSpec.resize(frameSize); 83 magSpec.resize (frameSize);
95 prevMagSpec.resize(frameSize); 84 prevMagSpec.resize (frameSize);
96 phase.resize(frameSize); 85 phase.resize (frameSize);
97 prevPhase.resize(frameSize); 86 prevPhase.resize (frameSize);
98 prevPhase2.resize(frameSize); 87 prevPhase2.resize (frameSize);
99 88
100 89
101 // set the window to the specified type 90 // set the window to the specified type
102 switch (windowType){ 91 switch (windowType)
92 {
103 case RectangularWindow: 93 case RectangularWindow:
104 calculateRectangularWindow(); // Rectangular window 94 calculateRectangularWindow(); // Rectangular window
105 break; 95 break;
106 case HanningWindow: 96 case HanningWindow:
107 calculateHanningWindow(); // Hanning Window 97 calculateHanningWindow(); // Hanning Window
118 default: 108 default:
119 calculateHanningWindow(); // DEFAULT: Hanning Window 109 calculateHanningWindow(); // DEFAULT: Hanning Window
120 } 110 }
121 111
122 // initialise previous magnitude spectrum to zero 112 // initialise previous magnitude spectrum to zero
123 for (int i = 0;i < frameSize;i++) 113 for (int i = 0; i < frameSize; i++)
124 { 114 {
125 prevMagSpec[i] = 0.0; 115 prevMagSpec[i] = 0.0;
126 prevPhase[i] = 0.0; 116 prevPhase[i] = 0.0;
127 prevPhase2[i] = 0.0; 117 prevPhase2[i] = 0.0;
128 frame[i] = 0.0; 118 frame[i] = 0.0;
129 } 119 }
130 120
131 prevEnergySum = 0.0; // initialise previous energy sum value to zero 121 prevEnergySum = 0.0; // initialise previous energy sum value to zero
132 122
133 /* Init fft */ 123 initialiseFFT();
134 complexIn = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * frameSize); // complex array to hold fft data 124 }
135 complexOut = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * frameSize); // complex array to hold fft data 125
136 p = fftw_plan_dft_1d(frameSize, complexIn, complexOut, FFTW_FORWARD, FFTW_ESTIMATE); // FFT plan initialisation 126 //=======================================================================
137 127 void OnsetDetectionFunction::initialiseFFT()
138 initialised = true; 128 {
139 } 129 if (initialised) // if we have already initialised FFT plan
140 130 {
141 //======================================================================= 131 freeFFT();
142 void OnsetDetectionFunction :: setOnsetDetectionFunctionType(int onsetDetectionFunctionType_) 132 }
133
134 #ifdef USE_FFTW
135 complexIn = (fftw_complex*) fftw_malloc (sizeof(fftw_complex) * frameSize); // complex array to hold fft data
136 complexOut = (fftw_complex*) fftw_malloc (sizeof(fftw_complex) * frameSize); // complex array to hold fft data
137 p = fftw_plan_dft_1d (frameSize, complexIn, complexOut, FFTW_FORWARD, FFTW_ESTIMATE); // FFT plan initialisation
138 #endif
139
140 #ifdef USE_KISS_FFT
141 complexOut.resize (frameSize);
142
143 for (int i = 0; i < frameSize;i++)
144 {
145 complexOut[i].resize(2);
146 }
147
148 fftIn = new kiss_fft_cpx[frameSize];
149 fftOut = new kiss_fft_cpx[frameSize];
150 cfg = kiss_fft_alloc (frameSize, 0, 0, 0);
151 #endif
152
153 initialised = true;
154 }
155
156 //=======================================================================
157 void OnsetDetectionFunction::freeFFT()
158 {
159 #ifdef USE_FFTW
160 fftw_destroy_plan (p);
161 fftw_free (complexIn);
162 fftw_free (complexOut);
163 #endif
164
165 #ifdef USE_KISS_FFT
166 free (cfg);
167 delete [] fftIn;
168 delete [] fftOut;
169 #endif
170 }
171
172 //=======================================================================
173 void OnsetDetectionFunction::setOnsetDetectionFunctionType (int onsetDetectionFunctionType_)
143 { 174 {
144 onsetDetectionFunctionType = onsetDetectionFunctionType_; // set detection function type 175 onsetDetectionFunctionType = onsetDetectionFunctionType_; // set detection function type
145 } 176 }
146 177
147 //======================================================================= 178 //=======================================================================
148 double OnsetDetectionFunction :: calculateOnsetDetectionFunctionSample(double *buffer) 179 double OnsetDetectionFunction::calculateOnsetDetectionFunctionSample (double* buffer)
149 { 180 {
150 double odfSample; 181 double odfSample;
151 182
152 // shift audio samples back in frame by hop size 183 // shift audio samples back in frame by hop size
153 for (int i = 0; i < (frameSize-hopSize);i++) 184 for (int i = 0; i < (frameSize-hopSize);i++)
161 { 192 {
162 frame[i] = buffer[j]; 193 frame[i] = buffer[j];
163 j++; 194 j++;
164 } 195 }
165 196
166 switch (onsetDetectionFunctionType){ 197 switch (onsetDetectionFunctionType)
198 {
167 case EnergyEnvelope: 199 case EnergyEnvelope:
168 { 200 {
169 // calculate energy envelope detection function sample 201 // calculate energy envelope detection function sample
170 odfSample = energyEnvelope(); 202 odfSample = energyEnvelope();
171 break; 203 break;
233 return odfSample; 265 return odfSample;
234 } 266 }
235 267
236 268
237 //======================================================================= 269 //=======================================================================
238 void OnsetDetectionFunction :: performFFT() 270 void OnsetDetectionFunction::performFFT()
239 { 271 {
240 int fsize2 = (frameSize/2); 272 int fsize2 = (frameSize/2);
241 273
274 #ifdef USE_FFTW
242 // window frame and copy to complex array, swapping the first and second half of the signal 275 // window frame and copy to complex array, swapping the first and second half of the signal
243 for (int i = 0;i < fsize2;i++) 276 for (int i = 0;i < fsize2;i++)
244 { 277 {
245 complexIn[i][0] = frame[i+fsize2] * window[i+fsize2]; 278 complexIn[i][0] = frame[i + fsize2] * window[i + fsize2];
246 complexIn[i][1] = 0.0; 279 complexIn[i][1] = 0.0;
247 complexIn[i+fsize2][0] = frame[i] * window[i]; 280 complexIn[i+fsize2][0] = frame[i] * window[i];
248 complexIn[i+fsize2][1] = 0.0; 281 complexIn[i+fsize2][1] = 0.0;
249 } 282 }
250 283
251 // perform the fft 284 // perform the fft
252 fftw_execute(p); 285 fftw_execute (p);
286 #endif
287
288 #ifdef USE_KISS_FFT
289 for (int i = 0; i < fsize2; i++)
290 {
291 fftIn[i].r = frame[i + fsize2] * window[i + fsize2];
292 fftIn[i].i = 0.0;
293 fftIn[i + fsize2].r = frame[i] * window[i];
294 fftIn[i + fsize2].i = 0.0;
295 }
296
297 // execute kiss fft
298 kiss_fft (cfg, fftIn, fftOut);
299
300 // store real and imaginary parts of FFT
301 for (int i = 0; i < frameSize; i++)
302 {
303 complexOut[i][0] = fftOut[i].r;
304 complexOut[i][1] = fftOut[i].i;
305 }
306 #endif
253 } 307 }
254 308
255 //////////////////////////////////////////////////////////////////////////////////////////////// 309 ////////////////////////////////////////////////////////////////////////////////////////////////
256 //////////////////////////////////////////////////////////////////////////////////////////////// 310 ////////////////////////////////////////////////////////////////////////////////////////////////
257 ////////////////////////////// Methods for Detection Functions ///////////////////////////////// 311 ////////////////////////////// Methods for Detection Functions /////////////////////////////////
258 312
259 //======================================================================= 313 //=======================================================================
260 double OnsetDetectionFunction :: energyEnvelope() 314 double OnsetDetectionFunction::energyEnvelope()
261 { 315 {
262 double sum; 316 double sum;
263 317
264 sum = 0; // initialise sum 318 sum = 0; // initialise sum
265 319
266 // sum the squares of the samples 320 // sum the squares of the samples
267 for (int i = 0;i < frameSize;i++) 321 for (int i = 0;i < frameSize;i++)
268 { 322 {
269 sum = sum + (frame[i]*frame[i]); 323 sum = sum + (frame[i] * frame[i]);
270 } 324 }
271 325
272 return sum; // return sum 326 return sum; // return sum
273 } 327 }
274 328
275 //======================================================================= 329 //=======================================================================
276 double OnsetDetectionFunction :: energyDifference() 330 double OnsetDetectionFunction::energyDifference()
277 { 331 {
278 double sum; 332 double sum;
279 double sample; 333 double sample;
280 334
281 sum = 0; // initialise sum 335 sum = 0; // initialise sum
282 336
283 // sum the squares of the samples 337 // sum the squares of the samples
284 for (int i = 0;i < frameSize;i++) 338 for (int i = 0; i < frameSize; i++)
285 { 339 {
286 sum = sum + (frame[i]*frame[i]); 340 sum = sum + (frame[i] * frame[i]);
287 } 341 }
288 342
289 sample = sum - prevEnergySum; // sample is first order difference in energy 343 sample = sum - prevEnergySum; // sample is first order difference in energy
290 344
291 prevEnergySum = sum; // store energy value for next calculation 345 prevEnergySum = sum; // store energy value for next calculation
299 return 0; 353 return 0;
300 } 354 }
301 } 355 }
302 356
303 //======================================================================= 357 //=======================================================================
304 double OnsetDetectionFunction :: spectralDifference() 358 double OnsetDetectionFunction::spectralDifference()
305 { 359 {
306 double diff; 360 double diff;
307 double sum; 361 double sum;
308 362
309 // perform the FFT 363 // perform the FFT
310 performFFT(); 364 performFFT();
311 365
312 // compute first (N/2)+1 mag values 366 // compute first (N/2)+1 mag values
313 for (int i = 0;i < (frameSize/2)+1;i++) 367 for (int i = 0;i < (frameSize/2)+1;i++)
314 { 368 {
315 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2)); 369 magSpec[i] = sqrt (pow (complexOut[i][0], 2) + pow (complexOut[i][1], 2));
316 } 370 }
317 // mag spec symmetric above (N/2)+1 so copy previous values 371 // mag spec symmetric above (N/2)+1 so copy previous values
318 for (int i = (frameSize/2)+1;i < frameSize;i++) 372 for (int i = (frameSize/2)+1; i < frameSize; i++)
319 { 373 {
320 magSpec[i] = magSpec[frameSize-i]; 374 magSpec[i] = magSpec[frameSize-i];
321 } 375 }
322 376
323 sum = 0; // initialise sum to zero 377 sum = 0; // initialise sum to zero
324 378
325 for (int i = 0;i < frameSize;i++) 379 for (int i = 0; i < frameSize; i++)
326 { 380 {
327 // calculate difference 381 // calculate difference
328 diff = magSpec[i] - prevMagSpec[i]; 382 diff = magSpec[i] - prevMagSpec[i];
329 383
330 // ensure all difference values are positive 384 // ensure all difference values are positive
332 { 386 {
333 diff = diff*-1; 387 diff = diff*-1;
334 } 388 }
335 389
336 // add difference to sum 390 // add difference to sum
337 sum = sum+diff; 391 sum = sum + diff;
338 392
339 // store magnitude spectrum bin for next detection function sample calculation 393 // store magnitude spectrum bin for next detection function sample calculation
340 prevMagSpec[i] = magSpec[i]; 394 prevMagSpec[i] = magSpec[i];
341 } 395 }
342 396
343 return sum; 397 return sum;
344 } 398 }
345 399
346 //======================================================================= 400 //=======================================================================
347 double OnsetDetectionFunction :: spectralDifferenceHWR() 401 double OnsetDetectionFunction::spectralDifferenceHWR()
348 { 402 {
349 double diff; 403 double diff;
350 double sum; 404 double sum;
351 405
352 // perform the FFT 406 // perform the FFT
353 performFFT(); 407 performFFT();
354 408
355 // compute first (N/2)+1 mag values 409 // compute first (N/2)+1 mag values
356 for (int i = 0;i < (frameSize/2)+1;i++) 410 for (int i = 0;i < (frameSize/2) + 1; i++)
357 { 411 {
358 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2)); 412 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow (complexOut[i][1],2));
359 } 413 }
360 // mag spec symmetric above (N/2)+1 so copy previous values 414 // mag spec symmetric above (N/2)+1 so copy previous values
361 for (int i = (frameSize/2)+1;i < frameSize;i++) 415 for (int i = (frameSize/2)+1;i < frameSize;i++)
362 { 416 {
363 magSpec[i] = magSpec[frameSize-i]; 417 magSpec[i] = magSpec[frameSize-i];
375 { 429 {
376 // add difference to sum 430 // add difference to sum
377 sum = sum+diff; 431 sum = sum+diff;
378 } 432 }
379 433
380
381
382 // store magnitude spectrum bin for next detection function sample calculation 434 // store magnitude spectrum bin for next detection function sample calculation
383 prevMagSpec[i] = magSpec[i]; 435 prevMagSpec[i] = magSpec[i];
384 } 436 }
385 437
386 return sum; 438 return sum;
387 } 439 }
388 440
389 441
390 //======================================================================= 442 //=======================================================================
391 double OnsetDetectionFunction :: phaseDeviation() 443 double OnsetDetectionFunction::phaseDeviation()
392 { 444 {
393 double dev,pdev; 445 double dev,pdev;
394 double sum; 446 double sum;
395 447
396 // perform the FFT 448 // perform the FFT
400 452
401 // compute phase values from fft output and sum deviations 453 // compute phase values from fft output and sum deviations
402 for (int i = 0;i < frameSize;i++) 454 for (int i = 0;i < frameSize;i++)
403 { 455 {
404 // calculate phase value 456 // calculate phase value
405 phase[i] = atan2(complexOut[i][1],complexOut[i][0]); 457 phase[i] = atan2 (complexOut[i][1], complexOut[i][0]);
406 458
407 // calculate magnitude value 459 // calculate magnitude value
408 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2)); 460 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow (complexOut[i][1],2));
409 461
410 462
411 // if bin is not just a low energy bin then examine phase deviation 463 // if bin is not just a low energy bin then examine phase deviation
412 if (magSpec[i] > 0.1) 464 if (magSpec[i] > 0.1)
413 { 465 {
414 dev = phase[i] - (2*prevPhase[i]) + prevPhase2[i]; // phase deviation 466 dev = phase[i] - (2*prevPhase[i]) + prevPhase2[i]; // phase deviation
415 pdev = princarg(dev); // wrap into [-pi,pi] range 467 pdev = princarg (dev); // wrap into [-pi,pi] range
416 468
417 // make all values positive 469 // make all values positive
418 if (pdev < 0) 470 if (pdev < 0)
419 { 471 {
420 pdev = pdev*-1; 472 pdev = pdev*-1;
431 483
432 return sum; 484 return sum;
433 } 485 }
434 486
435 //======================================================================= 487 //=======================================================================
436 double OnsetDetectionFunction :: complexSpectralDifference() 488 double OnsetDetectionFunction::complexSpectralDifference()
437 { 489 {
438 double phaseDeviation; 490 double phaseDeviation;
439 double sum; 491 double sum;
440 double csd; 492 double csd;
441 493
446 498
447 // compute phase values from fft output and sum deviations 499 // compute phase values from fft output and sum deviations
448 for (int i = 0;i < frameSize;i++) 500 for (int i = 0;i < frameSize;i++)
449 { 501 {
450 // calculate phase value 502 // calculate phase value
451 phase[i] = atan2(complexOut[i][1],complexOut[i][0]); 503 phase[i] = atan2 (complexOut[i][1], complexOut[i][0]);
452 504
453 // calculate magnitude value 505 // calculate magnitude value
454 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2)); 506 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow(complexOut[i][1],2));
455 507
456 // phase deviation 508 // phase deviation
457 phaseDeviation = phase[i] - (2*prevPhase[i]) + prevPhase2[i]; 509 phaseDeviation = phase[i] - (2 * prevPhase[i]) + prevPhase2[i];
458 510
459 // calculate complex spectral difference for the current spectral bin 511 // calculate complex spectral difference for the current spectral bin
460 csd = sqrt(pow(magSpec[i], 2) + pow(prevMagSpec[i], 2) - 2 * magSpec[i] * prevMagSpec[i] * cos(phaseDeviation)); 512 csd = sqrt (pow (magSpec[i], 2) + pow (prevMagSpec[i], 2) - 2 * magSpec[i] * prevMagSpec[i] * cos (phaseDeviation));
461 513
462 // add to sum 514 // add to sum
463 sum = sum + csd; 515 sum = sum + csd;
464 516
465 // store values for next calculation 517 // store values for next calculation
470 522
471 return sum; 523 return sum;
472 } 524 }
473 525
474 //======================================================================= 526 //=======================================================================
475 double OnsetDetectionFunction :: complexSpectralDifferenceHWR() 527 double OnsetDetectionFunction::complexSpectralDifferenceHWR()
476 { 528 {
477 double phaseDeviation; 529 double phaseDeviation;
478 double sum; 530 double sum;
479 double magnitudeDifference; 531 double magnitudeDifference;
480 double csd; 532 double csd;
486 538
487 // compute phase values from fft output and sum deviations 539 // compute phase values from fft output and sum deviations
488 for (int i = 0;i < frameSize;i++) 540 for (int i = 0;i < frameSize;i++)
489 { 541 {
490 // calculate phase value 542 // calculate phase value
491 phase[i] = atan2(complexOut[i][1],complexOut[i][0]); 543 phase[i] = atan2 (complexOut[i][1], complexOut[i][0]);
492 544
493 // calculate magnitude value 545 // calculate magnitude value
494 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2)); 546 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow(complexOut[i][1],2));
495 547
496 // phase deviation 548 // phase deviation
497 phaseDeviation = phase[i] - (2*prevPhase[i]) + prevPhase2[i]; 549 phaseDeviation = phase[i] - (2 * prevPhase[i]) + prevPhase2[i];
498 550
499 // calculate magnitude difference (real part of Euclidean distance between complex frames) 551 // calculate magnitude difference (real part of Euclidean distance between complex frames)
500 magnitudeDifference = magSpec[i] - prevMagSpec[i]; 552 magnitudeDifference = magSpec[i] - prevMagSpec[i];
501 553
502 // if we have a positive change in magnitude, then include in sum, otherwise ignore (half-wave rectification) 554 // if we have a positive change in magnitude, then include in sum, otherwise ignore (half-wave rectification)
503 if (magnitudeDifference > 0) 555 if (magnitudeDifference > 0)
504 { 556 {
505 // calculate complex spectral difference for the current spectral bin 557 // calculate complex spectral difference for the current spectral bin
506 csd = sqrt(pow(magSpec[i], 2) + pow(prevMagSpec[i], 2) - 2 * magSpec[i] * prevMagSpec[i] * cos(phaseDeviation)); 558 csd = sqrt (pow (magSpec[i], 2) + pow (prevMagSpec[i], 2) - 2 * magSpec[i] * prevMagSpec[i] * cos (phaseDeviation));
507 559
508 // add to sum 560 // add to sum
509 sum = sum + csd; 561 sum = sum + csd;
510 } 562 }
511 563
518 return sum; 570 return sum;
519 } 571 }
520 572
521 573
522 //======================================================================= 574 //=======================================================================
523 double OnsetDetectionFunction :: highFrequencyContent() 575 double OnsetDetectionFunction::highFrequencyContent()
524 { 576 {
525 double sum; 577 double sum;
578
579 // perform the FFT
580 performFFT();
581
582 sum = 0; // initialise sum to zero
583
584 // compute phase values from fft output and sum deviations
585 for (int i = 0; i < frameSize; i++)
586 {
587 // calculate magnitude value
588 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow (complexOut[i][1],2));
589
590
591 sum = sum + (magSpec[i] * ((double) (i+1)));
592
593 // store values for next calculation
594 prevMagSpec[i] = magSpec[i];
595 }
596
597 return sum;
598 }
599
600 //=======================================================================
601 double OnsetDetectionFunction::highFrequencySpectralDifference()
602 {
603 double sum;
604 double mag_diff;
526 605
527 // perform the FFT 606 // perform the FFT
528 performFFT(); 607 performFFT();
529 608
530 sum = 0; // initialise sum to zero 609 sum = 0; // initialise sum to zero
531 610
532 // compute phase values from fft output and sum deviations 611 // compute phase values from fft output and sum deviations
533 for (int i = 0;i < frameSize;i++) 612 for (int i = 0;i < frameSize;i++)
534 { 613 {
535 // calculate magnitude value 614 // calculate magnitude value
536 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2)); 615 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow (complexOut[i][1],2));
537 616
538 617 // calculate difference
539 sum = sum + (magSpec[i]*((double) (i+1))); 618 mag_diff = magSpec[i] - prevMagSpec[i];
619
620 if (mag_diff < 0)
621 {
622 mag_diff = -mag_diff;
623 }
624
625 sum = sum + (mag_diff * ((double) (i+1)));
540 626
541 // store values for next calculation 627 // store values for next calculation
542 prevMagSpec[i] = magSpec[i]; 628 prevMagSpec[i] = magSpec[i];
543 } 629 }
544 630
545 return sum; 631 return sum;
546 } 632 }
547 633
548 //======================================================================= 634 //=======================================================================
549 double OnsetDetectionFunction :: highFrequencySpectralDifference() 635 double OnsetDetectionFunction::highFrequencySpectralDifferenceHWR()
550 { 636 {
551 double sum; 637 double sum;
552 double mag_diff; 638 double mag_diff;
553 639
554 // perform the FFT 640 // perform the FFT
558 644
559 // compute phase values from fft output and sum deviations 645 // compute phase values from fft output and sum deviations
560 for (int i = 0;i < frameSize;i++) 646 for (int i = 0;i < frameSize;i++)
561 { 647 {
562 // calculate magnitude value 648 // calculate magnitude value
563 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2)); 649 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow (complexOut[i][1],2));
564 650
565 // calculate difference 651 // calculate difference
566 mag_diff = magSpec[i] - prevMagSpec[i]; 652 mag_diff = magSpec[i] - prevMagSpec[i];
567 653
568 if (mag_diff < 0)
569 {
570 mag_diff = -mag_diff;
571 }
572
573 sum = sum + (mag_diff*((double) (i+1)));
574
575 // store values for next calculation
576 prevMagSpec[i] = magSpec[i];
577 }
578
579 return sum;
580 }
581
582 //=======================================================================
583 double OnsetDetectionFunction :: highFrequencySpectralDifferenceHWR()
584 {
585 double sum;
586 double mag_diff;
587
588 // perform the FFT
589 performFFT();
590
591 sum = 0; // initialise sum to zero
592
593 // compute phase values from fft output and sum deviations
594 for (int i = 0;i < frameSize;i++)
595 {
596 // calculate magnitude value
597 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2));
598
599 // calculate difference
600 mag_diff = magSpec[i] - prevMagSpec[i];
601
602 if (mag_diff > 0) 654 if (mag_diff > 0)
603 { 655 {
604 sum = sum + (mag_diff*((double) (i+1))); 656 sum = sum + (mag_diff * ((double) (i+1)));
605 } 657 }
606 658
607 // store values for next calculation 659 // store values for next calculation
608 prevMagSpec[i] = magSpec[i]; 660 prevMagSpec[i] = magSpec[i];
609 } 661 }
615 //////////////////////////////////////////////////////////////////////////////////////////////// 667 ////////////////////////////////////////////////////////////////////////////////////////////////
616 //////////////////////////////////////////////////////////////////////////////////////////////// 668 ////////////////////////////////////////////////////////////////////////////////////////////////
617 ////////////////////////////// Methods to Calculate Windows //////////////////////////////////// 669 ////////////////////////////// Methods to Calculate Windows ////////////////////////////////////
618 670
619 //======================================================================= 671 //=======================================================================
620 void OnsetDetectionFunction :: calculateHanningWindow() 672 void OnsetDetectionFunction::calculateHanningWindow()
621 { 673 {
622 double N; // variable to store framesize minus 1 674 double N; // variable to store framesize minus 1
623 675
624 N = (double) (frameSize-1); // framesize minus 1 676 N = (double) (frameSize-1); // framesize minus 1
625 677
626 // Hanning window calculation 678 // Hanning window calculation
627 for (int n = 0;n < frameSize;n++) 679 for (int n = 0; n < frameSize; n++)
628 { 680 {
629 window[n] = 0.5*(1-cos(2*pi*(n/N))); 681 window[n] = 0.5 * (1 - cos (2 * pi * (n / N)));
630 } 682 }
631 } 683 }
632 684
633 //======================================================================= 685 //=======================================================================
634 void OnsetDetectionFunction :: calclulateHammingWindow() 686 void OnsetDetectionFunction::calclulateHammingWindow()
635 { 687 {
636 double N; // variable to store framesize minus 1 688 double N; // variable to store framesize minus 1
637 double n_val; // double version of index 'n' 689 double n_val; // double version of index 'n'
638 690
639 N = (double) (frameSize-1); // framesize minus 1 691 N = (double) (frameSize-1); // framesize minus 1
640 n_val = 0; 692 n_val = 0;
641 693
642 // Hamming window calculation 694 // Hamming window calculation
643 for (int n = 0;n < frameSize;n++) 695 for (int n = 0;n < frameSize;n++)
644 { 696 {
645 window[n] = 0.54 - (0.46*cos(2*pi*(n_val/N))); 697 window[n] = 0.54 - (0.46 * cos (2 * pi * (n_val/N)));
646 n_val = n_val+1; 698 n_val = n_val+1;
647 } 699 }
648 } 700 }
649 701
650 //======================================================================= 702 //=======================================================================
651 void OnsetDetectionFunction :: calculateBlackmanWindow() 703 void OnsetDetectionFunction::calculateBlackmanWindow()
652 { 704 {
653 double N; // variable to store framesize minus 1 705 double N; // variable to store framesize minus 1
654 double n_val; // double version of index 'n' 706 double n_val; // double version of index 'n'
655 707
656 N = (double) (frameSize-1); // framesize minus 1 708 N = (double) (frameSize-1); // framesize minus 1
663 n_val = n_val+1; 715 n_val = n_val+1;
664 } 716 }
665 } 717 }
666 718
667 //======================================================================= 719 //=======================================================================
668 void OnsetDetectionFunction :: calculateTukeyWindow() 720 void OnsetDetectionFunction::calculateTukeyWindow()
669 { 721 {
670 double N; // variable to store framesize minus 1 722 double N; // variable to store framesize minus 1
671 double n_val; // double version of index 'n' 723 double n_val; // double version of index 'n'
672 double alpha; // alpha [default value = 0.5]; 724 double alpha; // alpha [default value = 0.5];
673 725
698 } 750 }
699 751
700 } 752 }
701 753
702 //======================================================================= 754 //=======================================================================
703 void OnsetDetectionFunction :: calculateRectangularWindow() 755 void OnsetDetectionFunction::calculateRectangularWindow()
704 { 756 {
705 // Rectangular window calculation 757 // Rectangular window calculation
706 for (int n = 0;n < frameSize;n++) 758 for (int n = 0;n < frameSize;n++)
707 { 759 {
708 window[n] = 1.0; 760 window[n] = 1.0;
709 } 761 }
710 } 762 }
711
712
713 763
714 //////////////////////////////////////////////////////////////////////////////////////////////// 764 ////////////////////////////////////////////////////////////////////////////////////////////////
715 //////////////////////////////////////////////////////////////////////////////////////////////// 765 ////////////////////////////////////////////////////////////////////////////////////////////////
716 ///////////////////////////////// Other Handy Methods ////////////////////////////////////////// 766 ///////////////////////////////// Other Handy Methods //////////////////////////////////////////
717 767
718 //======================================================================= 768 //=======================================================================
719 double OnsetDetectionFunction :: princarg(double phaseVal) 769 double OnsetDetectionFunction::princarg(double phaseVal)
720 { 770 {
721 // if phase value is less than or equal to -pi then add 2*pi 771 // if phase value is less than or equal to -pi then add 2*pi
722 while (phaseVal <= (-pi)) 772 while (phaseVal <= (-pi))
723 { 773 {
724 phaseVal = phaseVal + (2*pi); 774 phaseVal = phaseVal + (2 * pi);
725 } 775 }
726 776
727 // if phase value is larger than pi, then subtract 2*pi 777 // if phase value is larger than pi, then subtract 2*pi
728 while (phaseVal > pi) 778 while (phaseVal > pi)
729 { 779 {
730 phaseVal = phaseVal - (2*pi); 780 phaseVal = phaseVal - (2 * pi);
731 } 781 }
732 782
733 return phaseVal; 783 return phaseVal;
734 } 784 }
735
736
737
738
739
740
741
742
743
744
745
746
747