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 |
