comparison src/BTrack.cpp @ 93:4aa362058011

Added Kiss FFT option
author Adam Stark <adamstark.uk@gmail.com>
date Sat, 18 Jun 2016 09:24:13 +0100
parents a88d887bd281
children 6a4dd7478954
comparison
equal deleted inserted replaced
92:f6708e4c69f1 93:4aa362058011
27 27
28 //======================================================================= 28 //=======================================================================
29 BTrack::BTrack() 29 BTrack::BTrack()
30 : odf (512, 1024, ComplexSpectralDifferenceHWR, HanningWindow) 30 : odf (512, 1024, ComplexSpectralDifferenceHWR, HanningWindow)
31 { 31 {
32 initialise(512, 1024); 32 initialise (512, 1024);
33 } 33 }
34 34
35 //======================================================================= 35 //=======================================================================
36 BTrack::BTrack (int hopSize_) 36 BTrack::BTrack (int hopSize_)
37 : odf(hopSize_, 2*hopSize_, ComplexSpectralDifferenceHWR, HanningWindow) 37 : odf(hopSize_, 2*hopSize_, ComplexSpectralDifferenceHWR, HanningWindow)
38 { 38 {
39 initialise(hopSize_, 2*hopSize_); 39 initialise (hopSize_, 2*hopSize_);
40 } 40 }
41 41
42 //======================================================================= 42 //=======================================================================
43 BTrack::BTrack (int hopSize_, int frameSize_) 43 BTrack::BTrack (int hopSize_, int frameSize_)
44 : odf (hopSize_, frameSize_, ComplexSpectralDifferenceHWR, HanningWindow) 44 : odf (hopSize_, frameSize_, ComplexSpectralDifferenceHWR, HanningWindow)
47 } 47 }
48 48
49 //======================================================================= 49 //=======================================================================
50 BTrack::~BTrack() 50 BTrack::~BTrack()
51 { 51 {
52 #ifdef USE_FFTW
52 // destroy fft plan 53 // destroy fft plan
53 fftw_destroy_plan (acfForwardFFT); 54 fftw_destroy_plan (acfForwardFFT);
54 fftw_destroy_plan (acfBackwardFFT); 55 fftw_destroy_plan (acfBackwardFFT);
55 fftw_free (complexIn); 56 fftw_free (complexIn);
56 fftw_free (complexOut); 57 fftw_free (complexOut);
58 #endif
59
60 #ifdef USE_KISS_FFT
61 free (cfgForwards);
62 free (cfgBackwards);
63 delete [] fftIn;
64 delete [] fftOut;
65 #endif
57 } 66 }
58 67
59 //======================================================================= 68 //=======================================================================
60 double BTrack::getBeatTimeInSeconds (long frameNumber, int hopSize, int fs) 69 double BTrack::getBeatTimeInSeconds (long frameNumber, int hopSize, int fs)
61 { 70 {
135 144
136 145
137 // Set up FFT for calculating the auto-correlation function 146 // Set up FFT for calculating the auto-correlation function
138 FFTLengthForACFCalculation = 1024; 147 FFTLengthForACFCalculation = 1024;
139 148
149 #ifdef USE_FFTW
140 complexIn = (fftw_complex*) fftw_malloc (sizeof(fftw_complex) * FFTLengthForACFCalculation); // complex array to hold fft data 150 complexIn = (fftw_complex*) fftw_malloc (sizeof(fftw_complex) * FFTLengthForACFCalculation); // complex array to hold fft data
141 complexOut = (fftw_complex*) fftw_malloc (sizeof(fftw_complex) * FFTLengthForACFCalculation); // complex array to hold fft data 151 complexOut = (fftw_complex*) fftw_malloc (sizeof(fftw_complex) * FFTLengthForACFCalculation); // complex array to hold fft data
142 152
143 acfForwardFFT = fftw_plan_dft_1d (FFTLengthForACFCalculation, complexIn, complexOut, FFTW_FORWARD, FFTW_ESTIMATE); // FFT plan initialisation 153 acfForwardFFT = fftw_plan_dft_1d (FFTLengthForACFCalculation, complexIn, complexOut, FFTW_FORWARD, FFTW_ESTIMATE); // FFT plan initialisation
144 acfBackwardFFT = fftw_plan_dft_1d (FFTLengthForACFCalculation, complexOut, complexIn, FFTW_BACKWARD, FFTW_ESTIMATE); // FFT plan initialisation 154 acfBackwardFFT = fftw_plan_dft_1d (FFTLengthForACFCalculation, complexOut, complexIn, FFTW_BACKWARD, FFTW_ESTIMATE); // FFT plan initialisation
155 #endif
156
157 #ifdef USE_KISS_FFT
158 fftIn = new kiss_fft_cpx[FFTLengthForACFCalculation];
159 fftOut = new kiss_fft_cpx[FFTLengthForACFCalculation];
160 cfgForwards = kiss_fft_alloc (FFTLengthForACFCalculation, 0, 0, 0);
161 cfgBackwards = kiss_fft_alloc (FFTLengthForACFCalculation, 1, 0, 0);
162 #endif
145 } 163 }
146 164
147 //======================================================================= 165 //=======================================================================
148 void BTrack::setHopSize (int hopSize_) 166 void BTrack::setHopSize (int hopSize_)
149 { 167 {
475 estimatedTempo = 60.0/((((double) hopSize) / 44100.0) * beatPeriod); 493 estimatedTempo = 60.0/((((double) hopSize) / 44100.0) * beatPeriod);
476 } 494 }
477 } 495 }
478 496
479 //======================================================================= 497 //=======================================================================
480 void BTrack::adaptiveThreshold (double*x, int N) 498 void BTrack::adaptiveThreshold (double* x, int N)
481 { 499 {
482 int i = 0; 500 int i = 0;
483 int k,t = 0; 501 int k,t = 0;
484 double x_thresh[N]; 502 double x_thresh[N];
485 503
544 //======================================================================= 562 //=======================================================================
545 void BTrack::calculateBalancedACF (double* onsetDetectionFunction) 563 void BTrack::calculateBalancedACF (double* onsetDetectionFunction)
546 { 564 {
547 int onsetDetectionFunctionLength = 512; 565 int onsetDetectionFunctionLength = 512;
548 566
567 #ifdef USE_FFTW
549 // copy into complex array and zero pad 568 // copy into complex array and zero pad
550 for (int i = 0;i < FFTLengthForACFCalculation;i++) 569 for (int i = 0;i < FFTLengthForACFCalculation;i++)
551 { 570 {
552 if (i < onsetDetectionFunctionLength) 571 if (i < onsetDetectionFunctionLength)
553 { 572 {
572 } 591 }
573 592
574 // perform the ifft 593 // perform the ifft
575 fftw_execute (acfBackwardFFT); 594 fftw_execute (acfBackwardFFT);
576 595
596 #endif
597
598 #ifdef USE_KISS_FFT
599 // copy into complex array and zero pad
600 for (int i = 0;i < FFTLengthForACFCalculation;i++)
601 {
602 if (i < onsetDetectionFunctionLength)
603 {
604 fftIn[i].r = onsetDetectionFunction[i];
605 fftIn[i].i = 0.0;
606 }
607 else
608 {
609 fftIn[i].r = 0.0;
610 fftIn[i].i = 0.0;
611 }
612 }
613
614 // execute kiss fft
615 kiss_fft (cfgForwards, fftIn, fftOut);
616
617 // multiply by complex conjugate
618 for (int i = 0;i < FFTLengthForACFCalculation;i++)
619 {
620 fftOut[i].r = fftOut[i].r * fftOut[i].r + fftOut[i].i * fftOut[i].i;
621 fftOut[i].i = 0.0;
622 }
623
624 // perform the ifft
625 kiss_fft (cfgBackwards, fftOut, fftIn);
626
627 #endif
577 628
578 double lag = 512; 629 double lag = 512;
579 630
580 for (int i = 0; i < 512; i++) 631 for (int i = 0; i < 512; i++)
581 { 632 {
633 #ifdef USE_FFTW
582 // calculate absolute value of result 634 // calculate absolute value of result
583 double absValue = sqrt (complexIn[i][0]*complexIn[i][0] + complexIn[i][1]*complexIn[i][1]); 635 double absValue = sqrt (complexIn[i][0]*complexIn[i][0] + complexIn[i][1]*complexIn[i][1]);
636 #endif
584 637
638 #ifdef USE_KISS_FFT
639 // calculate absolute value of result
640 double absValue = sqrt (fftIn[i].r * fftIn[i].r + fftIn[i].i * fftIn[i].i);
641 #endif
585 // divide by inverse lad to deal with scale bias towards small lags 642 // divide by inverse lad to deal with scale bias towards small lags
586 acf[i] = absValue / lag; 643 acf[i] = absValue / lag;
587 644
588 // this division by 1024 is technically unnecessary but it ensures the algorithm produces 645 // this division by 1024 is technically unnecessary but it ensures the algorithm produces
589 // exactly the same ACF output as the old time domain implementation. The time difference is 646 // exactly the same ACF output as the old time domain implementation. The time difference is
617 return 0; 674 return 0;
618 } 675 }
619 } 676 }
620 677
621 //======================================================================= 678 //=======================================================================
622 void BTrack::normaliseArray(double* array, int N) 679 void BTrack::normaliseArray (double* array, int N)
623 { 680 {
624 double sum = 0; 681 double sum = 0;
625 682
626 for (int i = 0; i < N; i++) 683 for (int i = 0; i < N; i++)
627 { 684 {
652 709
653 double w1[winsize]; 710 double w1[winsize];
654 double v = -2*beatPeriod; 711 double v = -2*beatPeriod;
655 double wcumscore; 712 double wcumscore;
656 713
657
658 // create window 714 // create window
659 for (int i = 0; i < winsize; i++) 715 for (int i = 0; i < winsize; i++)
660 { 716 {
661 w1[i] = exp((-1*pow (tightness * log (-v / beatPeriod), 2)) / 2); 717 w1[i] = exp((-1 * pow (tightness * log (-v / beatPeriod), 2)) / 2);
662 v = v+1; 718 v = v+1;
663 } 719 }
664 720
665 // calculate new cumulative score value 721 // calculate new cumulative score value
666 max = 0; 722 max = 0;
674 max = wcumscore; 730 max = wcumscore;
675 } 731 }
676 n++; 732 n++;
677 } 733 }
678 734
679 735 latestCumulativeScoreValue = ((1 - alpha) * odfSample) + (alpha * max);
680 latestCumulativeScoreValue = ((1-alpha)*odfSample) + (alpha*max);
681 736
682 cumulativeScore.addSampleToEnd (latestCumulativeScoreValue); 737 cumulativeScore.addSampleToEnd (latestCumulativeScoreValue);
683 } 738 }
684 739
685 //======================================================================= 740 //=======================================================================
686 void BTrack::predictBeat() 741 void BTrack::predictBeat()
687 { 742 {
688 int windowSize = (int) beatPeriod; 743 int windowSize = (int) beatPeriod;
689 double futureCumulativeScore[onsetDFBufferSize + windowSize]; 744 double futureCumulativeScore[onsetDFBufferSize + windowSize];
690 double w2[windowSize]; 745 double w2[windowSize];
746
691 // copy cumscore to first part of fcumscore 747 // copy cumscore to first part of fcumscore
692 for (int i = 0;i < onsetDFBufferSize;i++) 748 for (int i = 0;i < onsetDFBufferSize;i++)
693 { 749 {
694 futureCumulativeScore[i] = cumulativeScore[i]; 750 futureCumulativeScore[i] = cumulativeScore[i];
695 } 751 }
712 for (int i = 0;i < pastwinsize;i++) 768 for (int i = 0;i < pastwinsize;i++)
713 { 769 {
714 w1[i] = exp((-1*pow(tightness*log(-v/beatPeriod),2))/2); 770 w1[i] = exp((-1*pow(tightness*log(-v/beatPeriod),2))/2);
715 v = v+1; 771 v = v+1;
716 } 772 }
717
718
719 773
720 // calculate future cumulative score 774 // calculate future cumulative score
721 double max; 775 double max;
722 int n; 776 int n;
723 double wcumscore; 777 double wcumscore;
740 } 794 }
741 795
742 futureCumulativeScore[i] = max; 796 futureCumulativeScore[i] = max;
743 } 797 }
744 798
745
746 // predict beat 799 // predict beat
747 max = 0; 800 max = 0;
748 n = 0; 801 n = 0;
749 802
750 for (int i = onsetDFBufferSize; i < (onsetDFBufferSize + windowSize); i++) 803 for (int i = onsetDFBufferSize; i < (onsetDFBufferSize + windowSize); i++)