diff CepstralPitchTracker.cpp @ 35:2f5b169e4a3b

Integrate NoteHypothesis class, build fixes
author Chris Cannam
date Thu, 19 Jul 2012 13:46:45 +0100
parents 2c175adf8736
children 822cf7b8e070
line wrap: on
line diff
--- a/CepstralPitchTracker.cpp	Fri Jul 13 22:48:02 2012 +0100
+++ b/CepstralPitchTracker.cpp	Thu Jul 19 13:46:45 2012 +0100
@@ -37,161 +37,6 @@
 using std::vector;
 using Vamp::RealTime;
 
-CepstralPitchTracker::Hypothesis::Hypothesis()
-{
-    m_state = New;
-}
-
-CepstralPitchTracker::Hypothesis::~Hypothesis()
-{
-}
-
-bool
-CepstralPitchTracker::Hypothesis::isWithinTolerance(Estimate s) const
-{
-    if (m_pending.empty()) {
-        return true;
-    }
-
-    // check we are within a relatively close tolerance of the last
-    // candidate
-    Estimate last = m_pending[m_pending.size()-1];
-    double r = s.freq / last.freq;
-    int cents = lrint(1200.0 * (log(r) / log(2.0)));
-    if (cents < -60 || cents > 60) return false;
-
-    // and within a slightly bigger tolerance of the current mean
-    double meanFreq = getMeanFrequency();
-    r = s.freq / meanFreq;
-    cents = lrint(1200.0 * (log(r) / log(2.0)));
-    if (cents < -80 || cents > 80) return false;
-    
-    return true;
-}
-
-bool
-CepstralPitchTracker::Hypothesis::isOutOfDateFor(Estimate s) const
-{
-    if (m_pending.empty()) return false;
-
-    return ((s.time - m_pending[m_pending.size()-1].time) > 
-            RealTime::fromMilliseconds(40));
-}
-
-bool 
-CepstralPitchTracker::Hypothesis::isSatisfied() const
-{
-    if (m_pending.empty()) return false;
-    
-    double meanConfidence = 0.0;
-    for (int i = 0; i < m_pending.size(); ++i) {
-        meanConfidence += m_pending[i].confidence;
-    }
-    meanConfidence /= m_pending.size();
-
-    int lengthRequired = 10000;
-    if (meanConfidence > 0.0) {
-        lengthRequired = int(2.0 / meanConfidence + 0.5);
-    }
-
-    return (m_pending.size() > lengthRequired);
-}
-
-bool
-CepstralPitchTracker::Hypothesis::accept(Estimate s)
-{
-    bool accept = false;
-
-    switch (m_state) {
-
-    case New:
-        m_state = Provisional;
-        accept = true;
-        break;
-
-    case Provisional:
-        if (isOutOfDateFor(s)) {
-            m_state = Rejected;
-        } else if (isWithinTolerance(s)) {
-            accept = true;
-        }
-        break;
-        
-    case Satisfied:
-        if (isOutOfDateFor(s)) {
-            m_state = Expired;
-        } else if (isWithinTolerance(s)) {
-            accept = true;
-        }
-        break;
-
-    case Rejected:
-        break;
-
-    case Expired:
-        break;
-    }
-
-    if (accept) {
-        m_pending.push_back(s);
-        if (m_state == Provisional && isSatisfied()) {
-            m_state = Satisfied;
-        }
-    }
-
-    return accept;
-}        
-
-CepstralPitchTracker::Hypothesis::State
-CepstralPitchTracker::Hypothesis::getState() const
-{
-    return m_state;
-}
-
-CepstralPitchTracker::Hypothesis::Estimates
-CepstralPitchTracker::Hypothesis::getAcceptedEstimates() const
-{
-    if (m_state == Satisfied || m_state == Expired) {
-        return m_pending;
-    } else {
-        return Estimates();
-    }
-}
-
-double
-CepstralPitchTracker::Hypothesis::getMeanFrequency() const
-{
-    double acc = 0.0;
-    for (int i = 0; i < m_pending.size(); ++i) {
-        acc += m_pending[i].freq;
-    }
-    acc /= m_pending.size();
-    return acc;
-}
-
-CepstralPitchTracker::Hypothesis::Note
-CepstralPitchTracker::Hypothesis::getAveragedNote() const
-{
-    Note n;
-
-    if (!(m_state == Satisfied || m_state == Expired)) {
-        n.freq = 0.0;
-        n.time = RealTime::zeroTime;
-        n.duration = RealTime::zeroTime;
-        return n;
-    }
-
-    n.time = m_pending.begin()->time;
-
-    Estimates::const_iterator i = m_pending.end();
-    --i;
-    n.duration = i->time - n.time;
-
-    // just mean frequency for now, but this isn't at all right perceptually
-    n.freq = getMeanFrequency();
-    
-    return n;
-}
 
 CepstralPitchTracker::CepstralPitchTracker(float inputSampleRate) :
     Plugin(inputSampleRate),
