comparison src/OnsetDetectionFunction.cpp @ 117:ca2d83d29814 tip master

Merge branch 'release/1.0.5'
author Adam Stark <adamstark.uk@gmail.com>
date Fri, 18 Aug 2023 20:07:33 +0200
parents 54c657d621dd
children
comparison
equal deleted inserted replaced
96:c58f01834337 117:ca2d83d29814
21 21
22 #include <math.h> 22 #include <math.h>
23 #include "OnsetDetectionFunction.h" 23 #include "OnsetDetectionFunction.h"
24 24
25 //======================================================================= 25 //=======================================================================
26 OnsetDetectionFunction::OnsetDetectionFunction (int hopSize_,int frameSize_) 26 OnsetDetectionFunction::OnsetDetectionFunction (int hopSize_, int frameSize_)
27 : 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
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_) 40 OnsetDetectionFunction::OnsetDetectionFunction (int hopSize_, int frameSize_, int onsetDetectionFunctionType_, int windowType_)
41 : onsetDetectionFunctionType (ComplexSpectralDifferenceHWR), windowType (HanningWindow) 41 : onsetDetectionFunctionType (ComplexSpectralDifferenceHWR), windowType (HanningWindow)
42 { 42 {
43 // indicate that we have not initialised yet 43 // indicate that we have not initialised yet
44 initialised = false; 44 initialised = false;
45 45
67 // 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
68 initialise (hopSize_, frameSize_, onsetDetectionFunctionType, windowType); 68 initialise (hopSize_, frameSize_, onsetDetectionFunctionType, windowType);
69 } 69 }
70 70
71 //======================================================================= 71 //=======================================================================
72 void OnsetDetectionFunction::initialise(int hopSize_,int frameSize_,int onsetDetectionFunctionType_,int windowType_) 72 void OnsetDetectionFunction::initialise (int hopSize_, int frameSize_, int onsetDetectionFunctionType_, int windowType_)
73 { 73 {
74 hopSize = hopSize_; // set hopsize 74 hopSize = hopSize_; // set hopsize
75 frameSize = frameSize_; // set framesize 75 frameSize = frameSize_; // set framesize
76 76
77 onsetDetectionFunctionType = onsetDetectionFunctionType_; // set detection function type 77 onsetDetectionFunctionType = onsetDetectionFunctionType_; // set detection function type
138 #endif 138 #endif
139 139
140 #ifdef USE_KISS_FFT 140 #ifdef USE_KISS_FFT
141 complexOut.resize (frameSize); 141 complexOut.resize (frameSize);
142 142
143 for (int i = 0; i < frameSize;i++) 143 for (int i = 0; i < frameSize; i++)
144 { 144 {
145 complexOut[i].resize(2); 145 complexOut[i].resize(2);
146 } 146 }
147 147
148 fftIn = new kiss_fft_cpx[frameSize]; 148 fftIn = new kiss_fft_cpx[frameSize];
179 double OnsetDetectionFunction::calculateOnsetDetectionFunctionSample (double* buffer) 179 double OnsetDetectionFunction::calculateOnsetDetectionFunctionSample (double* buffer)
180 { 180 {
181 double odfSample; 181 double odfSample;
182 182
183 // shift audio samples back in frame by hop size 183 // shift audio samples back in frame by hop size
184 for (int i = 0; i < (frameSize-hopSize);i++) 184 std::rotate (frame.begin(), frame.begin() + hopSize, frame.end());
185 {
186 frame[i] = frame[i+hopSize];
187 }
188 185
189 // add new samples to frame from input buffer 186 // add new samples to frame from input buffer
190 int j = 0; 187 int j = 0;
191 for (int i = (frameSize-hopSize);i < frameSize;i++) 188 for (int i = (frameSize - hopSize); i < frameSize; i++)
192 { 189 {
193 frame[i] = buffer[j]; 190 frame[i] = buffer[j];
194 j++; 191 j++;
195 } 192 }
196 193
267 264
268 265
269 //======================================================================= 266 //=======================================================================
270 void OnsetDetectionFunction::performFFT() 267 void OnsetDetectionFunction::performFFT()
271 { 268 {
272 int fsize2 = (frameSize/2); 269 int fsize2 = (frameSize / 2);
273 270
274 #ifdef USE_FFTW 271 #ifdef USE_FFTW
275 // window frame and copy to complex array, swapping the first and second half of the signal 272 // window frame and copy to complex array, swapping the first and second half of the signal
276 for (int i = 0;i < fsize2;i++) 273 for (int i = 0; i < fsize2; i++)
277 { 274 {
278 complexIn[i][0] = frame[i + fsize2] * window[i + fsize2]; 275 complexIn[i][0] = frame[i + fsize2] * window[i + fsize2];
279 complexIn[i][1] = 0.0; 276 complexIn[i][1] = 0.0;
280 complexIn[i+fsize2][0] = frame[i] * window[i]; 277 complexIn[i+fsize2][0] = frame[i] * window[i];
281 complexIn[i+fsize2][1] = 0.0; 278 complexIn[i+fsize2][1] = 0.0;
316 double sum; 313 double sum;
317 314
318 sum = 0; // initialise sum 315 sum = 0; // initialise sum
319 316
320 // sum the squares of the samples 317 // sum the squares of the samples
321 for (int i = 0;i < frameSize;i++) 318 for (int i = 0; i < frameSize; i++)
322 { 319 {
323 sum = sum + (frame[i] * frame[i]); 320 sum = sum + (frame[i] * frame[i]);
324 } 321 }
325 322
326 return sum; // return sum 323 return sum; // return sum
361 double sum; 358 double sum;
362 359
363 // perform the FFT 360 // perform the FFT
364 performFFT(); 361 performFFT();
365 362
366 // compute first (N/2)+1 mag values 363 // compute first (N / 2) + 1 mag values
367 for (int i = 0;i < (frameSize/2)+1;i++) 364 for (int i = 0; i < (frameSize / 2) + 1; i++)
368 { 365 {
369 magSpec[i] = sqrt (pow (complexOut[i][0], 2) + pow (complexOut[i][1], 2)); 366 magSpec[i] = sqrt (pow (complexOut[i][0], 2) + pow (complexOut[i][1], 2));
370 } 367 }
371 // mag spec symmetric above (N/2)+1 so copy previous values 368 // mag spec symmetric above (N / 2) + 1 so copy previous values
372 for (int i = (frameSize/2)+1; i < frameSize; i++) 369 for (int i = (frameSize / 2) + 1; i < frameSize; i++)
373 { 370 {
374 magSpec[i] = magSpec[frameSize-i]; 371 magSpec[i] = magSpec[frameSize - i];
375 } 372 }
376 373
377 sum = 0; // initialise sum to zero 374 sum = 0; // initialise sum to zero
378 375
379 for (int i = 0; i < frameSize; i++) 376 for (int i = 0; i < frameSize; i++)
382 diff = magSpec[i] - prevMagSpec[i]; 379 diff = magSpec[i] - prevMagSpec[i];
383 380
384 // ensure all difference values are positive 381 // ensure all difference values are positive
385 if (diff < 0) 382 if (diff < 0)
386 { 383 {
387 diff = diff*-1; 384 diff = diff * -1;
388 } 385 }
389 386
390 // add difference to sum 387 // add difference to sum
391 sum = sum + diff; 388 sum = sum + diff;
392 389
404 double sum; 401 double sum;
405 402
406 // perform the FFT 403 // perform the FFT
407 performFFT(); 404 performFFT();
408 405
409 // compute first (N/2)+1 mag values 406 // compute first (N / 2) + 1 mag values
410 for (int i = 0;i < (frameSize/2) + 1; i++) 407 for (int i = 0; i < (frameSize / 2) + 1; i++)
411 { 408 {
412 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow (complexOut[i][1],2)); 409 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow (complexOut[i][1],2));
413 } 410 }
414 // mag spec symmetric above (N/2)+1 so copy previous values 411 // mag spec symmetric above (N / 2) + 1 so copy previous values
415 for (int i = (frameSize/2)+1;i < frameSize;i++) 412 for (int i = (frameSize / 2) + 1; i < frameSize; i++)
416 { 413 {
417 magSpec[i] = magSpec[frameSize-i]; 414 magSpec[i] = magSpec[frameSize - i];
418 } 415 }
419 416
420 sum = 0; // initialise sum to zero 417 sum = 0; // initialise sum to zero
421 418
422 for (int i = 0;i < frameSize;i++) 419 for (int i = 0; i < frameSize; i++)
423 { 420 {
424 // calculate difference 421 // calculate difference
425 diff = magSpec[i] - prevMagSpec[i]; 422 diff = magSpec[i] - prevMagSpec[i];
426 423
427 // only add up positive differences 424 // only add up positive differences
449 performFFT(); 446 performFFT();
450 447
451 sum = 0; // initialise sum to zero 448 sum = 0; // initialise sum to zero
452 449
453 // compute phase values from fft output and sum deviations 450 // compute phase values from fft output and sum deviations
454 for (int i = 0;i < frameSize;i++) 451 for (int i = 0; i < frameSize; i++)
455 { 452 {
456 // calculate phase value 453 // calculate phase value
457 phase[i] = atan2 (complexOut[i][1], complexOut[i][0]); 454 phase[i] = atan2 (complexOut[i][1], complexOut[i][0]);
458 455
459 // calculate magnitude value 456 // calculate magnitude value
461 458
462 459
463 // if bin is not just a low energy bin then examine phase deviation 460 // if bin is not just a low energy bin then examine phase deviation
464 if (magSpec[i] > 0.1) 461 if (magSpec[i] > 0.1)
465 { 462 {
466 dev = phase[i] - (2*prevPhase[i]) + prevPhase2[i]; // phase deviation 463 dev = phase[i] - (2 * prevPhase[i]) + prevPhase2[i]; // phase deviation
467 pdev = princarg (dev); // wrap into [-pi,pi] range 464 pdev = princarg (dev); // wrap into [-pi,pi] range
468 465
469 // make all values positive 466 // make all values positive
470 if (pdev < 0) 467 if (pdev < 0)
471 { 468 {
472 pdev = pdev*-1; 469 pdev = pdev * -1;
473 } 470 }
474 471
475 // add to sum 472 // add to sum
476 sum = sum + pdev; 473 sum = sum + pdev;
477 } 474 }
495 performFFT(); 492 performFFT();
496 493
497 sum = 0; // initialise sum to zero 494 sum = 0; // initialise sum to zero
498 495
499 // compute phase values from fft output and sum deviations 496 // compute phase values from fft output and sum deviations
500 for (int i = 0;i < frameSize;i++) 497 for (int i = 0; i < frameSize; i++)
501 { 498 {
502 // calculate phase value 499 // calculate phase value
503 phase[i] = atan2 (complexOut[i][1], complexOut[i][0]); 500 phase[i] = atan2 (complexOut[i][1], complexOut[i][0]);
504 501
505 // calculate magnitude value 502 // calculate magnitude value
535 performFFT(); 532 performFFT();
536 533
537 sum = 0; // initialise sum to zero 534 sum = 0; // initialise sum to zero
538 535
539 // compute phase values from fft output and sum deviations 536 // compute phase values from fft output and sum deviations
540 for (int i = 0;i < frameSize;i++) 537 for (int i = 0; i < frameSize; i++)
541 { 538 {
542 // calculate phase value 539 // calculate phase value
543 phase[i] = atan2 (complexOut[i][1], complexOut[i][0]); 540 phase[i] = atan2 (complexOut[i][1], complexOut[i][0]);
544 541
545 // calculate magnitude value 542 // calculate magnitude value
586 { 583 {
587 // calculate magnitude value 584 // calculate magnitude value
588 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow (complexOut[i][1],2)); 585 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow (complexOut[i][1],2));
589 586
590 587
591 sum = sum + (magSpec[i] * ((double) (i+1))); 588 sum = sum + (magSpec[i] * ((double) (i + 1)));
592 589
593 // store values for next calculation 590 // store values for next calculation
594 prevMagSpec[i] = magSpec[i]; 591 prevMagSpec[i] = magSpec[i];
595 } 592 }
596 593
607 performFFT(); 604 performFFT();
608 605
609 sum = 0; // initialise sum to zero 606 sum = 0; // initialise sum to zero
610 607
611 // compute phase values from fft output and sum deviations 608 // compute phase values from fft output and sum deviations
612 for (int i = 0;i < frameSize;i++) 609 for (int i = 0; i < frameSize; i++)
613 { 610 {
614 // calculate magnitude value 611 // calculate magnitude value
615 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow (complexOut[i][1],2)); 612 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow (complexOut[i][1],2));
616 613
617 // calculate difference 614 // calculate difference
620 if (mag_diff < 0) 617 if (mag_diff < 0)
621 { 618 {
622 mag_diff = -mag_diff; 619 mag_diff = -mag_diff;
623 } 620 }
624 621
625 sum = sum + (mag_diff * ((double) (i+1))); 622 sum = sum + (mag_diff * ((double) (i + 1)));
626 623
627 // store values for next calculation 624 // store values for next calculation
628 prevMagSpec[i] = magSpec[i]; 625 prevMagSpec[i] = magSpec[i];
629 } 626 }
630 627
641 performFFT(); 638 performFFT();
642 639
643 sum = 0; // initialise sum to zero 640 sum = 0; // initialise sum to zero
644 641
645 // compute phase values from fft output and sum deviations 642 // compute phase values from fft output and sum deviations
646 for (int i = 0;i < frameSize;i++) 643 for (int i = 0; i < frameSize; i++)
647 { 644 {
648 // calculate magnitude value 645 // calculate magnitude value
649 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow (complexOut[i][1],2)); 646 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow (complexOut[i][1],2));
650 647
651 // calculate difference 648 // calculate difference
652 mag_diff = magSpec[i] - prevMagSpec[i]; 649 mag_diff = magSpec[i] - prevMagSpec[i];
653 650
654 if (mag_diff > 0) 651 if (mag_diff > 0)
655 { 652 {
656 sum = sum + (mag_diff * ((double) (i+1))); 653 sum = sum + (mag_diff * ((double) (i + 1)));
657 } 654 }
658 655
659 // store values for next calculation 656 // store values for next calculation
660 prevMagSpec[i] = magSpec[i]; 657 prevMagSpec[i] = magSpec[i];
661 } 658 }
671 //======================================================================= 668 //=======================================================================
672 void OnsetDetectionFunction::calculateHanningWindow() 669 void OnsetDetectionFunction::calculateHanningWindow()
673 { 670 {
674 double N; // variable to store framesize minus 1 671 double N; // variable to store framesize minus 1
675 672
676 N = (double) (frameSize-1); // framesize minus 1 673 N = (double) (frameSize - 1); // framesize minus 1
677 674
678 // Hanning window calculation 675 // Hanning window calculation
679 for (int n = 0; n < frameSize; n++) 676 for (int n = 0; n < frameSize; n++)
680 { 677 {
681 window[n] = 0.5 * (1 - cos (2 * pi * (n / N))); 678 window[n] = 0.5 * (1 - cos (2 * pi * (n / N)));
686 void OnsetDetectionFunction::calclulateHammingWindow() 683 void OnsetDetectionFunction::calclulateHammingWindow()
687 { 684 {
688 double N; // variable to store framesize minus 1 685 double N; // variable to store framesize minus 1
689 double n_val; // double version of index 'n' 686 double n_val; // double version of index 'n'
690 687
691 N = (double) (frameSize-1); // framesize minus 1 688 N = (double) (frameSize - 1); // framesize minus 1
692 n_val = 0; 689 n_val = 0;
693 690
694 // Hamming window calculation 691 // Hamming window calculation
695 for (int n = 0;n < frameSize;n++) 692 for (int n = 0; n < frameSize; n++)
696 { 693 {
697 window[n] = 0.54 - (0.46 * cos (2 * pi * (n_val/N))); 694 window[n] = 0.54 - (0.46 * cos (2 * pi * (n_val / N)));
698 n_val = n_val+1; 695 n_val = n_val+1;
699 } 696 }
700 } 697 }
701 698
702 //======================================================================= 699 //=======================================================================
703 void OnsetDetectionFunction::calculateBlackmanWindow() 700 void OnsetDetectionFunction::calculateBlackmanWindow()
704 { 701 {
705 double N; // variable to store framesize minus 1 702 double N; // variable to store framesize minus 1
706 double n_val; // double version of index 'n' 703 double n_val; // double version of index 'n'
707 704
708 N = (double) (frameSize-1); // framesize minus 1 705 N = (double) (frameSize - 1); // framesize minus 1
709 n_val = 0; 706 n_val = 0;
710 707
711 // Blackman window calculation 708 // Blackman window calculation
712 for (int n = 0;n < frameSize;n++) 709 for (int n = 0; n < frameSize; n++)
713 { 710 {
714 window[n] = 0.42 - (0.5*cos(2*pi*(n_val/N))) + (0.08*cos(4*pi*(n_val/N))); 711 window[n] = 0.42 - (0.5 * cos (2 * pi * (n_val / N))) + (0.08 * cos (4 * pi * (n_val / N)));
715 n_val = n_val+1; 712 n_val = n_val + 1;
716 } 713 }
717 } 714 }
718 715
719 //======================================================================= 716 //=======================================================================
720 void OnsetDetectionFunction::calculateTukeyWindow() 717 void OnsetDetectionFunction::calculateTukeyWindow()
723 double n_val; // double version of index 'n' 720 double n_val; // double version of index 'n'
724 double alpha; // alpha [default value = 0.5]; 721 double alpha; // alpha [default value = 0.5];
725 722
726 alpha = 0.5; 723 alpha = 0.5;
727 724
728 N = (double) (frameSize-1); // framesize minus 1 725 N = (double) (frameSize - 1); // framesize minus 1
729 726
730 // Tukey window calculation 727 // Tukey window calculation
731 728
732 n_val = (double) (-1*((frameSize/2)))+1; 729 n_val = (double) (-1 * ((frameSize / 2))) + 1;
733 730
734 for (int n = 0;n < frameSize;n++) // left taper 731 for (int n = 0; n < frameSize; n++) // left taper
735 { 732 {
736 if ((n_val >= 0) && (n_val <= (alpha*(N/2)))) 733 if ((n_val >= 0) && (n_val <= (alpha * (N / 2))))
737 { 734 {
738 window[n] = 1.0; 735 window[n] = 1.0;
739 } 736 }
740 else if ((n_val <= 0) && (n_val >= (-1*alpha*(N/2)))) 737 else if ((n_val <= 0) && (n_val >= (-1 * alpha * (N / 2))))
741 { 738 {
742 window[n] = 1.0; 739 window[n] = 1.0;
743 } 740 }
744 else 741 else
745 { 742 {
746 window[n] = 0.5*(1+cos(pi*(((2*n_val)/(alpha*N))-1))); 743 window[n] = 0.5 * (1 + cos (pi * (((2 * n_val) / (alpha * N)) - 1)));
747 } 744 }
748 745
749 n_val = n_val+1; 746 n_val = n_val + 1;
750 } 747 }
751 748
752 } 749 }
753 750
754 //======================================================================= 751 //=======================================================================
755 void OnsetDetectionFunction::calculateRectangularWindow() 752 void OnsetDetectionFunction::calculateRectangularWindow()
756 { 753 {
757 // Rectangular window calculation 754 // Rectangular window calculation
758 for (int n = 0;n < frameSize;n++) 755 for (int n = 0; n < frameSize; n++)
759 { 756 {
760 window[n] = 1.0; 757 window[n] = 1.0;
761 } 758 }
762 } 759 }
763 760