Mercurial > hg > btrack
diff src/BTrack.cpp @ 97:6a4dd7478954
Replaced C-style arrays with std vectors and modernised some code
author | Adam Stark <adamstark.uk@gmail.com> |
---|---|
date | Fri, 11 Aug 2017 18:18:33 +0100 |
parents | 4aa362058011 |
children | 3b24b01fbe15 |
line wrap: on
line diff
--- a/src/BTrack.cpp Sat Jun 18 10:49:26 2016 +0100 +++ b/src/BTrack.cpp Fri Aug 11 18:18:33 2017 +0100 @@ -21,6 +21,7 @@ #include <cmath> #include <algorithm> +#include <numeric> #include "BTrack.h" #include "samplerate.h" #include <iostream> @@ -34,9 +35,9 @@ //======================================================================= BTrack::BTrack (int hopSize_) - : odf(hopSize_, 2*hopSize_, ComplexSpectralDifferenceHWR, HanningWindow) + : odf (hopSize_, 2 * hopSize_, ComplexSpectralDifferenceHWR, HanningWindow) { - initialise (hopSize_, 2*hopSize_); + initialise (hopSize_, 2 * hopSize_); } //======================================================================= @@ -88,6 +89,16 @@ //======================================================================= void BTrack::initialise (int hopSize_, int frameSize_) { + // set vector sizes + resampledOnsetDF.resize (512); + acf.resize (512); + weightingVector.resize (128); + combFilterBankOutput.resize (128); + tempoObservationVector.resize (41); + delta.resize (41); + prevDelta.resize (41); + prevDeltaFixed.resize (41); + double rayparam = 43; double pi = 3.14159265; @@ -111,12 +122,9 @@ weightingVector[n] = ((double) n / pow(rayparam,2)) * exp((-1*pow((double)-n,2)) / (2*pow(rayparam,2))); } - // initialise prev_delta - for (int i = 0; i < 41; i++) - { - prevDelta[i] = 1; - } - + // initialise prev_delta + std::fill (prevDelta.begin(), prevDelta.end(), 1); + double t_mu = 41/2; double m_sig; double x; @@ -166,7 +174,7 @@ void BTrack::setHopSize (int hopSize_) { hopSize = hopSize_; - onsetDFBufferSize = (512*512)/hopSize; // calculate df buffer size + onsetDFBufferSize = (512 * 512) / hopSize; // calculate df buffer size beatPeriod = round(60/((((double) hopSize)/44100)*tempo)); @@ -254,11 +262,9 @@ // update cumulative score updateCumulativeScore (newSample); - // if we are halfway between beats + // if we are halfway between beats, predict a beat if (m0 == 0) - { - predictBeat(); - } + predictBeat(); // if we are at a beat if (beatCounter == 0) @@ -273,44 +279,35 @@ //======================================================================= void BTrack::setTempo (double tempo) -{ - +{ /////////// TEMPO INDICATION RESET ////////////////// // firstly make sure tempo is between 80 and 160 bpm.. while (tempo > 160) - { - tempo = tempo/2; - } + tempo = tempo / 2; while (tempo < 80) - { - tempo = tempo * 2; - } + tempo = tempo * 2; // convert tempo from bpm value to integer index of tempo probability int tempo_index = (int) round((tempo - 80)/2); - // now set previous tempo observations to zero - for (int i=0;i < 41;i++) - { - prevDelta[i] = 0; - } - - // set desired tempo index to 1 + // now set previous tempo observations to zero and set desired tempo index to 1 + std::fill (prevDelta.begin(), prevDelta.end(), 0); prevDelta[tempo_index] = 1; - /////////// CUMULATIVE SCORE ARTIFICAL TEMPO UPDATE ////////////////// // calculate new beat period - int new_bperiod = (int) round(60/((((double) hopSize)/44100)*tempo)); + int newBeatPeriod = (int) round (60 / ((((double) hopSize) / 44100) * tempo)); - int bcounter = 1; - // initialise df_buffer to zeros - for (int i = (onsetDFBufferSize-1);i >= 0;i--) + int k = 1; + + // initialise onset detection function with delta functions spaced + // at the new beat period + for (int i = onsetDFBufferSize - 1; i >= 0; i--) { - if (bcounter == 1) + if (k == 1) { cumulativeScore[i] = 150; onsetDF[i] = 150; @@ -321,11 +318,11 @@ onsetDF[i] = 10; } - bcounter++; + k++; - if (bcounter > new_bperiod) + if (k > newBeatPeriod) { - bcounter = 1; + k = 1; } } @@ -335,7 +332,7 @@ beatCounter = 0; // offbeat is half of new beat period away - m0 = (int) round(((double) new_bperiod)/2); + m0 = (int) round (((double) newBeatPeriod) / 2); } //======================================================================= @@ -379,52 +376,42 @@ void BTrack::resampleOnsetDetectionFunction() { float output[512]; - float input[onsetDFBufferSize]; for (int i = 0;i < onsetDFBufferSize;i++) - { input[i] = (float) onsetDF[i]; - } - double src_ratio = 512.0/((double) onsetDFBufferSize); - int BUFFER_LEN = onsetDFBufferSize; - int output_len; - SRC_DATA src_data ; + double ratio = 512.0 / ((double) onsetDFBufferSize); + int bufferLength = onsetDFBufferSize; + int outputLength = 512; - //output_len = (int) floor (((double) BUFFER_LEN) * src_ratio) ; - output_len = 512; - + SRC_DATA src_data; src_data.data_in = input; - src_data.input_frames = BUFFER_LEN; - - src_data.src_ratio = src_ratio; - + src_data.input_frames = bufferLength; + src_data.src_ratio = ratio; src_data.data_out = output; - src_data.output_frames = output_len; + src_data.output_frames = outputLength; src_simple (&src_data, SRC_SINC_BEST_QUALITY, 1); - for (int i = 0;i < output_len;i++) - { + for (int i = 0; i < outputLength; i++) resampledOnsetDF[i] = (double) src_data.data_out[i]; - } } //======================================================================= void BTrack::calculateTempo() { // adaptive threshold on input - adaptiveThreshold (resampledOnsetDF,512); + adaptiveThreshold (resampledOnsetDF, 512); // calculate auto-correlation function of detection function - calculateBalancedACF (resampledOnsetDF); + calculateBalancedACF (&resampledOnsetDF[0]); // calculate output of comb filterbank calculateOutputOfCombFilterBank(); // adaptive threshold on rcf - adaptiveThreshold (combFilterBankOutput,128); + adaptiveThreshold (combFilterBankOutput, 128); int t_index; @@ -470,7 +457,7 @@ } - normaliseArray(delta,41); + normaliseArray (delta); maxind = -1; maxval = -1; @@ -495,7 +482,7 @@ } //======================================================================= -void BTrack::adaptiveThreshold (double* x, int N) +void BTrack::adaptiveThreshold (std::vector<double>& x, int N) { int i = 0; int k,t = 0; @@ -507,21 +494,21 @@ t = std::min(N,p_post); // what is smaller, p_post of df size. This is to avoid accessing outside of arrays // find threshold for first 't' samples, where a full average cannot be computed yet - for (i = 0;i <= t;i++) + for (i = 0; i <= t; i++) { - k = std::min ((i+p_pre),N); - x_thresh[i] = calculateMeanOfArray (x,1,k); + k = std::min ((i + p_pre), N); + x_thresh[i] = calculateMeanOfArray (x, 1, k); } // find threshold for bulk of samples across a moving average from [i-p_pre,i+p_post] - for (i = t+1;i < N-p_post;i++) + for (i = t + 1; i < N - p_post; i++) { - x_thresh[i] = calculateMeanOfArray (x,i-p_pre,i+p_post); + x_thresh[i] = calculateMeanOfArray (x, i - p_pre, i + p_post); } // for last few samples calculate threshold, again, not enough samples to do as above - for (i = N-p_post;i < N;i++) + for (i = N - p_post; i < N; i++) { - k = std::max ((i-p_post),1); - x_thresh[i] = calculateMeanOfArray (x,k,N); + k = std::max ((i - p_post), 1); + x_thresh[i] = calculateMeanOfArray (x, k, N); } // subtract the threshold from the detection function and check that it is not less than 0 @@ -652,49 +639,27 @@ } //======================================================================= -double BTrack::calculateMeanOfArray (double* array, int startIndex, int endIndex) +double BTrack::calculateMeanOfArray (std::vector<double>& array, int startIndex, int endIndex) { - int i; - double sum = 0; + int length = endIndex - startIndex; + double sum = std::accumulate (array.begin() + startIndex, array.begin() + endIndex, 0.0); - int length = endIndex - startIndex; - - // find sum - for (i = startIndex; i < endIndex; i++) - { - sum = sum + array[i]; - } - if (length > 0) - { - return sum / length; // average and return - } + return sum / static_cast<double> (length); // average and return else - { return 0; - } } //======================================================================= -void BTrack::normaliseArray (double* array, int N) +void BTrack::normaliseArray (std::vector<double>& array) { - double sum = 0; - - for (int i = 0; i < N; i++) - { - if (array[i] > 0) - { - sum = sum + array[i]; - } - } + double sum = std::accumulate (array.begin(), array.end(), 0.0); if (sum > 0) - { - for (int i = 0; i < N; i++) - { - array[i] = array[i] / sum; - } - } + { + for (int i = 0; i < array.size(); i++) + array[i] = array[i] / sum; + } } //======================================================================= @@ -703,19 +668,19 @@ int start, end, winsize; double max; - start = onsetDFBufferSize - round (2 * beatPeriod); - end = onsetDFBufferSize - round (beatPeriod / 2); - winsize = end-start+1; + start = onsetDFBufferSize - round (2. * beatPeriod); + end = onsetDFBufferSize - round (beatPeriod / 2.); + winsize = end - start + 1; double w1[winsize]; - double v = -2*beatPeriod; + double v = -2. * beatPeriod; double wcumscore; // create window for (int i = 0; i < winsize; i++) { w1[i] = exp((-1 * pow (tightness * log (-v / beatPeriod), 2)) / 2); - v = v+1; + v = v + 1; } // calculate new cumulative score value @@ -815,4 +780,4 @@ // set next prediction time m0 = beatCounter + round (beatPeriod / 2); -} \ No newline at end of file +}