cannam@54
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
cannam@54
|
2
|
cannam@54
|
3 /*
|
cannam@54
|
4 QM DSP Library
|
cannam@54
|
5
|
cannam@54
|
6 Centre for Digital Music, Queen Mary, University of London.
|
cannam@54
|
7 This file copyright 2008-2009 Matthew Davies and QMUL.
|
cannam@54
|
8 All rights reserved.
|
cannam@54
|
9 */
|
cannam@54
|
10
|
cannam@54
|
11 #ifndef DOWNBEAT_H
|
cannam@54
|
12 #define DOWNBEAT_H
|
cannam@54
|
13
|
cannam@54
|
14 #include <vector>
|
cannam@54
|
15
|
cannam@54
|
16 #include "dsp/rateconversion/Decimator.h"
|
cannam@54
|
17
|
cannam@54
|
18 using std::vector;
|
cannam@54
|
19
|
cannam@54
|
20 /**
|
cannam@54
|
21 * This class takes an input audio signal and a sequence of beat
|
cannam@54
|
22 * locations (calculated e.g. by TempoTrackV2) and estimates which of
|
cannam@54
|
23 * the beat locations are downbeats (first beat of the bar).
|
cannam@54
|
24 *
|
cannam@54
|
25 * The input audio signal is expected to have been downsampled to a
|
cannam@54
|
26 * very low sampling rate (e.g. 2700Hz). A utility function for
|
cannam@54
|
27 * downsampling and buffering incoming block-by-block audio is
|
cannam@54
|
28 * provided.
|
cannam@54
|
29 */
|
cannam@54
|
30 class DownBeat
|
cannam@54
|
31 {
|
cannam@54
|
32 public:
|
cannam@54
|
33 /**
|
cannam@54
|
34 * Construct a downbeat locator that will operate on audio at the
|
cannam@54
|
35 * downsampled by the given decimation factor from the given
|
cannam@54
|
36 * original sample rate, plus beats extracted from the same audio
|
cannam@54
|
37 * at the given original sample rate with the given frame
|
cannam@54
|
38 * increment.
|
cannam@54
|
39 *
|
cannam@54
|
40 * decimationFactor must be a power of two no greater than 64, and
|
cannam@54
|
41 * dfIncrement must be a multiple of decimationFactor.
|
cannam@54
|
42 */
|
cannam@54
|
43 DownBeat(float originalSampleRate,
|
cannam@54
|
44 size_t decimationFactor,
|
cannam@54
|
45 size_t dfIncrement);
|
cannam@54
|
46 ~DownBeat();
|
cannam@54
|
47
|
cannam@55
|
48 void setBeatsPerBar(int bpb);
|
cannam@55
|
49
|
cannam@54
|
50 /**
|
cannam@54
|
51 * Estimate which beats are down-beats.
|
cannam@54
|
52 *
|
cannam@54
|
53 * audio contains the input audio stream after downsampling, and
|
cannam@54
|
54 * audioLength contains the number of samples in this downsampled
|
cannam@54
|
55 * stream.
|
cannam@54
|
56 *
|
cannam@54
|
57 * beats contains a series of beat positions expressed in
|
cannam@54
|
58 * multiples of the df increment at the audio's original sample
|
cannam@54
|
59 * rate, as described to the constructor.
|
cannam@54
|
60 *
|
cannam@54
|
61 * The returned downbeat array contains a series of indices to the
|
cannam@54
|
62 * beats array.
|
cannam@54
|
63 */
|
cannam@55
|
64 void findDownBeats(const float *audio, // downsampled
|
cannam@54
|
65 size_t audioLength, // after downsampling
|
cannam@54
|
66 const vector<double> &beats,
|
cannam@54
|
67 vector<int> &downbeats);
|
cannam@54
|
68
|
cannam@54
|
69 /**
|
cannam@54
|
70 * For your downsampling convenience: call this function
|
cannam@54
|
71 * repeatedly with input audio blocks containing dfIncrement
|
cannam@54
|
72 * samples at the original sample rate, to decimate them to the
|
cannam@54
|
73 * downsampled rate and buffer them within the DownBeat class.
|
cannam@54
|
74 *
|
cannam@54
|
75 * Call getBufferedAudio() to retrieve the results after all
|
cannam@54
|
76 * blocks have been processed.
|
cannam@54
|
77 */
|
cannam@55
|
78 void pushAudioBlock(const float *audio);
|
cannam@54
|
79
|
cannam@54
|
80 /**
|
cannam@54
|
81 * Retrieve the accumulated audio produced by pushAudioBlock calls.
|
cannam@54
|
82 */
|
cannam@55
|
83 const float *getBufferedAudio(size_t &length) const;
|
cannam@55
|
84
|
cannam@55
|
85 /**
|
cannam@55
|
86 * Clear any buffered downsampled audio data.
|
cannam@55
|
87 */
|
cannam@55
|
88 void resetAudioBuffer();
|
cannam@54
|
89
|
cannam@54
|
90 private:
|
cannam@54
|
91 typedef vector<int> i_vec_t;
|
cannam@54
|
92 typedef vector<vector<int> > i_mat_t;
|
cannam@54
|
93 typedef vector<double> d_vec_t;
|
cannam@54
|
94 typedef vector<vector<double> > d_mat_t;
|
cannam@54
|
95
|
cannam@54
|
96 void makeDecimators();
|
cannam@54
|
97 double measureSpecDiff(d_vec_t oldspec, d_vec_t newspec);
|
cannam@54
|
98
|
cannam@55
|
99 int m_bpb;
|
cannam@54
|
100 float m_rate;
|
cannam@54
|
101 size_t m_factor;
|
cannam@54
|
102 size_t m_increment;
|
cannam@54
|
103 Decimator *m_decimator1;
|
cannam@54
|
104 Decimator *m_decimator2;
|
cannam@55
|
105 float *m_buffer;
|
cannam@55
|
106 float *m_decbuf;
|
cannam@54
|
107 size_t m_bufsiz;
|
cannam@54
|
108 size_t m_buffill;
|
cannam@54
|
109 size_t m_beatframesize;
|
cannam@54
|
110 double *m_beatframe;
|
cannam@54
|
111 double *m_fftRealOut;
|
cannam@54
|
112 double *m_fftImagOut;
|
cannam@54
|
113 };
|
cannam@54
|
114
|
cannam@54
|
115 #endif
|