Mercurial > hg > btrack
comparison src/OnsetDetectionFunction.cpp @ 92:f6708e4c69f1
More code style updates
author | Adam Stark <adamstark.uk@gmail.com> |
---|---|
date | Wed, 11 May 2016 00:19:06 +0100 |
parents | 5eeabb24d677 |
children | 4aa362058011 |
comparison
equal
deleted
inserted
replaced
91:a88d887bd281 | 92:f6708e4c69f1 |
---|---|
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 // destroy fft plan |
59 fftw_destroy_plan(p); | 60 fftw_destroy_plan (p); |
60 fftw_free(complexIn); | 61 fftw_free (complexIn); |
61 fftw_free(complexOut); | 62 fftw_free (complexOut); |
62 } | 63 } |
63 } | 64 } |
64 | 65 |
65 //======================================================================= | 66 //======================================================================= |
66 void OnsetDetectionFunction::initialise(int hopSize_,int frameSize_) | 67 void OnsetDetectionFunction::initialise (int hopSize_, int frameSize_) |
67 { | 68 { |
68 // use the already initialised onset detection function and window type and | 69 // use the already initialised onset detection function and window type and |
69 // pass the new frame and hop size to the main initialisation function | 70 // pass the new frame and hop size to the main initialisation function |
70 initialise(hopSize_, frameSize_, onsetDetectionFunctionType, windowType); | 71 initialise (hopSize_, frameSize_, onsetDetectionFunctionType, windowType); |
71 } | 72 } |
72 | 73 |
73 //======================================================================= | 74 //======================================================================= |
74 void OnsetDetectionFunction::initialise(int hopSize_,int frameSize_,int onsetDetectionFunctionType_,int windowType_) | 75 void OnsetDetectionFunction::initialise(int hopSize_,int frameSize_,int onsetDetectionFunctionType_,int windowType_) |
75 { | 76 { |
76 if (initialised) // if we have already initialised FFT plan | 77 if (initialised) // if we have already initialised FFT plan |
77 { | 78 { |
78 // destroy fft plan | 79 // destroy fft plan |
79 fftw_destroy_plan(p); | 80 fftw_destroy_plan (p); |
80 fftw_free(complexIn); | 81 fftw_free (complexIn); |
81 fftw_free(complexOut); | 82 fftw_free (complexOut); |
82 | |
83 } | 83 } |
84 | 84 |
85 hopSize = hopSize_; // set hopsize | 85 hopSize = hopSize_; // set hopsize |
86 frameSize = frameSize_; // set framesize | 86 frameSize = frameSize_; // set framesize |
87 | 87 |
88 onsetDetectionFunctionType = onsetDetectionFunctionType_; // set detection function type | 88 onsetDetectionFunctionType = onsetDetectionFunctionType_; // set detection function type |
89 windowType = windowType_; // set window type | 89 windowType = windowType_; // set window type |
90 | 90 |
91 // initialise buffers | 91 // initialise buffers |
92 frame.resize(frameSize); | 92 frame.resize (frameSize); |
93 window.resize(frameSize); | 93 window.resize (frameSize); |
94 magSpec.resize(frameSize); | 94 magSpec.resize (frameSize); |
95 prevMagSpec.resize(frameSize); | 95 prevMagSpec.resize (frameSize); |
96 phase.resize(frameSize); | 96 phase.resize (frameSize); |
97 prevPhase.resize(frameSize); | 97 prevPhase.resize (frameSize); |
98 prevPhase2.resize(frameSize); | 98 prevPhase2.resize (frameSize); |
99 | 99 |
100 | 100 |
101 // set the window to the specified type | 101 // set the window to the specified type |
102 switch (windowType){ | 102 switch (windowType) |
103 { | |
103 case RectangularWindow: | 104 case RectangularWindow: |
104 calculateRectangularWindow(); // Rectangular window | 105 calculateRectangularWindow(); // Rectangular window |
105 break; | 106 break; |
106 case HanningWindow: | 107 case HanningWindow: |
107 calculateHanningWindow(); // Hanning Window | 108 calculateHanningWindow(); // Hanning Window |
118 default: | 119 default: |
119 calculateHanningWindow(); // DEFAULT: Hanning Window | 120 calculateHanningWindow(); // DEFAULT: Hanning Window |
120 } | 121 } |
121 | 122 |
122 // initialise previous magnitude spectrum to zero | 123 // initialise previous magnitude spectrum to zero |
123 for (int i = 0;i < frameSize;i++) | 124 for (int i = 0; i < frameSize; i++) |
124 { | 125 { |
125 prevMagSpec[i] = 0.0; | 126 prevMagSpec[i] = 0.0; |
126 prevPhase[i] = 0.0; | 127 prevPhase[i] = 0.0; |
127 prevPhase2[i] = 0.0; | 128 prevPhase2[i] = 0.0; |
128 frame[i] = 0.0; | 129 frame[i] = 0.0; |
131 prevEnergySum = 0.0; // initialise previous energy sum value to zero | 132 prevEnergySum = 0.0; // initialise previous energy sum value to zero |
132 | 133 |
133 /* Init fft */ | 134 /* Init fft */ |
134 complexIn = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * frameSize); // complex array to hold fft data | 135 complexIn = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * frameSize); // complex array to hold fft data |
135 complexOut = (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 |
136 p = fftw_plan_dft_1d(frameSize, complexIn, complexOut, FFTW_FORWARD, FFTW_ESTIMATE); // FFT plan initialisation | 137 p = fftw_plan_dft_1d (frameSize, complexIn, complexOut, FFTW_FORWARD, FFTW_ESTIMATE); // FFT plan initialisation |
137 | 138 |
138 initialised = true; | 139 initialised = true; |
139 } | 140 } |
140 | 141 |
141 //======================================================================= | 142 //======================================================================= |
142 void OnsetDetectionFunction :: setOnsetDetectionFunctionType(int onsetDetectionFunctionType_) | 143 void OnsetDetectionFunction::setOnsetDetectionFunctionType (int onsetDetectionFunctionType_) |
143 { | 144 { |
144 onsetDetectionFunctionType = onsetDetectionFunctionType_; // set detection function type | 145 onsetDetectionFunctionType = onsetDetectionFunctionType_; // set detection function type |
145 } | 146 } |
146 | 147 |
147 //======================================================================= | 148 //======================================================================= |
148 double OnsetDetectionFunction :: calculateOnsetDetectionFunctionSample(double *buffer) | 149 double OnsetDetectionFunction::calculateOnsetDetectionFunctionSample (double* buffer) |
149 { | 150 { |
150 double odfSample; | 151 double odfSample; |
151 | 152 |
152 // shift audio samples back in frame by hop size | 153 // shift audio samples back in frame by hop size |
153 for (int i = 0; i < (frameSize-hopSize);i++) | 154 for (int i = 0; i < (frameSize-hopSize);i++) |
161 { | 162 { |
162 frame[i] = buffer[j]; | 163 frame[i] = buffer[j]; |
163 j++; | 164 j++; |
164 } | 165 } |
165 | 166 |
166 switch (onsetDetectionFunctionType){ | 167 switch (onsetDetectionFunctionType) |
168 { | |
167 case EnergyEnvelope: | 169 case EnergyEnvelope: |
168 { | 170 { |
169 // calculate energy envelope detection function sample | 171 // calculate energy envelope detection function sample |
170 odfSample = energyEnvelope(); | 172 odfSample = energyEnvelope(); |
171 break; | 173 break; |
233 return odfSample; | 235 return odfSample; |
234 } | 236 } |
235 | 237 |
236 | 238 |
237 //======================================================================= | 239 //======================================================================= |
238 void OnsetDetectionFunction :: performFFT() | 240 void OnsetDetectionFunction::performFFT() |
239 { | 241 { |
240 int fsize2 = (frameSize/2); | 242 int fsize2 = (frameSize/2); |
241 | 243 |
242 // window frame and copy to complex array, swapping the first and second half of the signal | 244 // window frame and copy to complex array, swapping the first and second half of the signal |
243 for (int i = 0;i < fsize2;i++) | 245 for (int i = 0;i < fsize2;i++) |
247 complexIn[i+fsize2][0] = frame[i] * window[i]; | 249 complexIn[i+fsize2][0] = frame[i] * window[i]; |
248 complexIn[i+fsize2][1] = 0.0; | 250 complexIn[i+fsize2][1] = 0.0; |
249 } | 251 } |
250 | 252 |
251 // perform the fft | 253 // perform the fft |
252 fftw_execute(p); | 254 fftw_execute (p); |
253 } | 255 } |
254 | 256 |
255 //////////////////////////////////////////////////////////////////////////////////////////////// | 257 //////////////////////////////////////////////////////////////////////////////////////////////// |
256 //////////////////////////////////////////////////////////////////////////////////////////////// | 258 //////////////////////////////////////////////////////////////////////////////////////////////// |
257 ////////////////////////////// Methods for Detection Functions ///////////////////////////////// | 259 ////////////////////////////// Methods for Detection Functions ///////////////////////////////// |
258 | 260 |
259 //======================================================================= | 261 //======================================================================= |
260 double OnsetDetectionFunction :: energyEnvelope() | 262 double OnsetDetectionFunction::energyEnvelope() |
261 { | 263 { |
262 double sum; | 264 double sum; |
263 | 265 |
264 sum = 0; // initialise sum | 266 sum = 0; // initialise sum |
265 | 267 |
266 // sum the squares of the samples | 268 // sum the squares of the samples |
267 for (int i = 0;i < frameSize;i++) | 269 for (int i = 0;i < frameSize;i++) |
268 { | 270 { |
269 sum = sum + (frame[i]*frame[i]); | 271 sum = sum + (frame[i] * frame[i]); |
270 } | 272 } |
271 | 273 |
272 return sum; // return sum | 274 return sum; // return sum |
273 } | 275 } |
274 | 276 |
275 //======================================================================= | 277 //======================================================================= |
276 double OnsetDetectionFunction :: energyDifference() | 278 double OnsetDetectionFunction::energyDifference() |
277 { | 279 { |
278 double sum; | 280 double sum; |
279 double sample; | 281 double sample; |
280 | 282 |
281 sum = 0; // initialise sum | 283 sum = 0; // initialise sum |
282 | 284 |
283 // sum the squares of the samples | 285 // sum the squares of the samples |
284 for (int i = 0;i < frameSize;i++) | 286 for (int i = 0; i < frameSize; i++) |
285 { | 287 { |
286 sum = sum + (frame[i]*frame[i]); | 288 sum = sum + (frame[i] * frame[i]); |
287 } | 289 } |
288 | 290 |
289 sample = sum - prevEnergySum; // sample is first order difference in energy | 291 sample = sum - prevEnergySum; // sample is first order difference in energy |
290 | 292 |
291 prevEnergySum = sum; // store energy value for next calculation | 293 prevEnergySum = sum; // store energy value for next calculation |
299 return 0; | 301 return 0; |
300 } | 302 } |
301 } | 303 } |
302 | 304 |
303 //======================================================================= | 305 //======================================================================= |
304 double OnsetDetectionFunction :: spectralDifference() | 306 double OnsetDetectionFunction::spectralDifference() |
305 { | 307 { |
306 double diff; | 308 double diff; |
307 double sum; | 309 double sum; |
308 | 310 |
309 // perform the FFT | 311 // perform the FFT |
310 performFFT(); | 312 performFFT(); |
311 | 313 |
312 // compute first (N/2)+1 mag values | 314 // compute first (N/2)+1 mag values |
313 for (int i = 0;i < (frameSize/2)+1;i++) | 315 for (int i = 0;i < (frameSize/2)+1;i++) |
314 { | 316 { |
315 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2)); | 317 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow (complexOut[i][1],2)); |
316 } | 318 } |
317 // mag spec symmetric above (N/2)+1 so copy previous values | 319 // mag spec symmetric above (N/2)+1 so copy previous values |
318 for (int i = (frameSize/2)+1;i < frameSize;i++) | 320 for (int i = (frameSize/2)+1; i < frameSize; i++) |
319 { | 321 { |
320 magSpec[i] = magSpec[frameSize-i]; | 322 magSpec[i] = magSpec[frameSize-i]; |
321 } | 323 } |
322 | 324 |
323 sum = 0; // initialise sum to zero | 325 sum = 0; // initialise sum to zero |
324 | 326 |
325 for (int i = 0;i < frameSize;i++) | 327 for (int i = 0; i < frameSize; i++) |
326 { | 328 { |
327 // calculate difference | 329 // calculate difference |
328 diff = magSpec[i] - prevMagSpec[i]; | 330 diff = magSpec[i] - prevMagSpec[i]; |
329 | 331 |
330 // ensure all difference values are positive | 332 // ensure all difference values are positive |
332 { | 334 { |
333 diff = diff*-1; | 335 diff = diff*-1; |
334 } | 336 } |
335 | 337 |
336 // add difference to sum | 338 // add difference to sum |
337 sum = sum+diff; | 339 sum = sum + diff; |
338 | 340 |
339 // store magnitude spectrum bin for next detection function sample calculation | 341 // store magnitude spectrum bin for next detection function sample calculation |
340 prevMagSpec[i] = magSpec[i]; | 342 prevMagSpec[i] = magSpec[i]; |
341 } | 343 } |
342 | 344 |
343 return sum; | 345 return sum; |
344 } | 346 } |
345 | 347 |
346 //======================================================================= | 348 //======================================================================= |
347 double OnsetDetectionFunction :: spectralDifferenceHWR() | 349 double OnsetDetectionFunction::spectralDifferenceHWR() |
348 { | 350 { |
349 double diff; | 351 double diff; |
350 double sum; | 352 double sum; |
351 | 353 |
352 // perform the FFT | 354 // perform the FFT |
353 performFFT(); | 355 performFFT(); |
354 | 356 |
355 // compute first (N/2)+1 mag values | 357 // compute first (N/2)+1 mag values |
356 for (int i = 0;i < (frameSize/2)+1;i++) | 358 for (int i = 0;i < (frameSize/2) + 1; i++) |
357 { | 359 { |
358 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2)); | 360 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow (complexOut[i][1],2)); |
359 } | 361 } |
360 // mag spec symmetric above (N/2)+1 so copy previous values | 362 // mag spec symmetric above (N/2)+1 so copy previous values |
361 for (int i = (frameSize/2)+1;i < frameSize;i++) | 363 for (int i = (frameSize/2)+1;i < frameSize;i++) |
362 { | 364 { |
363 magSpec[i] = magSpec[frameSize-i]; | 365 magSpec[i] = magSpec[frameSize-i]; |
375 { | 377 { |
376 // add difference to sum | 378 // add difference to sum |
377 sum = sum+diff; | 379 sum = sum+diff; |
378 } | 380 } |
379 | 381 |
380 | |
381 | |
382 // store magnitude spectrum bin for next detection function sample calculation | 382 // store magnitude spectrum bin for next detection function sample calculation |
383 prevMagSpec[i] = magSpec[i]; | 383 prevMagSpec[i] = magSpec[i]; |
384 } | 384 } |
385 | 385 |
386 return sum; | 386 return sum; |
387 } | 387 } |
388 | 388 |
389 | 389 |
390 //======================================================================= | 390 //======================================================================= |
391 double OnsetDetectionFunction :: phaseDeviation() | 391 double OnsetDetectionFunction::phaseDeviation() |
392 { | 392 { |
393 double dev,pdev; | 393 double dev,pdev; |
394 double sum; | 394 double sum; |
395 | 395 |
396 // perform the FFT | 396 // perform the FFT |
400 | 400 |
401 // compute phase values from fft output and sum deviations | 401 // compute phase values from fft output and sum deviations |
402 for (int i = 0;i < frameSize;i++) | 402 for (int i = 0;i < frameSize;i++) |
403 { | 403 { |
404 // calculate phase value | 404 // calculate phase value |
405 phase[i] = atan2(complexOut[i][1],complexOut[i][0]); | 405 phase[i] = atan2 (complexOut[i][1],complexOut[i][0]); |
406 | 406 |
407 // calculate magnitude value | 407 // calculate magnitude value |
408 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2)); | 408 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow (complexOut[i][1],2)); |
409 | 409 |
410 | 410 |
411 // if bin is not just a low energy bin then examine phase deviation | 411 // if bin is not just a low energy bin then examine phase deviation |
412 if (magSpec[i] > 0.1) | 412 if (magSpec[i] > 0.1) |
413 { | 413 { |
414 dev = phase[i] - (2*prevPhase[i]) + prevPhase2[i]; // phase deviation | 414 dev = phase[i] - (2*prevPhase[i]) + prevPhase2[i]; // phase deviation |
415 pdev = princarg(dev); // wrap into [-pi,pi] range | 415 pdev = princarg (dev); // wrap into [-pi,pi] range |
416 | 416 |
417 // make all values positive | 417 // make all values positive |
418 if (pdev < 0) | 418 if (pdev < 0) |
419 { | 419 { |
420 pdev = pdev*-1; | 420 pdev = pdev*-1; |
431 | 431 |
432 return sum; | 432 return sum; |
433 } | 433 } |
434 | 434 |
435 //======================================================================= | 435 //======================================================================= |
436 double OnsetDetectionFunction :: complexSpectralDifference() | 436 double OnsetDetectionFunction::complexSpectralDifference() |
437 { | 437 { |
438 double phaseDeviation; | 438 double phaseDeviation; |
439 double sum; | 439 double sum; |
440 double csd; | 440 double csd; |
441 | 441 |
446 | 446 |
447 // compute phase values from fft output and sum deviations | 447 // compute phase values from fft output and sum deviations |
448 for (int i = 0;i < frameSize;i++) | 448 for (int i = 0;i < frameSize;i++) |
449 { | 449 { |
450 // calculate phase value | 450 // calculate phase value |
451 phase[i] = atan2(complexOut[i][1],complexOut[i][0]); | 451 phase[i] = atan2 (complexOut[i][1],complexOut[i][0]); |
452 | 452 |
453 // calculate magnitude value | 453 // calculate magnitude value |
454 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2)); | 454 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow(complexOut[i][1],2)); |
455 | 455 |
456 // phase deviation | 456 // phase deviation |
457 phaseDeviation = phase[i] - (2*prevPhase[i]) + prevPhase2[i]; | 457 phaseDeviation = phase[i] - (2 * prevPhase[i]) + prevPhase2[i]; |
458 | 458 |
459 // calculate complex spectral difference for the current spectral bin | 459 // 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)); | 460 csd = sqrt (pow (magSpec[i], 2) + pow (prevMagSpec[i], 2) - 2 * magSpec[i] * prevMagSpec[i] * cos (phaseDeviation)); |
461 | 461 |
462 // add to sum | 462 // add to sum |
463 sum = sum + csd; | 463 sum = sum + csd; |
464 | 464 |
465 // store values for next calculation | 465 // store values for next calculation |
470 | 470 |
471 return sum; | 471 return sum; |
472 } | 472 } |
473 | 473 |
474 //======================================================================= | 474 //======================================================================= |
475 double OnsetDetectionFunction :: complexSpectralDifferenceHWR() | 475 double OnsetDetectionFunction::complexSpectralDifferenceHWR() |
476 { | 476 { |
477 double phaseDeviation; | 477 double phaseDeviation; |
478 double sum; | 478 double sum; |
479 double magnitudeDifference; | 479 double magnitudeDifference; |
480 double csd; | 480 double csd; |
486 | 486 |
487 // compute phase values from fft output and sum deviations | 487 // compute phase values from fft output and sum deviations |
488 for (int i = 0;i < frameSize;i++) | 488 for (int i = 0;i < frameSize;i++) |
489 { | 489 { |
490 // calculate phase value | 490 // calculate phase value |
491 phase[i] = atan2(complexOut[i][1],complexOut[i][0]); | 491 phase[i] = atan2 (complexOut[i][1],complexOut[i][0]); |
492 | 492 |
493 // calculate magnitude value | 493 // calculate magnitude value |
494 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2)); | 494 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow(complexOut[i][1],2)); |
495 | 495 |
496 // phase deviation | 496 // phase deviation |
497 phaseDeviation = phase[i] - (2*prevPhase[i]) + prevPhase2[i]; | 497 phaseDeviation = phase[i] - (2 * prevPhase[i]) + prevPhase2[i]; |
498 | 498 |
499 // calculate magnitude difference (real part of Euclidean distance between complex frames) | 499 // calculate magnitude difference (real part of Euclidean distance between complex frames) |
500 magnitudeDifference = magSpec[i] - prevMagSpec[i]; | 500 magnitudeDifference = magSpec[i] - prevMagSpec[i]; |
501 | 501 |
502 // if we have a positive change in magnitude, then include in sum, otherwise ignore (half-wave rectification) | 502 // if we have a positive change in magnitude, then include in sum, otherwise ignore (half-wave rectification) |
503 if (magnitudeDifference > 0) | 503 if (magnitudeDifference > 0) |
504 { | 504 { |
505 // calculate complex spectral difference for the current spectral bin | 505 // 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)); | 506 csd = sqrt (pow (magSpec[i], 2) + pow (prevMagSpec[i], 2) - 2 * magSpec[i] * prevMagSpec[i] * cos (phaseDeviation)); |
507 | 507 |
508 // add to sum | 508 // add to sum |
509 sum = sum + csd; | 509 sum = sum + csd; |
510 } | 510 } |
511 | 511 |
518 return sum; | 518 return sum; |
519 } | 519 } |
520 | 520 |
521 | 521 |
522 //======================================================================= | 522 //======================================================================= |
523 double OnsetDetectionFunction :: highFrequencyContent() | 523 double OnsetDetectionFunction::highFrequencyContent() |
524 { | 524 { |
525 double sum; | 525 double sum; |
526 | |
527 // perform the FFT | |
528 performFFT(); | |
529 | |
530 sum = 0; // initialise sum to zero | |
531 | |
532 // compute phase values from fft output and sum deviations | |
533 for (int i = 0; i < frameSize; i++) | |
534 { | |
535 // calculate magnitude value | |
536 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow (complexOut[i][1],2)); | |
537 | |
538 | |
539 sum = sum + (magSpec[i] * ((double) (i+1))); | |
540 | |
541 // store values for next calculation | |
542 prevMagSpec[i] = magSpec[i]; | |
543 } | |
544 | |
545 return sum; | |
546 } | |
547 | |
548 //======================================================================= | |
549 double OnsetDetectionFunction::highFrequencySpectralDifference() | |
550 { | |
551 double sum; | |
552 double mag_diff; | |
526 | 553 |
527 // perform the FFT | 554 // perform the FFT |
528 performFFT(); | 555 performFFT(); |
529 | 556 |
530 sum = 0; // initialise sum to zero | 557 sum = 0; // initialise sum to zero |
531 | 558 |
532 // compute phase values from fft output and sum deviations | 559 // compute phase values from fft output and sum deviations |
533 for (int i = 0;i < frameSize;i++) | 560 for (int i = 0;i < frameSize;i++) |
534 { | 561 { |
535 // calculate magnitude value | 562 // calculate magnitude value |
536 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2)); | 563 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow (complexOut[i][1],2)); |
537 | 564 |
538 | 565 // calculate difference |
539 sum = sum + (magSpec[i]*((double) (i+1))); | 566 mag_diff = magSpec[i] - prevMagSpec[i]; |
567 | |
568 if (mag_diff < 0) | |
569 { | |
570 mag_diff = -mag_diff; | |
571 } | |
572 | |
573 sum = sum + (mag_diff * ((double) (i+1))); | |
540 | 574 |
541 // store values for next calculation | 575 // store values for next calculation |
542 prevMagSpec[i] = magSpec[i]; | 576 prevMagSpec[i] = magSpec[i]; |
543 } | 577 } |
544 | 578 |
545 return sum; | 579 return sum; |
546 } | 580 } |
547 | 581 |
548 //======================================================================= | 582 //======================================================================= |
549 double OnsetDetectionFunction :: highFrequencySpectralDifference() | 583 double OnsetDetectionFunction::highFrequencySpectralDifferenceHWR() |
550 { | 584 { |
551 double sum; | 585 double sum; |
552 double mag_diff; | 586 double mag_diff; |
553 | 587 |
554 // perform the FFT | 588 // perform the FFT |
558 | 592 |
559 // compute phase values from fft output and sum deviations | 593 // compute phase values from fft output and sum deviations |
560 for (int i = 0;i < frameSize;i++) | 594 for (int i = 0;i < frameSize;i++) |
561 { | 595 { |
562 // calculate magnitude value | 596 // calculate magnitude value |
563 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2)); | 597 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow (complexOut[i][1],2)); |
564 | 598 |
565 // calculate difference | 599 // calculate difference |
566 mag_diff = magSpec[i] - prevMagSpec[i]; | 600 mag_diff = magSpec[i] - prevMagSpec[i]; |
567 | 601 |
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) | 602 if (mag_diff > 0) |
603 { | 603 { |
604 sum = sum + (mag_diff*((double) (i+1))); | 604 sum = sum + (mag_diff * ((double) (i+1))); |
605 } | 605 } |
606 | 606 |
607 // store values for next calculation | 607 // store values for next calculation |
608 prevMagSpec[i] = magSpec[i]; | 608 prevMagSpec[i] = magSpec[i]; |
609 } | 609 } |
615 //////////////////////////////////////////////////////////////////////////////////////////////// | 615 //////////////////////////////////////////////////////////////////////////////////////////////// |
616 //////////////////////////////////////////////////////////////////////////////////////////////// | 616 //////////////////////////////////////////////////////////////////////////////////////////////// |
617 ////////////////////////////// Methods to Calculate Windows //////////////////////////////////// | 617 ////////////////////////////// Methods to Calculate Windows //////////////////////////////////// |
618 | 618 |
619 //======================================================================= | 619 //======================================================================= |
620 void OnsetDetectionFunction :: calculateHanningWindow() | 620 void OnsetDetectionFunction::calculateHanningWindow() |
621 { | 621 { |
622 double N; // variable to store framesize minus 1 | 622 double N; // variable to store framesize minus 1 |
623 | 623 |
624 N = (double) (frameSize-1); // framesize minus 1 | 624 N = (double) (frameSize-1); // framesize minus 1 |
625 | 625 |
626 // Hanning window calculation | 626 // Hanning window calculation |
627 for (int n = 0;n < frameSize;n++) | 627 for (int n = 0; n < frameSize; n++) |
628 { | 628 { |
629 window[n] = 0.5*(1-cos(2*pi*(n/N))); | 629 window[n] = 0.5 * (1 - cos (2 * pi * (n / N))); |
630 } | 630 } |
631 } | 631 } |
632 | 632 |
633 //======================================================================= | 633 //======================================================================= |
634 void OnsetDetectionFunction :: calclulateHammingWindow() | 634 void OnsetDetectionFunction::calclulateHammingWindow() |
635 { | 635 { |
636 double N; // variable to store framesize minus 1 | 636 double N; // variable to store framesize minus 1 |
637 double n_val; // double version of index 'n' | 637 double n_val; // double version of index 'n' |
638 | 638 |
639 N = (double) (frameSize-1); // framesize minus 1 | 639 N = (double) (frameSize-1); // framesize minus 1 |
640 n_val = 0; | 640 n_val = 0; |
641 | 641 |
642 // Hamming window calculation | 642 // Hamming window calculation |
643 for (int n = 0;n < frameSize;n++) | 643 for (int n = 0;n < frameSize;n++) |
644 { | 644 { |
645 window[n] = 0.54 - (0.46*cos(2*pi*(n_val/N))); | 645 window[n] = 0.54 - (0.46 * cos (2 * pi * (n_val/N))); |
646 n_val = n_val+1; | 646 n_val = n_val+1; |
647 } | 647 } |
648 } | 648 } |
649 | 649 |
650 //======================================================================= | 650 //======================================================================= |
651 void OnsetDetectionFunction :: calculateBlackmanWindow() | 651 void OnsetDetectionFunction::calculateBlackmanWindow() |
652 { | 652 { |
653 double N; // variable to store framesize minus 1 | 653 double N; // variable to store framesize minus 1 |
654 double n_val; // double version of index 'n' | 654 double n_val; // double version of index 'n' |
655 | 655 |
656 N = (double) (frameSize-1); // framesize minus 1 | 656 N = (double) (frameSize-1); // framesize minus 1 |
663 n_val = n_val+1; | 663 n_val = n_val+1; |
664 } | 664 } |
665 } | 665 } |
666 | 666 |
667 //======================================================================= | 667 //======================================================================= |
668 void OnsetDetectionFunction :: calculateTukeyWindow() | 668 void OnsetDetectionFunction::calculateTukeyWindow() |
669 { | 669 { |
670 double N; // variable to store framesize minus 1 | 670 double N; // variable to store framesize minus 1 |
671 double n_val; // double version of index 'n' | 671 double n_val; // double version of index 'n' |
672 double alpha; // alpha [default value = 0.5]; | 672 double alpha; // alpha [default value = 0.5]; |
673 | 673 |
698 } | 698 } |
699 | 699 |
700 } | 700 } |
701 | 701 |
702 //======================================================================= | 702 //======================================================================= |
703 void OnsetDetectionFunction :: calculateRectangularWindow() | 703 void OnsetDetectionFunction::calculateRectangularWindow() |
704 { | 704 { |
705 // Rectangular window calculation | 705 // Rectangular window calculation |
706 for (int n = 0;n < frameSize;n++) | 706 for (int n = 0;n < frameSize;n++) |
707 { | 707 { |
708 window[n] = 1.0; | 708 window[n] = 1.0; |
709 } | 709 } |
710 } | 710 } |
711 | |
712 | |
713 | 711 |
714 //////////////////////////////////////////////////////////////////////////////////////////////// | 712 //////////////////////////////////////////////////////////////////////////////////////////////// |
715 //////////////////////////////////////////////////////////////////////////////////////////////// | 713 //////////////////////////////////////////////////////////////////////////////////////////////// |
716 ///////////////////////////////// Other Handy Methods ////////////////////////////////////////// | 714 ///////////////////////////////// Other Handy Methods ////////////////////////////////////////// |
717 | 715 |
718 //======================================================================= | 716 //======================================================================= |
719 double OnsetDetectionFunction :: princarg(double phaseVal) | 717 double OnsetDetectionFunction::princarg(double phaseVal) |
720 { | 718 { |
721 // if phase value is less than or equal to -pi then add 2*pi | 719 // if phase value is less than or equal to -pi then add 2*pi |
722 while (phaseVal <= (-pi)) | 720 while (phaseVal <= (-pi)) |
723 { | 721 { |
724 phaseVal = phaseVal + (2*pi); | 722 phaseVal = phaseVal + (2 * pi); |
725 } | 723 } |
726 | 724 |
727 // if phase value is larger than pi, then subtract 2*pi | 725 // if phase value is larger than pi, then subtract 2*pi |
728 while (phaseVal > pi) | 726 while (phaseVal > pi) |
729 { | 727 { |
730 phaseVal = phaseVal - (2*pi); | 728 phaseVal = phaseVal - (2 * pi); |
731 } | 729 } |
732 | 730 |
733 return phaseVal; | 731 return phaseVal; |
734 } | 732 } |
735 | |
736 | |
737 | |
738 | |
739 | |
740 | |
741 | |
742 | |
743 | |
744 | |
745 | |
746 | |
747 |