Mercurial > hg > qm-dsp
comparison dsp/tempotracking/DownBeat.cpp @ 56:a0f987c06bec
* Make it possible to retrieve beat spectral difference function from
bar detector
* Avoid crashes when bar detector is run with very short input
author | cannam |
---|---|
date | Fri, 27 Feb 2009 10:23:08 +0000 |
parents | 7fe29d8a7eaf |
children | d241e7701c0c |
comparison
equal
deleted
inserted
replaced
55:7fe29d8a7eaf | 56:a0f987c06bec |
---|---|
138 // DAVIES AND PLUMBLEY "A SPECTRAL DIFFERENCE APPROACH TO EXTRACTING DOWNBEATS IN MUSICAL AUDIO" | 138 // DAVIES AND PLUMBLEY "A SPECTRAL DIFFERENCE APPROACH TO EXTRACTING DOWNBEATS IN MUSICAL AUDIO" |
139 // EUSIPCO 2006, FLORENCE, ITALY | 139 // EUSIPCO 2006, FLORENCE, ITALY |
140 | 140 |
141 d_vec_t newspec(m_beatframesize / 2); // magnitude spectrum of current beat | 141 d_vec_t newspec(m_beatframesize / 2); // magnitude spectrum of current beat |
142 d_vec_t oldspec(m_beatframesize / 2); // magnitude spectrum of previous beat | 142 d_vec_t oldspec(m_beatframesize / 2); // magnitude spectrum of previous beat |
143 d_vec_t specdiff; | 143 |
144 m_beatsd.clear(); | |
144 | 145 |
145 if (audioLength == 0) return; | 146 if (audioLength == 0) return; |
146 | 147 |
147 for (size_t i = 0; i + 1 < beats.size(); ++i) { | 148 for (size_t i = 0; i + 1 < beats.size(); ++i) { |
148 | 149 |
189 | 190 |
190 MathUtilities::adaptiveThreshold(newspec); | 191 MathUtilities::adaptiveThreshold(newspec); |
191 | 192 |
192 // Calculate JS divergence between new and old spectral frames | 193 // Calculate JS divergence between new and old spectral frames |
193 | 194 |
194 specdiff.push_back(measureSpecDiff(oldspec, newspec)); | 195 if (i > 0) { // otherwise we have no previous frame |
195 // specdiff.push_back(KLDivergence().distanceDistribution(oldspec, newspec, false)); | 196 m_beatsd.push_back(measureSpecDiff(oldspec, newspec)); |
196 | 197 std::cerr << "specdiff: " << m_beatsd[m_beatsd.size()-1] << std::endl; |
197 std::cerr << "specdiff: " << specdiff[specdiff.size()-1] << std::endl; | 198 } |
198 | 199 |
199 // Copy newspec across to old | 200 // Copy newspec across to old |
200 | 201 |
201 for (size_t j = 0; j < m_beatframesize/2; ++j) { | 202 for (size_t j = 0; j < m_beatframesize/2; ++j) { |
202 oldspec[j] = newspec[j]; | 203 oldspec[j] = newspec[j]; |
214 dbcand[beat] = 0; | 215 dbcand[beat] = 0; |
215 } | 216 } |
216 | 217 |
217 // look for beat transition which leads to greatest spectral change | 218 // look for beat transition which leads to greatest spectral change |
218 for (int beat = 0; beat < timesig; ++beat) { | 219 for (int beat = 0; beat < timesig; ++beat) { |
219 for (int example = beat; example < specdiff.size(); example += timesig) { | 220 int count = 0; |
220 dbcand[beat] += (specdiff[example]) / timesig; | 221 for (int example = beat - 1; example < m_beatsd.size(); example += timesig) { |
221 } | 222 if (example < 0) continue; |
223 dbcand[beat] += (m_beatsd[example]) / timesig; | |
224 ++count; | |
225 } | |
226 if (count > 0) m_beatsd[beat] /= count; | |
222 std::cerr << "dbcand[" << beat << "] = " << dbcand[beat] << std::endl; | 227 std::cerr << "dbcand[" << beat << "] = " << dbcand[beat] << std::endl; |
223 } | 228 } |
224 | 229 |
225 | 230 |
226 // first downbeat is beat at index of maximum value of dbcand | 231 // first downbeat is beat at index of maximum value of dbcand |
278 } | 283 } |
279 | 284 |
280 return SD; | 285 return SD; |
281 } | 286 } |
282 | 287 |
288 void | |
289 DownBeat::getBeatSD(vector<double> &beatsd) const | |
290 { | |
291 for (int i = 0; i < m_beatsd.size(); ++i) beatsd.push_back(m_beatsd[i]); | |
292 } | |
293 |