@@ -320,8 +165,6 @@
 {
     OutputList outputs;
 
-    int n = 0;
-
     OutputDescriptor d;
 
     d.identifier = "f0";
@@ -391,11 +234,11 @@
 }
 
 void
-CepstralPitchTracker::addFeaturesFrom(Hypothesis h, FeatureSet &fs)
+CepstralPitchTracker::addFeaturesFrom(NoteHypothesis h, FeatureSet &fs)
 {
-    Hypothesis::Estimates es = h.getAcceptedEstimates();
+    NoteHypothesis::Estimates es = h.getAcceptedEstimates();
 
-    for (int i = 0; i < es.size(); ++i) {
+    for (int i = 0; i < (int)es.size(); ++i) {
 	Feature f;
 	f.hasTimestamp = true;
 	f.timestamp = es[i].time;
@@ -406,7 +249,7 @@
     Feature nf;
     nf.hasTimestamp = true;
     nf.hasDuration = true;
-    Hypothesis::Note n = h.getAveragedNote();
+    NoteHypothesis::Note n = h.getAveragedNote();
     nf.timestamp = n.time;
     nf.duration = n.duration;
     nf.values.push_back(n.freq);
@@ -422,7 +265,7 @@
         // average according to the vertical filter length
         for (int j = -m_vflen/2; j <= m_vflen/2; ++j) {
             int ix = i + m_binFrom + j;
-            if (ix >= 0 && ix < m_blockSize) {
+            if (ix >= 0 && ix < (int)m_blockSize) {
                 v += cep[ix];
                 ++n;
             }
@@ -575,24 +418,19 @@
         std::cerr << "magmean = " << magmean << ", confidence = " << confidence << std::endl;
     }
 
-    Hypothesis::Estimate e;
+    NoteHypothesis::Estimate e;
     e.freq = peakfreq;
     e.time = timestamp;
     e.confidence = confidence;
 
-//    m_good.advanceTime();
-    for (int i = 0; i < m_possible.size(); ++i) {
-//        m_possible[i].advanceTime();
-    }
-
     if (!m_good.accept(e)) {
 
         int candidate = -1;
         bool accepted = false;
 
-        for (int i = 0; i < m_possible.size(); ++i) {
+        for (int i = 0; i < (int)m_possible.size(); ++i) {
             if (m_possible[i].accept(e)) {
-                if (m_possible[i].getState() == Hypothesis::Satisfied) {
+                if (m_possible[i].getState() == NoteHypothesis::Satisfied) {
                     accepted = true;
                     candidate = i;
                 }
@@ -601,31 +439,31 @@
         }
 
         if (!accepted) {
-            Hypothesis h;
+            NoteHypothesis h;
             h.accept(e); //!!! must succeed as h is new, so perhaps there should be a ctor for this
             m_possible.push_back(h);
         }
 
-        if (m_good.getState() == Hypothesis::Expired) {
+        if (m_good.getState() == NoteHypothesis::Expired) {
             addFeaturesFrom(m_good, fs);
         }
         
-        if (m_good.getState() == Hypothesis::Expired ||
-            m_good.getState() == Hypothesis::Rejected) {
+        if (m_good.getState() == NoteHypothesis::Expired ||
+            m_good.getState() == NoteHypothesis::Rejected) {
             if (candidate >= 0) {
                 m_good = m_possible[candidate];
             } else {
-                m_good = Hypothesis();
+                m_good = NoteHypothesis();
             }
         }
 
         // reap rejected/expired hypotheses from possible list
         Hypotheses toReap = m_possible;
         m_possible.clear();
-        for (int i = 0; i < toReap.size(); ++i) {
-            Hypothesis h = toReap[i];
-            if (h.getState() != Hypothesis::Rejected && 
-                h.getState() != Hypothesis::Expired) {
+        for (int i = 0; i < (int)toReap.size(); ++i) {
+            NoteHypothesis h = toReap[i];
+            if (h.getState() != NoteHypothesis::Rejected && 
+                h.getState() != NoteHypothesis::Expired) {
                 m_possible.push_back(h);
             }
         }
@@ -639,7 +477,7 @@
 CepstralPitchTracker::getRemainingFeatures()
 {
     FeatureSet fs;
-    if (m_good.getState() == Hypothesis::Satisfied) {
+    if (m_good.getState() == NoteHypothesis::Satisfied) {
         addFeaturesFrom(m_good, fs);
     }
     return fs;