comparison dsp/tempotracking/DownBeat.cpp @ 281:33e03341d541

* Make it possible to retrieve beat spectral difference function from bar detector * Avoid crashes when bar detector is run with very short input
author Chris Cannam <c.cannam@qmul.ac.uk>
date Fri, 27 Feb 2009 10:23:08 +0000
parents 9c403afdd9e9
children d241e7701c0c
comparison
equal deleted inserted replaced
280:9c403afdd9e9 281:33e03341d541
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