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