add queen mary DSP library
[ardour.git] / libs / qm-dsp / dsp / tempotracking / DownBeat.h
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
2
3 /*
4     QM DSP Library
5
6     Centre for Digital Music, Queen Mary, University of London.
7     This file copyright 2008-2009 Matthew Davies and QMUL.
8
9     This program is free software; you can redistribute it and/or
10     modify it under the terms of the GNU General Public License as
11     published by the Free Software Foundation; either version 2 of the
12     License, or (at your option) any later version.  See the file
13     COPYING included with this distribution for more information.
14 */
15
16 #ifndef DOWNBEAT_H
17 #define DOWNBEAT_H
18
19 #include <vector>
20
21 #include "dsp/rateconversion/Decimator.h"
22
23 using std::vector;
24
25 class FFTReal;
26
27 /**
28  * This class takes an input audio signal and a sequence of beat
29  * locations (calculated e.g. by TempoTrackV2) and estimates which of
30  * the beat locations are downbeats (first beat of the bar).
31  * 
32  * The input audio signal is expected to have been downsampled to a
33  * very low sampling rate (e.g. 2700Hz).  A utility function for
34  * downsampling and buffering incoming block-by-block audio is
35  * provided.
36  */
37 class DownBeat
38 {
39 public:
40     /**
41      * Construct a downbeat locator that will operate on audio at the
42      * downsampled by the given decimation factor from the given
43      * original sample rate, plus beats extracted from the same audio
44      * at the given original sample rate with the given frame
45      * increment.
46      *
47      * decimationFactor must be a power of two no greater than 64, and
48      * dfIncrement must be a multiple of decimationFactor.
49      */
50     DownBeat(float originalSampleRate,
51              size_t decimationFactor,
52              size_t dfIncrement);
53     ~DownBeat();
54
55     void setBeatsPerBar(int bpb);
56
57     /**
58      * Estimate which beats are down-beats.
59      * 
60      * audio contains the input audio stream after downsampling, and
61      * audioLength contains the number of samples in this downsampled
62      * stream.
63      *
64      * beats contains a series of beat positions expressed in
65      * multiples of the df increment at the audio's original sample
66      * rate, as described to the constructor.
67      *
68      * The returned downbeat array contains a series of indices to the
69      * beats array.
70      */
71     void findDownBeats(const float *audio, // downsampled
72                        size_t audioLength, // after downsampling
73                        const vector<double> &beats,
74                        vector<int> &downbeats);
75
76     /**
77      * Return the beat spectral difference function.  This is
78      * calculated during findDownBeats, so this function can only be
79      * meaningfully called after that has completed.  The returned
80      * vector contains one value for each of the beat times passed in
81      * to findDownBeats, less one.  Each value contains the spectral
82      * difference between region prior to the beat's nominal position
83      * and the region following it.
84      */
85     void getBeatSD(vector<double> &beatsd) const;
86     
87     /**
88      * For your downsampling convenience: call this function
89      * repeatedly with input audio blocks containing dfIncrement
90      * samples at the original sample rate, to decimate them to the
91      * downsampled rate and buffer them within the DownBeat class.
92      *     
93      * Call getBufferedAudio() to retrieve the results after all
94      * blocks have been processed.
95      */
96     void pushAudioBlock(const float *audio);
97     
98     /**
99      * Retrieve the accumulated audio produced by pushAudioBlock calls.
100      */
101     const float *getBufferedAudio(size_t &length) const;
102
103     /**
104      * Clear any buffered downsampled audio data.
105      */
106     void resetAudioBuffer();
107
108 private:
109     typedef vector<int> i_vec_t;
110     typedef vector<vector<int> > i_mat_t;
111     typedef vector<double> d_vec_t;
112     typedef vector<vector<double> > d_mat_t;
113
114     void makeDecimators();
115     double measureSpecDiff(d_vec_t oldspec, d_vec_t newspec);
116
117     int m_bpb;
118     float m_rate;
119     size_t m_factor;
120     size_t m_increment;
121     Decimator *m_decimator1;
122     Decimator *m_decimator2;
123     float *m_buffer;
124     float *m_decbuf;
125     size_t m_bufsiz;
126     size_t m_buffill;
127     size_t m_beatframesize;
128     double *m_beatframe;
129     FFTReal *m_fft;
130     double *m_fftRealOut;
131     double *m_fftImagOut;
132     d_vec_t m_beatsd;
133 };
134
135 #endif