c@279: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ c@279: c@279: /* c@279: QM DSP Library c@279: c@279: Centre for Digital Music, Queen Mary, University of London. c@279: This file copyright 2008-2009 Matthew Davies and QMUL. c@309: c@309: This program is free software; you can redistribute it and/or c@309: modify it under the terms of the GNU General Public License as c@309: published by the Free Software Foundation; either version 2 of the c@309: License, or (at your option) any later version. See the file c@309: COPYING included with this distribution for more information. c@279: */ c@279: cannam@489: #ifndef QM_DSP_DOWNBEAT_H cannam@489: #define QM_DSP_DOWNBEAT_H c@279: c@279: #include c@323: #include c@279: c@279: #include "dsp/rateconversion/Decimator.h" c@279: c@279: using std::vector; c@279: c@289: class FFTReal; c@289: c@279: /** c@279: * This class takes an input audio signal and a sequence of beat c@279: * locations (calculated e.g. by TempoTrackV2) and estimates which of c@279: * the beat locations are downbeats (first beat of the bar). c@279: * c@279: * The input audio signal is expected to have been downsampled to a c@279: * very low sampling rate (e.g. 2700Hz). A utility function for c@279: * downsampling and buffering incoming block-by-block audio is c@279: * provided. c@279: */ c@279: class DownBeat c@279: { c@279: public: c@279: /** c@279: * Construct a downbeat locator that will operate on audio at the c@279: * downsampled by the given decimation factor from the given c@279: * original sample rate, plus beats extracted from the same audio c@279: * at the given original sample rate with the given frame c@279: * increment. c@279: * c@279: * decimationFactor must be a power of two no greater than 64, and c@279: * dfIncrement must be a multiple of decimationFactor. c@279: */ c@279: DownBeat(float originalSampleRate, c@279: size_t decimationFactor, c@279: size_t dfIncrement); c@279: ~DownBeat(); c@279: c@280: void setBeatsPerBar(int bpb); c@280: c@279: /** c@279: * Estimate which beats are down-beats. c@279: * c@279: * audio contains the input audio stream after downsampling, and c@279: * audioLength contains the number of samples in this downsampled c@279: * stream. c@279: * c@279: * beats contains a series of beat positions expressed in c@279: * multiples of the df increment at the audio's original sample c@279: * rate, as described to the constructor. c@279: * c@279: * The returned downbeat array contains a series of indices to the c@279: * beats array. c@279: */ c@280: void findDownBeats(const float *audio, // downsampled c@279: size_t audioLength, // after downsampling c@279: const vector &beats, c@279: vector &downbeats); c@281: c@281: /** c@281: * Return the beat spectral difference function. This is c@281: * calculated during findDownBeats, so this function can only be c@281: * meaningfully called after that has completed. The returned c@281: * vector contains one value for each of the beat times passed in c@281: * to findDownBeats, less one. Each value contains the spectral c@281: * difference between region prior to the beat's nominal position c@281: * and the region following it. c@281: */ c@281: void getBeatSD(vector &beatsd) const; c@279: c@279: /** c@279: * For your downsampling convenience: call this function c@279: * repeatedly with input audio blocks containing dfIncrement c@279: * samples at the original sample rate, to decimate them to the c@279: * downsampled rate and buffer them within the DownBeat class. c@279: * c@279: * Call getBufferedAudio() to retrieve the results after all c@279: * blocks have been processed. c@279: */ c@280: void pushAudioBlock(const float *audio); c@279: c@279: /** c@279: * Retrieve the accumulated audio produced by pushAudioBlock calls. c@279: */ c@280: const float *getBufferedAudio(size_t &length) const; c@280: c@280: /** c@280: * Clear any buffered downsampled audio data. c@280: */ c@280: void resetAudioBuffer(); c@279: c@279: private: c@279: typedef vector i_vec_t; c@279: typedef vector > i_mat_t; c@279: typedef vector d_vec_t; c@279: typedef vector > d_mat_t; c@279: c@279: void makeDecimators(); c@279: double measureSpecDiff(d_vec_t oldspec, d_vec_t newspec); c@279: c@280: int m_bpb; c@279: float m_rate; c@279: size_t m_factor; c@279: size_t m_increment; c@279: Decimator *m_decimator1; c@279: Decimator *m_decimator2; c@280: float *m_buffer; c@280: float *m_decbuf; c@279: size_t m_bufsiz; c@279: size_t m_buffill; c@279: size_t m_beatframesize; c@279: double *m_beatframe; c@289: FFTReal *m_fft; c@279: double *m_fftRealOut; c@279: double *m_fftImagOut; c@281: d_vec_t m_beatsd; c@279: }; c@279: c@279: #endif