Mercurial > hg > pyin
changeset 132:926c292fa3ff fixedlag
fixed lag smoothing for pitch track working
author | Matthias Mauch <mail@matthiasmauch.net> |
---|---|
date | Fri, 03 Jul 2015 17:34:38 +0100 |
parents | b877df85ad9e |
children | 83978b93aac1 |
files | LocalCandidatePYIN.cpp Makefile.inc Makefile.osx MonoNote.cpp MonoNoteHMM.cpp MonoNoteHMM.h MonoPitch.cpp MonoPitch.h MonoPitchHMM.cpp MonoPitchHMM.h PYinVamp.cpp PYinVamp.h SparseHMM.cpp SparseHMM.h win32-build/pyin.pro |
diffstat | 15 files changed, 193 insertions(+), 268 deletions(-) [+] |
line wrap: on
line diff
--- a/LocalCandidatePYIN.cpp Fri Jul 03 14:09:05 2015 +0100 +++ b/LocalCandidatePYIN.cpp Fri Jul 03 17:34:38 2015 +0100 @@ -12,7 +12,7 @@ */ #include "LocalCandidatePYIN.h" -#include "MonoPitch.h" +#include "MonoPitchHMM.h" #include "YinUtil.h" #include "vamp-sdk/FFT.h" @@ -345,7 +345,7 @@ } // MONO-PITCH STUFF - MonoPitch mp; + MonoPitchHMM hmm(0); size_t nFrame = m_timestamp.size(); vector<vector<float> > pitchTracks; vector<float> freqSum = vector<float>(m_nCandidate); @@ -359,11 +359,11 @@ for (size_t iCandidate = 0; iCandidate < m_nCandidate; ++iCandidate) { pitchTracks.push_back(vector<float>(nFrame)); - vector<vector<pair<double,double> > > tempPitchProb; + vector<pair<double,double> > tempPitchProb; + vector<vector<double> > tempObsProb; float centrePitch = 45 + 3 * iCandidate; for (size_t iFrame = 0; iFrame < nFrame; ++iFrame) { - tempPitchProb.push_back(vector<pair<double,double> >()); float sumProb = 0; float pitch = 0; float prob = 0; @@ -374,16 +374,26 @@ boost::math::pdf(normalDist, pitch-centrePitch) / maxNormalDist * 2; sumProb += prob; - tempPitchProb[iFrame].push_back( + tempPitchProb.push_back( pair<double,double>(pitch,prob)); } for (size_t iProb = 0; iProb < m_pitchProb[iFrame].size(); ++iProb) { - tempPitchProb[iFrame][iProb].second /= sumProb; + tempPitchProb[iProb].second /= sumProb; } + tempObsProb.push_back(hmm.calculateObsProb(tempPitchProb)); } - vector<float> mpOut = mp.process(tempPitchProb); + vector<int> rawPitchPath = hmm.decodeViterbi(tempObsProb); + vector<float> mpOut; + + for (size_t iFrame = 0; iFrame < rawPitchPath.size(); ++iFrame) + { + float freq = hmm.nearestFreq(rawPitchPath[iFrame], + m_pitchProb[iFrame]); + mpOut.push_back(freq); // for note processing below + } + float prevFreq = 0; for (size_t iFrame = 0; iFrame < nFrame; ++iFrame) {
--- a/Makefile.inc Fri Jul 03 14:09:05 2015 +0100 +++ b/Makefile.inc Fri Jul 03 17:34:38 2015 +0100 @@ -15,7 +15,6 @@ Yin.cpp \ YinUtil.cpp \ MonoNote.cpp \ - MonoPitch.cpp \ MonoNoteParameters.cpp \ SparseHMM.cpp \ MonoNoteHMM.cpp \ @@ -65,15 +64,14 @@ # DO NOT DELETE libmain.o: PYinVamp.h Yin.h MeanFilter.h YinVamp.h LocalCandidatePYIN.h -LocalCandidatePYIN.o: LocalCandidatePYIN.h Yin.h MeanFilter.h MonoPitch.h +LocalCandidatePYIN.o: LocalCandidatePYIN.h Yin.h MeanFilter.h LocalCandidatePYIN.o: MonoPitchHMM.h SparseHMM.h YinUtil.h MonoNote.o: MonoNote.h MonoNoteHMM.h MonoNoteParameters.h SparseHMM.h MonoNoteHMM.o: MonoNoteHMM.h MonoNoteParameters.h SparseHMM.h MonoNoteParameters.o: MonoNoteParameters.h -MonoPitch.o: MonoPitch.h MonoPitchHMM.h SparseHMM.h MonoPitchHMM.o: MonoPitchHMM.h SparseHMM.h PYinVamp.o: PYinVamp.h Yin.h MeanFilter.h MonoNote.h MonoNoteHMM.h -PYinVamp.o: MonoNoteParameters.h SparseHMM.h MonoPitch.h MonoPitchHMM.h +PYinVamp.o: MonoNoteParameters.h SparseHMM.h MonoPitchHMM.h SparseHMM.o: SparseHMM.h Yin.o: Yin.h MeanFilter.h YinUtil.h YinUtil.o: YinUtil.h MeanFilter.h @@ -90,7 +88,6 @@ LocalCandidatePYIN.o: Yin.h MeanFilter.h MonoNote.o: MonoNoteHMM.h MonoNoteParameters.h SparseHMM.h MonoNoteHMM.o: MonoNoteParameters.h SparseHMM.h -MonoPitch.o: MonoPitchHMM.h SparseHMM.h MonoPitchHMM.o: SparseHMM.h PYinVamp.o: Yin.h MeanFilter.h Yin.o: MeanFilter.h
--- a/Makefile.osx Fri Jul 03 14:09:05 2015 +0100 +++ b/Makefile.osx Fri Jul 03 17:34:38 2015 +0100 @@ -1,5 +1,5 @@ ARCHFLAGS := -arch x86_64 -mmacosx-version-min=10.7 -stdlib=libc++ -CFLAGS := $(ARCHFLAGS) -O3 -I../vamp-plugin-sdk -I/usr/local/include -Wall -fPIC +CFLAGS := $(ARCHFLAGS) -O3 -I../vamp-plugin-sdk -I/usr/local/include -Wall -fPIC -g CXXFLAGS := $(CFLAGS) LDFLAGS := -L../vamp-plugin-sdk -L../vamp-plugin-sdk -lvamp-sdk $(ARCHFLAGS) -L/usr/local/lib
--- a/MonoNote.cpp Fri Jul 03 14:09:05 2015 +0100 +++ b/MonoNote.cpp Fri Jul 03 17:34:38 2015 +0100 @@ -22,7 +22,7 @@ using std::pair; MonoNote::MonoNote() : - hmm() + hmm(0) { }
--- a/MonoNoteHMM.cpp Fri Jul 03 14:09:05 2015 +0100 +++ b/MonoNoteHMM.cpp Fri Jul 03 17:34:38 2015 +0100 @@ -21,7 +21,8 @@ using std::vector; using std::pair; -MonoNoteHMM::MonoNoteHMM() : +MonoNoteHMM::MonoNoteHMM(int fixedLag) : + SparseHMM(fixedLag), par() { build();
--- a/MonoNoteHMM.h Fri Jul 03 14:09:05 2015 +0100 +++ b/MonoNoteHMM.h Fri Jul 03 17:34:38 2015 +0100 @@ -27,7 +27,7 @@ class MonoNoteHMM : public SparseHMM { public: - MonoNoteHMM(); + MonoNoteHMM(int fixedLag); const std::vector<double> calculateObsProb(const vector<pair<double, double> >); double getMidiPitch(size_t index); double getFrequency(size_t index);
--- a/MonoPitch.cpp Fri Jul 03 14:09:05 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - pYIN - A fundamental frequency estimator for monophonic audio - Centre for Digital Music, Queen Mary, University of London. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. See the file - COPYING included with this distribution for more information. -*/ - -#include "MonoPitch.h" -#include "MonoPitchHMM.h" -#include <vector> - -#include <cstdio> -#include <cmath> -#include <complex> - -using std::vector; -using std::pair; - -MonoPitch::MonoPitch() : - hmm() -{ -} - -MonoPitch::~MonoPitch() -{ -} - -const vector<float> -MonoPitch::process(const vector<vector<pair<double, double> > > pitchProb) -{ - // std::cerr << "before observation prob calculation" << std::endl; - vector<vector<double> > obsProb; - for (size_t iFrame = 0; iFrame < pitchProb.size(); ++iFrame) - { - obsProb.push_back(hmm.calculateObsProb(pitchProb[iFrame])); - } - - vector<float> out; - - // std::cerr << "before Viterbi decoding" << obsProb.size() << "ng" << obsProb[1].size() << std::endl; - vector<int> path = hmm.decodeViterbi(obsProb); - // std::cerr << "after Viterbi decoding" << std::endl; - - for (size_t iFrame = 0; iFrame < path.size(); ++iFrame) - { - // std::cerr << path[iFrame] << " " << hmm.m_freqs[path[iFrame]] << std::endl; - float hmmFreq = hmm.m_freqs[path[iFrame]]; - float bestFreq = 0; - float leastDist = 10000; - if (hmmFreq > 0) - { - // This was a Yin estimate, so try to get original pitch estimate back - // ... a bit hacky, since we could have direclty saved the frequency - // that was assigned to the HMM bin in hmm.calculateObsProb -- but would - // have had to rethink the interface of that method. - for (size_t iPitch = 0; iPitch < pitchProb[iFrame].size(); ++iPitch) - { - float freq = 440. * std::pow(2, (pitchProb[iFrame][iPitch].first - 69)/12); - float dist = std::abs(hmmFreq-freq); - if (dist < leastDist) - { - leastDist = dist; - bestFreq = freq; - } - } - } else { - bestFreq = hmmFreq; - } - out.push_back(bestFreq); - } - return(out); -}
--- a/MonoPitch.h Fri Jul 03 14:09:05 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - pYIN - A fundamental frequency estimator for monophonic audio - Centre for Digital Music, Queen Mary, University of London. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. See the file - COPYING included with this distribution for more information. -*/ - -#ifndef _MONOPITCH_H_ -#define _MONOPITCH_H_ - -#include "MonoPitchHMM.h" - -#include <iostream> -#include <vector> -#include <exception> - -using std::vector; -using std::pair; - -class MonoPitch { -public: - MonoPitch(); - virtual ~MonoPitch(); - - // pitchProb is a frame-wise vector carrying a vector of pitch-probability pairs - const vector<float> process(const vector<vector<pair<double, double> > > pitchProb); -private: - MonoPitchHMM hmm; -}; - -#endif
--- a/MonoPitchHMM.cpp Fri Jul 03 14:09:05 2015 +0100 +++ b/MonoPitchHMM.cpp Fri Jul 03 17:34:38 2015 +0100 @@ -22,8 +22,8 @@ using std::vector; using std::pair; -MonoPitchHMM::MonoPitchHMM() : -SparseHMM(), +MonoPitchHMM::MonoPitchHMM(int fixedLag) : +SparseHMM(fixedLag), m_minFreq(61.735), m_nBPS(5), m_nPitch(0), @@ -156,3 +156,41 @@ m_delta = vector<double>(m_nState); m_oldDelta = vector<double>(m_nState); } + +/* +Takes a state number and a pitch-prob vector, then finds the pitch that would +have been closest to the pitch of the state. Easy to understand? ;) +*/ +const float +MonoPitchHMM::nearestFreq(int state, vector<pair<double, double> > pitchProb) +{ + float hmmFreq = m_freqs[state]; + // std::cerr << "hmmFreq " << hmmFreq << std::endl; + float bestFreq = 0; + float leastDist = 10000; + if (hmmFreq > 0) + { + // This was a Yin estimate, so try to get original pitch estimate back + // ... a bit hacky, since we could have direclty saved the frequency + // that was assigned to the HMM bin in hmm.calculateObsProb -- but would + // have had to rethink the interface of that method. + + // std::cerr << "pitch prob size " << pitchProb.size() << std::endl; + + for (size_t iPt = 0; iPt < pitchProb.size(); ++iPt) + { + float freq = 440. * + std::pow(2, + (pitchProb[iPt].first - 69)/12); + float dist = std::abs(hmmFreq-freq); + if (dist < leastDist) + { + leastDist = dist; + bestFreq = freq; + } + } + } else { + bestFreq = hmmFreq; + } + return bestFreq; +} \ No newline at end of file
--- a/MonoPitchHMM.h Fri Jul 03 14:09:05 2015 +0100 +++ b/MonoPitchHMM.h Fri Jul 03 17:34:38 2015 +0100 @@ -26,10 +26,10 @@ class MonoPitchHMM : public SparseHMM { public: - MonoPitchHMM(); + MonoPitchHMM(int fixedLag); const std::vector<double> calculateObsProb(const vector<pair<double, double> >); - // double getMidiPitch(size_t index); - // double getFrequency(size_t index); + const float nearestFreq(int state, vector<pair<double, double> > pitchProb); + void build(); double m_minFreq; // 82.40689f/2 size_t m_nBPS;
--- a/PYinVamp.cpp Fri Jul 03 14:09:05 2015 +0100 +++ b/PYinVamp.cpp Fri Jul 03 17:34:38 2015 +0100 @@ -13,7 +13,6 @@ #include "PYinVamp.h" #include "MonoNote.h" -#include "MonoPitch.h" #include "MonoPitchHMM.h" #include "vamp-sdk/FFT.h" @@ -45,13 +44,13 @@ m_oSmoothedPitchTrack(0), m_oNotes(0), m_threshDistr(2.0f), - m_fixedLag(0.0f), + m_fixedLag(1.0f), m_outputUnvoiced(0.0f), m_preciseTime(0.0f), m_lowAmp(0.1f), m_onsetSensitivity(0.7f), m_pruneThresh(0.1f), - m_pitchHmm(), + m_pitchHmm(0), m_pitchProb(0), m_timestamp(0), m_level(0) @@ -442,6 +441,9 @@ m_yin.setThresholdDistr(m_threshDistr); m_yin.setFrameSize(m_blockSize); m_yin.setFast(!m_preciseTime); + + if (m_fixedLag == 1.f) m_pitchHmm = MonoPitchHMM(100); + else m_pitchHmm = MonoPitchHMM(0); m_pitchProb.clear(); m_timestamp.clear(); @@ -493,21 +495,50 @@ } } - if (m_fixedLag == 0.f) + vector<double> tempObsProb = m_pitchHmm.calculateObsProb(tempPitchProb); + if (m_timestamp.empty()) { - vector<double> tempObsProb = m_pitchHmm.calculateObsProb(tempPitchProb); - if (m_timestamp.empty()) + m_pitchHmm.initialise(tempObsProb); + } else { + m_pitchHmm.process(tempObsProb); + } + + m_pitchProb.push_back(tempPitchProb); + m_timestamp.push_back(timestamp); + + int lag = m_pitchHmm.m_fixedLag; + + if (m_fixedLag == 1.f) + { + if (m_timestamp.size() == lag + 1) { - m_pitchHmm.initialise(tempObsProb); - } else { - m_pitchHmm.process(tempObsProb); + m_timestamp.pop_front(); + m_pitchProb.pop_front(); + + Feature f; + f.hasTimestamp = true; + vector<int> rawPitchPath = m_pitchHmm.track(); + float freq = m_pitchHmm.nearestFreq(rawPitchPath[0], + m_pitchProb[0]); + f.timestamp = m_timestamp[0]; + f.values.clear(); + + // different output modes + if (freq < 0 && (m_outputUnvoiced==0)) + { + + } else { + if (m_outputUnvoiced == 1) + { + f.values.push_back(fabs(freq)); + } else { + f.values.push_back(freq); + } + fs[m_oSmoothedPitchTrack].push_back(f); + } } - m_pitchProb.push_back(tempPitchProb); - } else { - // Damn, so I need the hmm right here! Sadly it isn't defined here yet. - // Perhaps I could re-design the whole shabang } - m_timestamp.push_back(timestamp); + // F0 CANDIDATES Feature f; @@ -560,16 +591,16 @@ // ================== P I T C H T R A C K ================================= - vector<int> rawPitchPath = m_pitchHmm.finalise(); + vector<int> rawPitchPath = m_pitchHmm.track(); vector<float> mpOut; for (size_t iFrame = 0; iFrame < rawPitchPath.size(); ++iFrame) { - float freq = pitchState2Freq(rawPitchPath[iFrame], m_pitchProb[iFrame]); + float freq = m_pitchHmm.nearestFreq(rawPitchPath[iFrame], + m_pitchProb[iFrame]); mpOut.push_back(freq); // for note processing below f.timestamp = m_timestamp[iFrame]; - // std::cerr << f.timestamp << std::endl; f.values.clear(); // different output modes @@ -582,114 +613,70 @@ } fs[m_oSmoothedPitchTrack].push_back(f); } - - // for (size_t iFrame = 0; iFrame < mpOut.size(); ++iFrame) - // { - // if (mpOut[iFrame] < 0 && (m_outputUnvoiced==0)) continue; - - // if (m_outputUnvoiced == 1) - // { - // f.values.push_back(fabs(mpOut[iFrame])); - // } else { - // f.values.push_back(mpOut[iFrame]); - // } - - // fs[m_oSmoothedPitchTrack].push_back(f); - // } // ======================== N O T E S ====================================== - MonoNote mn; - std::vector<std::vector<std::pair<double, double> > > smoothedPitch; - for (size_t iFrame = 0; iFrame < mpOut.size(); ++iFrame) { - std::vector<std::pair<double, double> > temp; - if (mpOut[iFrame] > 0) - { - double tempPitch = 12 * - std::log(mpOut[iFrame]/440)/std::log(2.) + 69; - temp.push_back(std::pair<double,double>(tempPitch, .9)); - } - smoothedPitch.push_back(temp); - } - // vector<MonoNote::FrameOutput> mnOut = mn.process(m_pitchProb); - vector<MonoNote::FrameOutput> mnOut = mn.process(smoothedPitch); + // MonoNote mn; + // std::vector<std::vector<std::pair<double, double> > > smoothedPitch; + // for (size_t iFrame = 0; iFrame < mpOut.size(); ++iFrame) { + // std::vector<std::pair<double, double> > temp; + // if (mpOut[iFrame] > 0) + // { + // double tempPitch = 12 * + // std::log(mpOut[iFrame]/440)/std::log(2.) + 69; + // temp.push_back(std::pair<double,double>(tempPitch, .9)); + // } + // smoothedPitch.push_back(temp); + // } + // // vector<MonoNote::FrameOutput> mnOut = mn.process(m_pitchProb); + // vector<MonoNote::FrameOutput> mnOut = mn.process(smoothedPitch); - // turning feature into a note feature - f.hasTimestamp = true; - f.hasDuration = true; - f.values.clear(); + // // turning feature into a note feature + // f.hasTimestamp = true; + // f.hasDuration = true; + // f.values.clear(); - int onsetFrame = 0; - bool isVoiced = 0; - bool oldIsVoiced = 0; - size_t nFrame = m_pitchProb.size(); + // int onsetFrame = 0; + // bool isVoiced = 0; + // bool oldIsVoiced = 0; + // size_t nFrame = m_pitchProb.size(); - float minNoteFrames = (m_inputSampleRate*m_pruneThresh) / m_stepSize; + // float minNoteFrames = (m_inputSampleRate*m_pruneThresh) / m_stepSize; - // the body of the loop below should be in a function/method - std::vector<float> notePitchTrack; // collects pitches for one note at a time - for (size_t iFrame = 0; iFrame < nFrame; ++iFrame) - { - isVoiced = mnOut[iFrame].noteState < 3 - && smoothedPitch[iFrame].size() > 0 - && (iFrame >= nFrame-2 - || ((m_level[iFrame]/m_level[iFrame+2]) > - m_onsetSensitivity)); - if (isVoiced && iFrame != nFrame-1) - { - if (oldIsVoiced == 0) // beginning of a note - { - onsetFrame = iFrame; - } - float pitch = smoothedPitch[iFrame][0].first; - notePitchTrack.push_back(pitch); // add to the note's pitch track - } else { // not currently voiced - if (oldIsVoiced == 1) // end of note - { - if (notePitchTrack.size() >= minNoteFrames) - { - std::sort(notePitchTrack.begin(), notePitchTrack.end()); - float medianPitch = notePitchTrack[notePitchTrack.size()/2]; - float medianFreq = std::pow(2,(medianPitch - 69) / 12) * 440; - f.values.clear(); - f.values.push_back(medianFreq); - f.timestamp = m_timestamp[onsetFrame]; - f.duration = m_timestamp[iFrame] - m_timestamp[onsetFrame]; - fs[m_oNotes].push_back(f); - } - notePitchTrack.clear(); - } - } - oldIsVoiced = isVoiced; - } + // // the body of the loop below should be in a function/method + // std::vector<float> notePitchTrack; // collects pitches for one note at a time + // for (size_t iFrame = 0; iFrame < nFrame; ++iFrame) + // { + // isVoiced = mnOut[iFrame].noteState < 3 + // && smoothedPitch[iFrame].size() > 0 + // && (iFrame >= nFrame-2 + // || ((m_level[iFrame]/m_level[iFrame+2]) > + // m_onsetSensitivity)); + // if (isVoiced && iFrame != nFrame-1) + // { + // if (oldIsVoiced == 0) // beginning of a note + // { + // onsetFrame = iFrame; + // } + // float pitch = smoothedPitch[iFrame][0].first; + // notePitchTrack.push_back(pitch); // add to the note's pitch track + // } else { // not currently voiced + // if (oldIsVoiced == 1) // end of note + // { + // if (notePitchTrack.size() >= minNoteFrames) + // { + // std::sort(notePitchTrack.begin(), notePitchTrack.end()); + // float medianPitch = notePitchTrack[notePitchTrack.size()/2]; + // float medianFreq = std::pow(2,(medianPitch - 69) / 12) * 440; + // f.values.clear(); + // f.values.push_back(medianFreq); + // f.timestamp = m_timestamp[onsetFrame]; + // f.duration = m_timestamp[iFrame] - m_timestamp[onsetFrame]; + // fs[m_oNotes].push_back(f); + // } + // notePitchTrack.clear(); + // } + // } + // oldIsVoiced = isVoiced; + // } return fs; } - -float -PYinVamp::pitchState2Freq(int state, vector<pair<double, double> > pitchProb) -{ - float hmmFreq = m_pitchHmm.m_freqs[state]; - float bestFreq = 0; - float leastDist = 10000; - if (hmmFreq > 0) - { - // This was a Yin estimate, so try to get original pitch estimate back - // ... a bit hacky, since we could have direclty saved the frequency - // that was assigned to the HMM bin in hmm.calculateObsProb -- but would - // have had to rethink the interface of that method. - for (size_t iPt = 0; iPt < pitchProb.size(); ++iPt) - { - float freq = 440. * - std::pow(2, - (pitchProb[iPt].first - 69)/12); - float dist = std::abs(hmmFreq-freq); - if (dist < leastDist) - { - leastDist = dist; - bestFreq = freq; - } - } - } else { - bestFreq = hmmFreq; - } - return bestFreq; -} \ No newline at end of file
--- a/PYinVamp.h Fri Jul 03 14:09:05 2015 +0100 +++ b/PYinVamp.h Fri Jul 03 17:34:38 2015 +0100 @@ -56,8 +56,6 @@ FeatureSet getRemainingFeatures(); - float pitchState2Freq(int state, vector<pair<double, double> > pitchProb); - protected: size_t m_channels; size_t m_stepSize; @@ -83,8 +81,8 @@ MonoPitchHMM m_pitchHmm; - vector<vector<pair<double, double> > > m_pitchProb; - vector<Vamp::RealTime> m_timestamp; + deque<vector<pair<double, double> > > m_pitchProb; + deque<Vamp::RealTime> m_timestamp; vector<float> m_level; };
--- a/SparseHMM.cpp Fri Jul 03 14:09:05 2015 +0100 +++ b/SparseHMM.cpp Fri Jul 03 17:34:38 2015 +0100 @@ -19,7 +19,8 @@ using std::vector; using std::pair; -SparseHMM::SparseHMM() : +SparseHMM::SparseHMM(int fixedLag) : + m_fixedLag(fixedLag), m_nState(0), m_nTrans(0), m_init(0), @@ -61,7 +62,7 @@ process(obsProb[iFrame]); } - vector<int> path = finalise(); + vector<int> path = track(); return(path); } @@ -153,11 +154,20 @@ } m_scale.push_back(1.0); } + + if (m_fixedLag > 0 && m_psi.size() > m_fixedLag) + { + m_psi.pop_front(); + m_scale.pop_front(); + } + + // std::cerr << m_fixedLag << " " << m_psi.size() << std::endl; + return 0; } -vector<int> -SparseHMM::finalise() +const vector<int> +SparseHMM::track() { // initialise backward step size_t nFrame = m_psi.size();
--- a/SparseHMM.h Fri Jul 03 14:09:05 2015 +0100 +++ b/SparseHMM.h Fri Jul 03 17:34:38 2015 +0100 @@ -25,7 +25,7 @@ class SparseHMM { public: - SparseHMM(); + SparseHMM(int fixedLag); virtual const std::vector<double> calculateObsProb(const vector<pair<double, double> >); virtual void build(); @@ -33,8 +33,9 @@ void reset(); void initialise(vector<double> firstObs); int process(vector<double> newObs); - vector<int> finalise(); + const vector<int> track(); // "sparse" HMM definition + int m_fixedLag; int m_nState; int m_nTrans; vector<double> m_init;
--- a/win32-build/pyin.pro Fri Jul 03 14:09:05 2015 +0100 +++ b/win32-build/pyin.pro Fri Jul 03 17:34:38 2015 +0100 @@ -13,7 +13,6 @@ ../Yin.cpp \ ../SparseHMM.cpp \ ../MonoPitchHMM.cpp \ - ../MonoPitch.cpp \ ../MonoNoteParameters.cpp \ ../MonoNoteHMM.cpp \ ../MonoNote.cpp \ @@ -27,7 +26,6 @@ ../Yin.h \ ../SparseHMM.h \ ../MonoPitchHMM.h \ - ../MonoPitch.h \ ../MonoNoteParameters.h \ ../MonoNoteHMM.h \ ../MonoNote.h \