# HG changeset patch # User Chris Cannam # Date 1235730188 0 # Node ID 33e03341d54183460643db95ca68205555760c5f # Parent 9c403afdd9e93ecb723f2e88446d5aeee8d15f29 * Make it possible to retrieve beat spectral difference function from bar detector * Avoid crashes when bar detector is run with very short input diff -r 9c403afdd9e9 -r 33e03341d541 dsp/tempotracking/DownBeat.cpp --- a/dsp/tempotracking/DownBeat.cpp Tue Feb 10 16:37:11 2009 +0000 +++ b/dsp/tempotracking/DownBeat.cpp Fri Feb 27 10:23:08 2009 +0000 @@ -140,7 +140,8 @@ d_vec_t newspec(m_beatframesize / 2); // magnitude spectrum of current beat d_vec_t oldspec(m_beatframesize / 2); // magnitude spectrum of previous beat - d_vec_t specdiff; + + m_beatsd.clear(); if (audioLength == 0) return; @@ -191,10 +192,10 @@ // Calculate JS divergence between new and old spectral frames - specdiff.push_back(measureSpecDiff(oldspec, newspec)); -// specdiff.push_back(KLDivergence().distanceDistribution(oldspec, newspec, false)); - - std::cerr << "specdiff: " << specdiff[specdiff.size()-1] << std::endl; + if (i > 0) { // otherwise we have no previous frame + m_beatsd.push_back(measureSpecDiff(oldspec, newspec)); + std::cerr << "specdiff: " << m_beatsd[m_beatsd.size()-1] << std::endl; + } // Copy newspec across to old @@ -216,9 +217,13 @@ // look for beat transition which leads to greatest spectral change for (int beat = 0; beat < timesig; ++beat) { - for (int example = beat; example < specdiff.size(); example += timesig) { - dbcand[beat] += (specdiff[example]) / timesig; + int count = 0; + for (int example = beat - 1; example < m_beatsd.size(); example += timesig) { + if (example < 0) continue; + dbcand[beat] += (m_beatsd[example]) / timesig; + ++count; } + if (count > 0) m_beatsd[beat] /= count; std::cerr << "dbcand[" << beat << "] = " << dbcand[beat] << std::endl; } @@ -280,3 +285,9 @@ return SD; } +void +DownBeat::getBeatSD(vector &beatsd) const +{ + for (int i = 0; i < m_beatsd.size(); ++i) beatsd.push_back(m_beatsd[i]); +} + diff -r 9c403afdd9e9 -r 33e03341d541 dsp/tempotracking/DownBeat.h --- a/dsp/tempotracking/DownBeat.h Tue Feb 10 16:37:11 2009 +0000 +++ b/dsp/tempotracking/DownBeat.h Fri Feb 27 10:23:08 2009 +0000 @@ -65,6 +65,17 @@ size_t audioLength, // after downsampling const vector &beats, vector &downbeats); + + /** + * Return the beat spectral difference function. This is + * calculated during findDownBeats, so this function can only be + * meaningfully called after that has completed. The returned + * vector contains one value for each of the beat times passed in + * to findDownBeats, less one. Each value contains the spectral + * difference between region prior to the beat's nominal position + * and the region following it. + */ + void getBeatSD(vector &beatsd) const; /** * For your downsampling convenience: call this function @@ -110,6 +121,7 @@ double *m_beatframe; double *m_fftRealOut; double *m_fftImagOut; + d_vec_t m_beatsd; }; #endif diff -r 9c403afdd9e9 -r 33e03341d541 dsp/tempotracking/TempoTrackV2.cpp --- a/dsp/tempotracking/TempoTrackV2.cpp Tue Feb 10 16:37:11 2009 +0000 +++ b/dsp/tempotracking/TempoTrackV2.cpp Fri Feb 27 10:23:08 2009 +0000 @@ -115,7 +115,7 @@ int col_counter = -1; // main loop for beat period calculation - for (uint i=0; i<(df.size()-winlen); i+=step) + for (uint i=0; i+winlen= backlink.size()) startpoint = backlink.size()-1; + // USE BACKLINK TO GET EACH NEW BEAT (TOWARDS THE BEGINNING OF THE FILE) // BACKTRACKING FROM THE END TO THE BEGINNING.. MAKING SURE NOT TO GO BEFORE SAMPLE 0 i_vec_t ibeats; @@ -457,7 +465,9 @@ while (backlink[ibeats.back()] > 0) { std::cerr << "backlink[" << ibeats.back() << "] = " << backlink[ibeats.back()] << std::endl; - ibeats.push_back(backlink[ibeats.back()]); + int b = ibeats.back(); + if (backlink[b] == b) break; // shouldn't happen... haha + ibeats.push_back(backlink[b]); } // REVERSE SEQUENCE OF IBEATS AND STORE AS BEATS