# HG changeset patch # User luisf # Date 1355325038 0 # Node ID d7619173d43c1bbfe4a6ae37d49cb2583db98b11 # Parent 505ed5f4280038d3a75c8e2a48395f0ef671e8df Now includes latest changes from MEPD: * TempoTrackV2::calculatebeats method - exposes "alpha" and "tightness" parameters * TempoTrackV2::calculateBeatPeriod - user can specify an inputtempo (in BPM) and "constraintempo" (bool) diff -r 505ed5f42800 -r d7619173d43c dsp/tempotracking/TempoTrackV2.cpp --- a/dsp/tempotracking/TempoTrackV2.cpp Wed Dec 12 15:05:13 2012 +0000 +++ b/dsp/tempotracking/TempoTrackV2.cpp Wed Dec 12 15:10:38 2012 +0000 @@ -41,7 +41,7 @@ b[0] = 0.2066; b[1] = 0.4131; b[2] = 0.2066; - + double inp1 = 0.; double inp2 = 0.; double out1 = 0.; @@ -67,7 +67,7 @@ for (unsigned int i = 0;i < df.size();i++) { - lp_df[i] = 0.; + lp_df[i] = 0.; } inp1 = 0.; inp2 = 0.; @@ -91,10 +91,17 @@ } +// MEPD 28/11/12 +// This function now allows for a user to specify an inputtempo (in BPM) +// and a flag "constraintempo" which replaces the general rayleigh weighting for periodicities +// with a gaussian which is centered around the input tempo +// Note, if inputtempo = 120 and constraintempo = false, then functionality is +// as it was before void TempoTrackV2::calculateBeatPeriod(const vector &df, vector &beat_period, - vector &tempi) + vector &tempi, + double inputtempo, bool constraintempo) { // to follow matlab.. split into 512 sample frames with a 128 hop size // calculate the acf, @@ -103,13 +110,42 @@ // and get best path unsigned int wv_len = 128; - double rayparam = 43.; + + // MEPD 28/11/12 + // the default value of inputtempo in the beat tracking plugin is 120 + // so if the user specifies a different inputtempo, the rayparam will be updated + // accordingly. + // note: 60*44100/512 is a magic number + // this might (will?) break if a user specifies a different frame rate for the onset detection function + double rayparam = (60*44100/512)/inputtempo; + + // these debug statements can be removed. + std::cout << "inputtempo" << inputtempo << std::endl; + std::cout << "rayparam" << rayparam << std::endl; + std::cout << "constraintempo" << constraintempo << std::endl; // make rayleigh weighting curve d_vec_t wv(wv_len); - for (unsigned int i=0; i (i) / pow(rayparam,2.)) * exp((-1.*pow(-static_cast (i),2.)) / (2.*pow(rayparam,2.))); + for (unsigned int i=0; i (i)-rayparam),2.)) / (2.*pow(rayparam/4.,2.)) ); + } + } + else + { + for (unsigned int i=0; i (i) / pow(rayparam,2.)) * exp((-1.*pow(-static_cast (i),2.)) / (2.*pow(rayparam,2.))); + } } // beat tracking frame size (roughly 6 seconds) and hop (1.5 seconds) @@ -130,9 +166,9 @@ dfframe[k] = df[i+k]; } // get rcf vector for current frame - d_vec_t rcf(wv_len); + d_vec_t rcf(wv_len); get_rcf(dfframe,wv,rcf); - + rcfmat.push_back( d_vec_t() ); // adds a new column col_counter++; for (unsigned int j=0; j (sum/ (dfframe.size()-lag)); @@ -177,7 +213,7 @@ // now apply comb filtering int numelem = 4; - + for (unsigned int i = 2;i < rcf.size();i++) // max beat period { for (int a = 1;a <= numelem;a++) // number of comb elements @@ -188,10 +224,10 @@ } } } - + // apply adaptive threshold to rcf MathUtilities::adaptiveThreshold(rcf); - + double rcfsum =0.; for (unsigned int i=0; i(i); tmat[i][j] = exp( (-1.*pow((j-mu),2.)) / (2.*pow(sigma,2.)) ); } @@ -246,7 +282,7 @@ delta.push_back( d_vec_t()); psi.push_back( i_vec_t()); for (unsigned int j=0; j0 ;t--) { @@ -328,7 +364,7 @@ unsigned int lastind = 0; for (unsigned int i=0; i &df, const vector &beat_period, - vector &beats) + vector &beats, double alpha, double tightness) { if (df.empty() || beat_period.empty()) return; @@ -414,8 +454,12 @@ backlink[i] = -1; } - double tightness = 4.; - double alpha = 0.9; + //double tightness = 4.; + //double alpha = 0.9; + // MEPD 28/11/12 + // debug statements that can be removed. + std::cout << "alpha" << alpha << std::endl; + std::cout << "tightness" << tightness << std::endl; // main loop for (unsigned int i=0; i= 0) + if (cscore_ind >= 0) { scorecands[j] = txwt[j] * cumscore[cscore_ind]; } @@ -457,7 +501,7 @@ for (unsigned int i=cumscore.size() - beat_period[beat_period.size()-1] ; i(ibeats[ibeats.size()-i-1]) ); } } diff -r 505ed5f42800 -r d7619173d43c dsp/tempotracking/TempoTrackV2.h --- a/dsp/tempotracking/TempoTrackV2.h Wed Dec 12 15:05:13 2012 +0000 +++ b/dsp/tempotracking/TempoTrackV2.h Wed Dec 12 15:10:38 2012 +0000 @@ -18,16 +18,14 @@ #define TEMPOTRACKV2_H #include -#include - -using std::vector; +using namespace std; //!!! Question: how far is this actually sample rate dependent? I // think it does produce plausible results for e.g. 48000 as well as // 44100, but surely the fixed window sizes and comb filtering will // make it prefer double or half time when run at e.g. 96000? -class TempoTrackV2 +class TempoTrackV2 { public: /** @@ -41,15 +39,17 @@ TempoTrackV2(float sampleRate, size_t dfIncrement); ~TempoTrackV2(); - // Returned beat periods are given in df increment units; tempi in bpm + // Returned beat periods are given in df increment units; inputtempo and tempi in bpm + // MEPD 28/11/12 Expose inputtempo and constraintempo parameters void calculateBeatPeriod(const vector &df, vector &beatPeriod, - vector &tempi); + vector &tempi, double inputtempo, bool constraintempo); // Returned beat positions are given in df increment units + // MEPD 28/11/12 Expose alpha and tightness parameters void calculateBeats(const vector &df, const vector &beatPeriod, - vector &beats); + vector &beats, double alpha, double tightness); private: typedef vector i_vec_t;