Mercurial > hg > btrack
comparison src/OnsetDetectionFunction.cpp @ 86:5eeabb24d677
Fixed implementation issue in complex spectral difference (and its HWR cousin) - thanks to @zbanks for pointing this out. Also updated README for new version
author | Adam Stark <adamstark.uk@gmail.com> |
---|---|
date | Sun, 10 Jan 2016 11:36:14 +0000 |
parents | b387d8327729 |
children | f6708e4c69f1 |
comparison
equal
deleted
inserted
replaced
85:db22205f8ffa | 86:5eeabb24d677 |
---|---|
433 } | 433 } |
434 | 434 |
435 //======================================================================= | 435 //======================================================================= |
436 double OnsetDetectionFunction :: complexSpectralDifference() | 436 double OnsetDetectionFunction :: complexSpectralDifference() |
437 { | 437 { |
438 double dev,pdev; | 438 double phaseDeviation; |
439 double sum; | 439 double sum; |
440 double mag_diff,phase_diff; | 440 double csd; |
441 double value; | |
442 | 441 |
443 // perform the FFT | 442 // perform the FFT |
444 performFFT(); | 443 performFFT(); |
445 | 444 |
446 sum = 0; // initialise sum to zero | 445 sum = 0; // initialise sum to zero |
452 phase[i] = atan2(complexOut[i][1],complexOut[i][0]); | 451 phase[i] = atan2(complexOut[i][1],complexOut[i][0]); |
453 | 452 |
454 // calculate magnitude value | 453 // calculate magnitude value |
455 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)); |
456 | 455 |
457 | |
458 // phase deviation | 456 // phase deviation |
459 dev = phase[i] - (2*prevPhase[i]) + prevPhase2[i]; | 457 phaseDeviation = phase[i] - (2*prevPhase[i]) + prevPhase2[i]; |
460 | 458 |
461 // wrap into [-pi,pi] range | 459 // calculate complex spectral difference for the current spectral bin |
462 pdev = princarg(dev); | 460 csd = sqrt(pow(magSpec[i], 2) + pow(prevMagSpec[i], 2) - 2 * magSpec[i] * prevMagSpec[i] * cos(phaseDeviation)); |
463 | |
464 | |
465 // calculate magnitude difference (real part of Euclidean distance between complex frames) | |
466 mag_diff = magSpec[i] - prevMagSpec[i]; | |
467 | |
468 // calculate phase difference (imaginary part of Euclidean distance between complex frames) | |
469 phase_diff = -magSpec[i]*sin(pdev); | |
470 | |
471 | |
472 | |
473 // square real and imaginary parts, sum and take square root | |
474 value = sqrt(pow(mag_diff,2) + pow(phase_diff,2)); | |
475 | |
476 | 461 |
477 // add to sum | 462 // add to sum |
478 sum = sum + value; | 463 sum = sum + csd; |
479 | |
480 | 464 |
481 // store values for next calculation | 465 // store values for next calculation |
482 prevPhase2[i] = prevPhase[i]; | 466 prevPhase2[i] = prevPhase[i]; |
483 prevPhase[i] = phase[i]; | 467 prevPhase[i] = phase[i]; |
484 prevMagSpec[i] = magSpec[i]; | 468 prevMagSpec[i] = magSpec[i]; |
488 } | 472 } |
489 | 473 |
490 //======================================================================= | 474 //======================================================================= |
491 double OnsetDetectionFunction :: complexSpectralDifferenceHWR() | 475 double OnsetDetectionFunction :: complexSpectralDifferenceHWR() |
492 { | 476 { |
493 double dev,pdev; | 477 double phaseDeviation; |
494 double sum; | 478 double sum; |
495 double mag_diff,phase_diff; | 479 double magnitudeDifference; |
496 double value; | 480 double csd; |
497 | 481 |
498 // perform the FFT | 482 // perform the FFT |
499 performFFT(); | 483 performFFT(); |
500 | 484 |
501 sum = 0; // initialise sum to zero | 485 sum = 0; // initialise sum to zero |
507 phase[i] = atan2(complexOut[i][1],complexOut[i][0]); | 491 phase[i] = atan2(complexOut[i][1],complexOut[i][0]); |
508 | 492 |
509 // calculate magnitude value | 493 // calculate magnitude value |
510 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)); |
511 | 495 |
512 | 496 // phase deviation |
513 // phase deviation | 497 phaseDeviation = phase[i] - (2*prevPhase[i]) + prevPhase2[i]; |
514 dev = phase[i] - (2*prevPhase[i]) + prevPhase2[i]; | 498 |
515 | 499 // calculate magnitude difference (real part of Euclidean distance between complex frames) |
516 // wrap into [-pi,pi] range | 500 magnitudeDifference = magSpec[i] - prevMagSpec[i]; |
517 pdev = princarg(dev); | 501 |
518 | 502 // if we have a positive change in magnitude, then include in sum, otherwise ignore (half-wave rectification) |
519 | 503 if (magnitudeDifference > 0) |
520 // calculate magnitude difference (real part of Euclidean distance between complex frames) | 504 { |
521 mag_diff = magSpec[i] - prevMagSpec[i]; | 505 // calculate complex spectral difference for the current spectral bin |
522 | 506 csd = sqrt(pow(magSpec[i], 2) + pow(prevMagSpec[i], 2) - 2 * magSpec[i] * prevMagSpec[i] * cos(phaseDeviation)); |
523 // if we have a positive change in magnitude, then include in sum, otherwise ignore (half-wave rectification) | 507 |
524 if (mag_diff > 0) | 508 // add to sum |
525 { | 509 sum = sum + csd; |
526 // calculate phase difference (imaginary part of Euclidean distance between complex frames) | 510 } |
527 phase_diff = -magSpec[i]*sin(pdev); | 511 |
528 | |
529 // square real and imaginary parts, sum and take square root | |
530 value = sqrt(pow(mag_diff,2) + pow(phase_diff,2)); | |
531 | |
532 // add to sum | |
533 sum = sum + value; | |
534 } | |
535 | |
536 // store values for next calculation | 512 // store values for next calculation |
537 prevPhase2[i] = prevPhase[i]; | 513 prevPhase2[i] = prevPhase[i]; |
538 prevPhase[i] = phase[i]; | 514 prevPhase[i] = phase[i]; |
539 prevMagSpec[i] = magSpec[i]; | 515 prevMagSpec[i] = magSpec[i]; |
540 } | 516 } |