Mercurial > hg > qm-dsp
comparison dsp/tempotracking/TempoTrackV2.cpp @ 279:c8908cdc8c32
* First cut at Matthew's downbeat estimator -- untested so far
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Tue, 10 Feb 2009 12:52:43 +0000 |
parents | 833ca65b0820 |
children | 7fe29d8a7eaf |
comparison
equal
deleted
inserted
replaced
278:833ca65b0820 | 279:c8908cdc8c32 |
---|---|
12 | 12 |
13 #include <cmath> | 13 #include <cmath> |
14 #include <cstdlib> | 14 #include <cstdlib> |
15 #include <iostream> | 15 #include <iostream> |
16 | 16 |
17 | 17 #include "maths/MathUtilities.h" |
18 //#define FRAMESIZE 512 | 18 |
19 //#define BIGFRAMESIZE 1024 | |
20 #define TWOPI 6.283185307179586232 | |
21 #define EPS 0.0000008 // just some arbitrary small number | 19 #define EPS 0.0000008 // just some arbitrary small number |
22 | 20 |
23 TempoTrackV2::TempoTrackV2() { } | 21 TempoTrackV2::TempoTrackV2(float rate, size_t increment) : |
22 m_rate(rate), m_increment(increment) { } | |
24 TempoTrackV2::~TempoTrackV2() { } | 23 TempoTrackV2::~TempoTrackV2() { } |
25 | |
26 void | |
27 TempoTrackV2::adapt_thresh(d_vec_t &df) | |
28 { | |
29 d_vec_t smoothed(df.size()); | |
30 | |
31 int p_post = 7; | |
32 int p_pre = 8; | |
33 | |
34 int t = std::min(static_cast<int>(df.size()),p_post); // what is smaller, p_post of df size. This is to avoid accessing outside of arrays | |
35 | |
36 // find threshold for first 't' samples, where a full average cannot be computed yet | |
37 for (int i = 0;i <= t;i++) | |
38 { | |
39 int k = std::min((i+p_pre),static_cast<int>(df.size())); | |
40 smoothed[i] = mean_array(df,1,k); | |
41 } | |
42 // find threshold for bulk of samples across a moving average from [i-p_pre,i+p_post] | |
43 for (uint i = t+1;i < df.size()-p_post;i++) | |
44 { | |
45 smoothed[i] = mean_array(df,i-p_pre,i+p_post); | |
46 } | |
47 // for last few samples calculate threshold, again, not enough samples to do as above | |
48 for (uint i = df.size()-p_post;i < df.size();i++) | |
49 { | |
50 int k = std::max((static_cast<int> (i) -p_post),1); | |
51 smoothed[i] = mean_array(df,k,df.size()); | |
52 } | |
53 | |
54 // subtract the threshold from the detection function and check that it is not less than 0 | |
55 for (uint i = 0;i < df.size();i++) | |
56 { | |
57 df[i] -= smoothed[i]; | |
58 if (df[i] < 0) | |
59 { | |
60 df[i] = 0; | |
61 } | |
62 } | |
63 } | |
64 | |
65 double | |
66 TempoTrackV2::mean_array(const d_vec_t &dfin,int start,int end) | |
67 { | |
68 double sum = 0.; | |
69 | |
70 // find sum | |
71 for (int i = start;i < end;i++) | |
72 { | |
73 sum += dfin[i]; | |
74 } | |
75 | |
76 return static_cast<double> (sum / (end - start + 1) ); // average and return | |
77 } | |
78 | 24 |
79 void | 25 void |
80 TempoTrackV2::filter_df(d_vec_t &df) | 26 TempoTrackV2::filter_df(d_vec_t &df) |
81 { | 27 { |
82 d_vec_t a(3); | 28 d_vec_t a(3); |
203 | 149 |
204 // make acf | 150 // make acf |
205 | 151 |
206 d_vec_t dfframe(dfframe_in); | 152 d_vec_t dfframe(dfframe_in); |
207 | 153 |
208 adapt_thresh(dfframe); | 154 MathUtilities::adaptiveThreshold(dfframe); |
209 | 155 |
210 d_vec_t acf(dfframe.size()); | 156 d_vec_t acf(dfframe.size()); |
211 | 157 |
212 | 158 |
213 for (uint lag=0; lag<dfframe.size(); lag++) | 159 for (uint lag=0; lag<dfframe.size(); lag++) |
236 } | 182 } |
237 } | 183 } |
238 } | 184 } |
239 | 185 |
240 // apply adaptive threshold to rcf | 186 // apply adaptive threshold to rcf |
241 adapt_thresh(rcf); | 187 MathUtilities::adaptiveThreshold(rcf); |
242 | 188 |
243 double rcfsum =0.; | 189 double rcfsum =0.; |
244 for (uint i=0; i<rcf.size(); i++) | 190 for (uint i=0; i<rcf.size(); i++) |
245 { | 191 { |
246 rcf[i] += EPS ; | 192 rcf[i] += EPS ; |
388 beat_period[i] = beat_period[lastind]; | 334 beat_period[i] = beat_period[lastind]; |
389 } | 335 } |
390 | 336 |
391 for (uint i = 0; i < beat_period.size(); i++) | 337 for (uint i = 0; i < beat_period.size(); i++) |
392 { | 338 { |
393 tempi.push_back((60.*44100./512.)/beat_period[i]); | 339 tempi.push_back((60. * m_rate / m_increment)/beat_period[i]); |
394 } | 340 } |
395 } | 341 } |
396 | 342 |
397 double | 343 double |
398 TempoTrackV2::get_max_val(const d_vec_t &df) | 344 TempoTrackV2::get_max_val(const d_vec_t &df) |