Mercurial > hg > qm-vamp-plugins
changeset 86:e377296d01b2
* First cut at including Matthew's newer beat tracker
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Tue, 20 Jan 2009 15:01:31 +0000 |
parents | 2631d0b3d7eb |
children | 790e051896a9 |
files | plugins/BeatTrack.cpp plugins/BeatTrack.h qm-vamp-plugins.pro |
diffstat | 3 files changed, 99 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/plugins/BeatTrack.cpp Thu Dec 04 12:03:51 2008 +0000 +++ b/plugins/BeatTrack.cpp Tue Jan 20 15:01:31 2009 +0000 @@ -12,13 +12,17 @@ #include <dsp/onsets/DetectionFunction.h> #include <dsp/onsets/PeakPicking.h> #include <dsp/tempotracking/TempoTrack.h> +#include <dsp/tempotracking/TempoTrackV2.h> using std::string; using std::vector; using std::cerr; using std::endl; -float BeatTracker::m_stepSecs = 0.01161; +float BeatTracker::m_stepSecs = 0.01161; // 512 samples at 44100 + +#define METHOD_OLD 0 +#define METHOD_NEW 1 class BeatTrackerData { @@ -46,6 +50,7 @@ BeatTracker::BeatTracker(float inputSampleRate) : Vamp::Plugin(inputSampleRate), m_d(0), + m_method(METHOD_NEW), m_dfType(DF_COMPLEXSD), m_whiten(false) { @@ -98,14 +103,26 @@ ParameterList list; ParameterDescriptor desc; + + desc.identifier = "method"; + desc.name = "Beat Tracking Method"; + desc.description = ""; //!!! + desc.minValue = 0; + desc.maxValue = 1; + desc.defaultValue = METHOD_NEW; + desc.isQuantized = true; + desc.quantizeStep = 1; + desc.valueNames.push_back("Old"); + desc.valueNames.push_back("New"); + list.push_back(desc); + desc.identifier = "dftype"; desc.name = "Onset Detection Function Type"; desc.description = "Method used to calculate the onset detection function"; desc.minValue = 0; desc.maxValue = 4; desc.defaultValue = 3; - desc.isQuantized = true; - desc.quantizeStep = 1; + desc.valueNames.clear(); desc.valueNames.push_back("High-Frequency Content"); desc.valueNames.push_back("Spectral Difference"); desc.valueNames.push_back("Phase Deviation"); @@ -139,6 +156,8 @@ default: case DF_COMPLEXSD: return 3; case DF_BROADBAND: return 4; } + } else if (name == "method") { + return m_method; } else if (name == "whiten") { return m_whiten ? 1.0 : 0.0; } @@ -156,6 +175,8 @@ default: case 3: m_dfType = DF_COMPLEXSD; break; case 4: m_dfType = DF_BROADBAND; break; } + } else if (name == "method") { + m_method = lrintf(value); } else if (name == "whiten") { m_whiten = (value > 0.5); } @@ -327,6 +348,13 @@ return FeatureSet(); } + if (m_method == METHOD_OLD) return beatTrackOld(); + else return beatTrackNew(); +} + +BeatTracker::FeatureSet +BeatTracker::beatTrackOld() +{ double aCoeffs[] = { 1.0000, -0.5949, 0.2348 }; double bCoeffs[] = { 0.1600, 0.3200, 0.1600 }; @@ -403,3 +431,64 @@ return returnFeatures; } +BeatTracker::FeatureSet +BeatTracker::beatTrackNew() +{ + vector<double> df; + vector<double> beatPeriod; + + for (size_t i = 2; i < m_d->dfOutput.size(); ++i) { // discard first two elts + df.push_back(m_d->dfOutput[i]); + beatPeriod.push_back(0.0); + } + if (df.empty()) return FeatureSet(); + + TempoTrackV2 tt; + + tt.calculateBeatPeriod(df, beatPeriod); + + vector<double> beats; + tt.calculateBeats(df, beatPeriod, beats); + + FeatureSet returnFeatures; + + char label[100]; + + for (size_t i = 0; i < beats.size(); ++i) { + + // beats are returned in reverse order? + + size_t index = beats.size() - i - 1; + + size_t frame = beats[index] * m_d->dfConfig.stepSize; + + Feature feature; + feature.hasTimestamp = true; + feature.timestamp = m_d->origin + Vamp::RealTime::frame2RealTime + (frame, lrintf(m_inputSampleRate)); + + float bpm = 0.0; + int frameIncrement = 0; + + if (index > 0) { + + frameIncrement = (beats[index - 1] - beats[index]) * m_d->dfConfig.stepSize; + + // one beat is frameIncrement frames, so there are + // samplerate/frameIncrement bps, so + // 60*samplerate/frameIncrement bpm + + if (frameIncrement > 0) { + bpm = (60.0 * m_inputSampleRate) / frameIncrement; + bpm = int(bpm * 100.0 + 0.5) / 100.0; + sprintf(label, "%.2f bpm", bpm); + feature.label = label; + } + } + + returnFeatures[0].push_back(feature); // beats are output 0 + } + + return returnFeatures; +} +
--- a/plugins/BeatTrack.h Thu Dec 04 12:03:51 2008 +0000 +++ b/plugins/BeatTrack.h Tue Jan 20 15:01:31 2009 +0000 @@ -48,9 +48,12 @@ protected: BeatTrackerData *m_d; + int m_method; int m_dfType; bool m_whiten; static float m_stepSecs; + FeatureSet beatTrackOld(); + FeatureSet beatTrackNew(); };
--- a/qm-vamp-plugins.pro Thu Dec 04 12:03:51 2008 +0000 +++ b/qm-vamp-plugins.pro Tue Jan 20 15:01:31 2009 +0000 @@ -1,10 +1,11 @@ TEMPLATE = lib -CONFIG += plugin warn_on release +CONFIG += plugin warn_on debug CONFIG -= qt linux-g++:QMAKE_CXXFLAGS_RELEASE += -DNDEBUG -O3 -fPIC -march=pentium3 -mfpmath=sse -msse +linux-g++-64:QMAKE_CXXFLAGS_RELEASE += -DNDEBUG -O3 -fPIC -ffast-math -fno-exceptions OBJECTS_DIR = tmp_obj MOC_DIR = tmp_moc @@ -14,6 +15,8 @@ linux-g++:LIBS += -static-libgcc -Wl,-Bstatic -lqm-dsp -lvamp-sdk -L/usr/lib/sse2/atlas -L/usr/lib/atlas/sse -llapack -lblas $$system(g++ -print-file-name=libstdc++.a) -lc -Wl,-Bdynamic -Wl,--version-script=vamp-plugin.map +linux-g++-64:LIBS += -Lbuild/linux/amd64 -Wl,-Bstatic -lqm-dsp -lvamp-sdk -llapack -lcblas -latlas -Wl,-Bdynamic -Wl,--version-script=vamp-plugin.map + macx-g++:LIBS += -framework Accelerate -exported_symbols_list=vamp-plugin.list #LIBS += -Wl,-Bstatic -lqm-dsp -lvamp-sdk -L/usr/lib/atlas/sse -lblas -llapack -Wl,-Bdynamic