cannam@52: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ cannam@52: cannam@52: /* cannam@52: QM DSP Library cannam@52: cannam@52: Centre for Digital Music, Queen Mary, University of London. cannam@52: This file copyright 2008-2009 Matthew Davies and QMUL. cannam@52: All rights reserved. cannam@52: */ cannam@52: cannam@52: cannam@52: #ifndef TEMPOTRACKV2_H cannam@52: #define TEMPOTRACKV2_H cannam@52: cannam@52: #include cannam@52: cannam@52: using std::vector; cannam@52: cannam@54: //!!! Question: how far is this actually sample rate dependent? I cannam@54: // think it does produce plausible results for e.g. 48000 as well as cannam@54: // 44100, but surely the fixed window sizes and comb filtering will cannam@54: // make it prefer double or half time when run at e.g. 96000? cannam@54: cannam@52: class TempoTrackV2 cannam@52: { cannam@52: public: cannam@54: /** cannam@54: * Construct a tempo tracker that will operate on beat detection cannam@54: * function data calculated from audio at the given sample rate cannam@54: * with the given frame increment. cannam@54: * cannam@54: * Currently the sample rate and increment are used only for the cannam@54: * conversion from beat frame location to bpm in the tempo array. cannam@54: */ cannam@54: TempoTrackV2(float sampleRate, size_t dfIncrement); cannam@52: ~TempoTrackV2(); cannam@52: cannam@54: // Returned beat periods are given in df increment units; tempi in bpm cannam@52: void calculateBeatPeriod(const vector &df, cannam@53: vector &beatPeriod, cannam@53: vector &tempi); cannam@52: cannam@54: // Returned beat positions are given in df increment units cannam@52: void calculateBeats(const vector &df, cannam@52: const vector &beatPeriod, cannam@52: vector &beats); cannam@52: cannam@52: private: cannam@52: typedef vector i_vec_t; cannam@52: typedef vector > i_mat_t; cannam@52: typedef vector d_vec_t; cannam@52: typedef vector > d_mat_t; cannam@52: cannam@54: float m_rate; cannam@54: size_t m_increment; cannam@54: cannam@52: void adapt_thresh(d_vec_t &df); cannam@52: double mean_array(const d_vec_t &dfin, int start, int end); cannam@52: void filter_df(d_vec_t &df); cannam@52: void get_rcf(const d_vec_t &dfframe, const d_vec_t &wv, d_vec_t &rcf); cannam@53: void viterbi_decode(const d_mat_t &rcfmat, const d_vec_t &wv, cannam@53: d_vec_t &bp, d_vec_t &tempi); cannam@52: double get_max_val(const d_vec_t &df); cannam@52: int get_max_ind(const d_vec_t &df); cannam@52: void normalise_vec(d_vec_t &df); cannam@52: }; cannam@52: cannam@52: #endif