# HG changeset patch # User Chris Cannam # Date 1495034983 -3600 # Node ID 729cc1da9b8de664ba9010de49bfc949bbc78b80 # Parent b83e6fbe22cc4968f85f28c5036f0a50f950e3ca Use fixed-lag HMM in note tracking as well (when fixed-lag mode is selected) diff -r b83e6fbe22cc -r 729cc1da9b8d MonoNote.cpp --- a/MonoNote.cpp Wed May 17 15:55:37 2017 +0100 +++ b/MonoNote.cpp Wed May 17 16:29:43 2017 +0100 @@ -21,8 +21,9 @@ using std::vector; using std::pair; -MonoNote::MonoNote() : - hmm(0) +MonoNote::MonoNote(bool fixedLag) : + m_fixedLag(fixedLag), + hmm(m_fixedLag ? 1000 : 0) { } @@ -49,6 +50,7 @@ // time. vector path; + path.reserve(pitchProb.size()); if (!pitchProb.empty()) { @@ -56,13 +58,21 @@ for (size_t iFrame = 1; iFrame < pitchProb.size(); ++iFrame) { + if (m_fixedLag && (int(iFrame) >= hmm.m_fixedLag)) + { + vector rawPath = hmm.track(); + path.push_back(rawPath[0]); + } + hmm.process(hmm.calculateObsProb(pitchProb[iFrame])); } - path = hmm.track(); + vector rawPath = hmm.track(); + path.insert(path.end(), rawPath.begin(), rawPath.end()); } - vector out; + vector out; + out.reserve(path.size()); for (size_t iFrame = 0; iFrame < path.size(); ++iFrame) { diff -r b83e6fbe22cc -r 729cc1da9b8d MonoNote.h --- a/MonoNote.h Wed May 17 15:55:37 2017 +0100 +++ b/MonoNote.h Wed May 17 16:29:43 2017 +0100 @@ -26,7 +26,7 @@ class MonoNote { public: - MonoNote(); + MonoNote(bool fixedLag); virtual ~MonoNote(); struct FrameOutput { @@ -39,7 +39,9 @@ }; // pitchProb is a frame-wise vector carrying a vector of pitch-probability pairs const vector process(const vector > > pitchProb); + private: + bool m_fixedLag; MonoNoteHMM hmm; }; diff -r b83e6fbe22cc -r 729cc1da9b8d PYinVamp.cpp --- a/PYinVamp.cpp Wed May 17 15:55:37 2017 +0100 +++ b/PYinVamp.cpp Wed May 17 16:29:43 2017 +0100 @@ -431,7 +431,7 @@ m_yin.setFrameSize(m_blockSize); m_yin.setFast(!m_preciseTime); - if (m_fixedLag == 1.f) m_pitchHmm = MonoPitchHMM(100); + if (m_fixedLag > 0.5f) m_pitchHmm = MonoPitchHMM(100); else m_pitchHmm = MonoPitchHMM(0); m_pitchProb.clear(); @@ -494,7 +494,7 @@ int lag = m_pitchHmm.m_fixedLag; - if (m_fixedLag == 1.f) // do fixed-lag smoothing instead of full Viterbi + if (m_fixedLag > 0.5f) // do fixed-lag smoothing instead of full Viterbi { if (int(m_timestamp.size()) == lag + 1) { @@ -623,7 +623,16 @@ smoothedPitch.push_back(temp); } - MonoNote mn; + // In fixed-lag mode, we use fixed-lag processing for the note + // transitions here as well as for the pitch transitions in + // process. The main reason we provide the fixed-lag option is so + // that we can get pitch results incrementally from process; we + // don't get that outcome here, but we do benefit from its bounded + // memory usage, which can be quite a big deal. So if the caller + // asked for it there, we use it here too. (It is a bit slower, + // but not much.) + + MonoNote mn(m_fixedLag > 0.5f); vector mnOut = mn.process(smoothedPitch); std::cerr << "mnOut size: " << mnOut.size() << std::endl; diff -r b83e6fbe22cc -r 729cc1da9b8d test/TestMonoNote.cpp --- a/test/TestMonoNote.cpp Wed May 17 15:55:37 2017 +0100 +++ b/test/TestMonoNote.cpp Wed May 17 16:29:43 2017 +0100 @@ -14,7 +14,7 @@ BOOST_AUTO_TEST_CASE(instantiate) { - MonoNote mn; + MonoNote mn(false); vector > > pitchProb; size_t n = 8;