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 }