changeset 43:ae21806fe84b tony

merge -- Chris can you check whether this still does what you'd expect it to do?
author matthiasm
date Thu, 30 Jan 2014 18:25:28 +0000
parents 34820224da74 (current diff) ce38afe240a1 (diff)
children e5ccda2c06d9
files LocalCandidatePYIN.cpp
diffstat 3 files changed, 54 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Thu Jan 30 18:25:28 2014 +0000
@@ -0,0 +1,3 @@
+syntax: glob
+*.o
+*.so
--- a/LocalCandidatePYIN.cpp	Tue Jan 28 10:21:34 2014 +0000
+++ b/LocalCandidatePYIN.cpp	Thu Jan 30 18:25:28 2014 +0000
@@ -25,9 +25,11 @@
 // #include <iostream>
 #include <cmath>
 #include <complex>
+#include <map>
 
 using std::string;
 using std::vector;
+using std::map;
 using Vamp::RealTime;
 
 
@@ -221,17 +223,15 @@
     d.name = "Pitch track candidates";
     d.description = "Multiple candidate pitch tracks.";
     d.unit = "Hz";
-    d.hasFixedBinCount = true;
-    d.binCount = m_nCandidate;
+    d.hasFixedBinCount = false;
     d.hasKnownExtents = true;
     d.minValue = m_fmin;
-    d.maxValue = 500;
+    d.maxValue = 500; //!!!???
     d.isQuantized = false;
     d.sampleType = OutputDescriptor::FixedSampleRate;
     d.sampleRate = (m_inputSampleRate / m_stepSize);
     d.hasDuration = false;
     outputs.push_back(d);
-    // m_oPitchTrackCandidates = outputNumber++;
 
     return outputs;
 }
@@ -279,7 +279,6 @@
 LocalCandidatePYIN::process(const float *const *inputBuffers, RealTime timestamp)
 {
     timestamp = timestamp + Vamp::RealTime::frame2RealTime(m_blockSize/4, lrintf(m_inputSampleRate));
-    FeatureSet fs;
     
     double *dInputBuffers = new double[m_blockSize];
     for (size_t i = 0; i < m_blockSize; ++i) dInputBuffers[i] = inputBuffers[0][i];
@@ -318,22 +317,19 @@
     }
     m_timestamp.push_back(timestamp);
 
-    return fs;
+    return FeatureSet();
 }
 
 LocalCandidatePYIN::FeatureSet
 LocalCandidatePYIN::getRemainingFeatures()
 {
-    FeatureSet fs;
-    Feature f;
-    f.hasTimestamp = true;
-    f.hasDuration = false;
-    f.values.push_back(0);
+    // timestamp -> candidate number -> value
+    map<RealTime, map<int, float> > featureValues;
 
     // std::cerr << "in remaining features" << std::endl;
 
     if (m_pitchProb.empty()) {
-        return fs;
+        return FeatureSet();
     }
 
     // MONO-PITCH STUFF
@@ -380,7 +376,10 @@
     }
 
     // now find non-duplicate pitch tracks
-    vector<size_t> actualCandidates;
+    map<int, int> candidateActuals;
+    map<int, std::string> candidateLabels;
+
+    int actualCandidateNumber = 0;
     for (size_t iCandidate = 0; iCandidate < m_nCandidate; ++iCandidate) {
         bool isDuplicate = false;
         for (size_t i = 0; i < duplicates.size(); ++i) {
@@ -390,34 +389,48 @@
                 break;
             }
         }
-        if (!isDuplicate && (freqNumber[iCandidate] > 0.5*nFrame)) {
-            actualCandidates.push_back(iCandidate);
-            // std::cerr << iCandidate << std::endl;
+        if (!isDuplicate && freqNumber[iCandidate] > 0.8*nFrame)
+        {
+            std::ostringstream convert;
+            convert << actualCandidateNumber++;
+            candidateLabels[iCandidate] = convert.str();
+            candidateActuals[iCandidate] = actualCandidateNumber;
+            std::cerr << freqNumber[iCandidate] << " " << freqMean[iCandidate] << std::endl;
+            for (size_t iFrame = 0; iFrame < nFrame; ++iFrame) 
+            {
+                if (pitchTracks[iCandidate][iFrame] > 0)
+                {
+                    featureValues[m_timestamp[iFrame]][iCandidate] = 
+                        pitchTracks[iCandidate][iFrame];
+                }
+            }
         }
+        // fs[m_oPitchTrackCandidates].push_back(f);
     }
 
-    // finally write them out
-    for (size_t iFrame = 0; iFrame < nFrame; ++iFrame) 
-    {
-        f.timestamp = m_timestamp[iFrame];
-        f.values.clear();
-        for (size_t iCandidate = 0; iCandidate < actualCandidates.size(); ++iCandidate) {
-            // std::ostringstream convert;
-            // convert << actualCandidateNumber++;
-            // f.label = convert.str();
-            // std::cerr << freqNumber[iCandidate] << " " << freqMean[iCandidate] << std::endl;
-            if (pitchTracks[actualCandidates[iCandidate]][iFrame] > 0)
-            {
-                f.values.push_back(pitchTracks[actualCandidates[iCandidate]][iFrame]);
-            } else {
+    // adapt our features so as to return a stack of candidate values
+    // per frame
+
+    FeatureSet fs;
+
+    for (map<RealTime, map<int, float> >::const_iterator i =
+             featureValues.begin(); i != featureValues.end(); ++i) {
+        Feature f;
+        f.hasTimestamp = true;
+        f.timestamp = i->first;
+        int nextCandidate = candidateActuals.begin()->second;
+        for (map<int, float>::const_iterator j = 
+                 i->second.begin(); j != i->second.end(); ++j) {
+            while (candidateActuals[j->first] > nextCandidate) {
                 f.values.push_back(0);
+                ++nextCandidate;
             }
+            f.values.push_back(j->second);
+            nextCandidate = j->first + 1;
         }
-        fs[m_oPitchTrackCandidates].push_back(f);
-        // std::cerr << freqNumber[iCandidate] << " " << (freqSum[iCandidate]*1.0/freqNumber[iCandidate]) << std::endl;
+        //!!! can't use labels?
+        fs[0].push_back(f);
     }
 
-    // only retain those that are close to their means
-
     return fs;
 }
--- a/SparseHMM.cpp	Tue Jan 28 10:21:34 2014 +0000
+++ b/SparseHMM.cpp	Thu Jan 30 18:25:28 2014 +0000
@@ -30,6 +30,10 @@
 SparseHMM::decodeViterbi(std::vector<vector<double> > obsProb,
                          vector<double> *scale) 
 {
+    if (obsProb.size() < 1) {
+        return vector<int>();
+    }
+
     size_t nState = init.size();
     size_t nFrame = obsProb.size();