diff src/BTrack.h @ 36:5bd9ae503dcf master 1.0.0

flow: Merged <release> '1.0.0' to <master> ('master').
author Adam Stark <adamstark.uk@gmail.com>
date Tue, 08 Jul 2014 12:32:27 +0100
parents 7af87d3f2ce2
children
line wrap: on
line diff
--- a/src/BTrack.h	Tue Jan 21 01:45:36 2014 +0000
+++ b/src/BTrack.h	Tue Jul 08 12:32:27 2014 +0100
@@ -22,77 +22,213 @@
 #ifndef __BTRACK_H
 #define __BTRACK_H
 
-//#include "fftw3.h"
+#include "OnsetDetectionFunction.h"
+#include <vector>
 
+//=======================================================================
+/** The main beat tracking class and the interface to the BTrack
+ * beat tracking algorithm. The algorithm can process either
+ * audio frames or onset detection function samples and also
+ * contains some static functions for calculating beat times in seconds
+ */
 class BTrack {
 	
 public:
-	BTrack();				// constructor
-	~BTrack();				// destructor	
+    
+    //=======================================================================
+    /** Constructor assuming hop size of 512 and frame size of 1024 */
+    BTrack();
+    
+    /** Constructor assuming frame size will be double the hopSize
+     * @param hopSize the hop size in audio samples
+     */
+    BTrack(int hopSize_);
+    
+    /** Constructor taking both hopSize and frameSize
+     * @param hopSize the hop size in audio samples
+     * @param frameSize the frame size in audio samples
+     */
+    BTrack(int hopSize_,int frameSize_);
+    
+    //=======================================================================
+    /** Updates the hop and frame size used by the beat tracker 
+     * @param hopSize the hop size in audio samples
+     * @param frameSize the frame size in audio samples
+     */
+    void updateHopAndFrameSize(int hopSize_,int frameSize_);
+    
+    //=======================================================================
+    /** Process a single audio frame 
+     * @param frame a pointer to an array containing an audio frame. The number of samples should 
+     * match the frame size that the algorithm was initialised with.
+     */
+    void processAudioFrame(double *frame);
+    
+    /** Add new onset detection function sample to buffer and apply beat tracking 
+     * @param sample an onset detection function sample
+     */
+    void processOnsetDetectionFunctionSample(double sample);
+   
+    //=======================================================================
+    /** @returns the current hop size being used by the beat tracker */
+    int getHopSize();
+    
+    /** @returns true if a beat should occur in the current audio frame */
+    bool beatDueInCurrentFrame();
+
+    /** @returns the current tempo estimate being used by the beat tracker */
+    double getCurrentTempoEstimate();
+    
+    /** @returns the most recent value of the cumulative score function */
+    double getLatestCumulativeScoreValue();
+    
+    //=======================================================================
+    /** Set the tempo of the beat tracker 
+     * @param tempo the tempo in beats per minute (bpm)
+     */
+    void setTempo(double tempo);
+    
+    /** Fix tempo to roughly around some value, so that the algorithm will only try to track
+     * tempi around the given tempo
+     * @param tempo the tempo in beats per minute (bpm)
+     */
+    void fixTempo(double tempo);
+    
+    /** Tell the algorithm to not fix the tempo anymore */
+    void doNotFixTempo();
+    
+    //=======================================================================
+    /** Calculates a beat time in seconds, given the frame number, hop size and sampling frequency.
+     * This version uses a long to represent the frame number
+     * @param frameNumber the index of the current frame 
+     * @param hopSize the hop size in audio samples
+     * @param fs the sampling frequency in Hz
+     * @returns a beat time in seconds
+     */
+    static double getBeatTimeInSeconds(long frameNumber,int hopSize,int fs);
+    
+    /** Calculates a beat time in seconds, given the frame number, hop size and sampling frequency.
+     * This version uses an int to represent the frame number
+     * @param frameNumber the index of the current frame
+     * @param hopSize the hop size in audio samples
+     * @param fs the sampling frequency in Hz
+     * @returns a beat time in seconds
+     */
+    static double getBeatTimeInSeconds(int frameNumber,int hopSize,int fs);
+    
+		
+private:
+    
+    /** Initialises the algorithm, setting internal parameters and creating weighting vectors 
+     * @param hopSize_ the hop size in audio samples
+     * @param frameSize_ the frame size in audio samples
+     */
+    void initialise(int hopSize_,int frameSize_);
+    
+    /** Initialise with hop size and set all array sizes accordingly
+     * @param hopSize_ the hop size in audio samples
+     */
+    void setHopSize(int hopSize_);
+    
+    /** Resamples the onset detection function from an arbitrary number of samples to 512 */
+    void resampleOnsetDetectionFunction();
+    
+    /** Updates the cumulative score function with a new onset detection function sample 
+     * @param odfSample an onset detection function sample
+     */
+    void updateCumulativeScore(double odfSample);
 	
-	void initialise(int fsize);
-	void process(float df_sample);
-	void plotdfbuffer();
-	void updatecumscore(float df_sample);
-	void predictbeat();
-	void dfconvert();
-	void calcTempo();
-	void adapt_thresh(float x[],int N);
-	float mean_array(float array[],int start,int end);
-	void normalise(float array[],int N);
-	void acf_bal(float df_thresh[]);
-	void getrcfoutput();
-	void settempo(float tempo);
-	void fixtempo(float tempo);
-	void unfixtempo();
+    /** Predicts the next beat, based upon the internal program state */
+    void predictBeat();
+    
+    /** Calculates the current tempo expressed as the beat period in detection function samples */
+    void calculateTempo();
+    
+    /** Calculates an adaptive threshold which is used to remove low level energy from detection
+     * function and emphasise peaks 
+     * @param x a pointer to an array containing onset detection function samples
+     * @param N the length of the array, x
+     */
+    void adaptiveThreshold(double *x,int N);
+    
+    /** Calculates the mean of values in an array between index locations [startIndex,endIndex]
+     * @param array a pointer to an array that contains the values we wish to find the mean from
+     * @param startIndex the start index from which we would like to calculate the mean
+     * @param endIndex the final index to which we would like to calculate the mean
+     * @returns the mean of the sub-section of the array
+     */
+    double calculateMeanOfArray(double *array,int startIndex,int endIndex);
+    
+    /** Normalises a given array
+     * @param array a pointer to the array we wish to normalise
+     * @param N the length of the array
+     */
+    void normaliseArray(double *array,int N);
+    
+    /** Calculates the balanced autocorrelation of the smoothed onset detection function
+     * @param onsetDetectionFunction a pointer to an array containing the onset detection function
+     */
+    void calculateBalancedACF(double *onsetDetectionFunction);
+    
+    /** Calculates the output of the comb filter bank */
+    void calculateOutputOfCombFilterBank();
 	
-	int playbeat;
-	float cscoreval;
-	float est_tempo;
-			
-private:
+    //=======================================================================
+
+    /** An OnsetDetectionFunction instance for calculating onset detection functions */
+    OnsetDetectionFunction odf;
+    
+    //=======================================================================
+	// buffers
+    
+    std::vector<double> onsetDF;            /**< to hold onset detection function */
+    std::vector<double> cumulativeScore;    /**< to hold cumulative score */
+    
+    double resampledOnsetDF[512];           /**< to hold resampled detection function */
 	
-	// buffers
-	float *dfbuffer;			// to hold detection function
-	float df512[512];			// to hold resampled detection function 
-	float *cumscore;			// to hold cumulative score
+    double acf[512];                        /**<  to hold autocorrelation function */
 	
-	float acf[512];				// to hold autocorrelation function
+    double weightingVector[128];            /**<  to hold weighting vector */
 	
-	float wv[128];				// to hold weighting vector
+    double combFilterBankOutput[128];       /**<  to hold comb filter output */
+    double tempoObservationVector[41];      /**<  to hold tempo version of comb filter output */
 	
-	float rcf[128];				// to hold comb filter output
-	float t_obs[41];			// to hold tempo version of comb filter output
+    double delta[41];                       /**<  to hold final tempo candidate array */
+    double prevDelta[41];                   /**<  previous delta */
+    double prevDeltaFixed[41];              /**<  fixed tempo version of previous delta */
 	
-	float delta[41];			// to hold final tempo candidate array
-	float prev_delta[41];		// previous delta
-	float prev_delta_fix[41];	// fixed tempo version of previous delta
+    double tempoTransitionMatrix[41][41];   /**<  tempo transition matrix */
 	
-	float t_tmat[41][41];		// transition matrix
+    
+	//=======================================================================
+    // parameters
+    
+    
+    double tightness;                       /**< the tightness of the weighting used to calculate cumulative score */
+    
+    double alpha;                           /**< the mix between the current detection function sample and the cumulative score's "momentum" */
+    
+    double beatPeriod;                      /**< the beat period, in detection function samples */
+    
+    double tempo;                           /**< the tempo in beats per minute */
 	
+    double estimatedTempo;                  /**< the current tempo estimation being used by the algorithm */
+    
+    double latestCumulativeScoreValue;      /**< holds the latest value of the cumulative score function */
+    
+    double tempoToLagFactor;                /**< factor for converting between lag and tempo */
 	
-	// parameters
-	float tightness;
-	float alpha;
-	float bperiod;
-	float tempo;
+    int m0;                                 /**< indicates when the next point to predict the next beat is */
+    
+    int beatCounter;                        /**< keeps track of when the next beat is - will be zero when the beat is due, and is set elsewhere in the algorithm to be positive once a beat prediction is made */
 	
+    int hopSize;                            /**< the hop size being used by the algorithm */
+    
+    int onsetDFBufferSize;                  /**< the onset detection function buffer size */
 	
-	float p_fact;
-	
-	
-	//
-	int m0;				// indicates when the next point to predict the next beat is
-	int beat;
-	
-	int dfbuffer_size;
-		
-	
-	int framesize;
-	
-	
-	int tempofix;
-	
+    bool tempoFixed;                        /**< indicates whether the tempo should be fixed or not */
+    
+    bool beatDueInFrame;                    /**< indicates whether a beat is due in the current frame */
 
 };