changeset 16:4c8526c5bf58

Implement features outputs
author Chris Cannam
date Fri, 10 Oct 2014 13:16:54 +0100
parents a82276091bbd
children 27f418d77095
files MatchVampPlugin.cpp MatchVampPlugin.h Matcher.cpp Matcher.h
diffstat 4 files changed, 85 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/MatchVampPlugin.cpp	Fri Oct 10 12:55:05 2014 +0100
+++ b/MatchVampPlugin.cpp	Fri Oct 10 13:16:54 2014 +0100
@@ -49,9 +49,9 @@
 
 MatchVampPlugin::MatchVampPlugin(float inputSampleRate) :
     Plugin(inputSampleRate),
-    m_stepSize(0),
+    m_stepSize(inputSampleRate * defaultStepTime + 0.001),
     m_stepTime(defaultStepTime),
-    m_blockSize(0),
+    m_blockSize(2048),
     m_serialise(false),
     m_begin(true),
     m_locked(false)
@@ -252,6 +252,7 @@
     desc.quantizeStep = 1;
     desc.sampleType = OutputDescriptor::VariableSampleRate;
     desc.sampleRate = outRate;
+    m_pathOutNo = list.size();
     list.push_back(desc);
 
     desc.identifier = "a_b";
@@ -264,6 +265,7 @@
     desc.isQuantized = false;
     desc.sampleType = OutputDescriptor::VariableSampleRate;
     desc.sampleRate = outRate;
+    m_abOutNo = list.size();
     list.push_back(desc);
 
     desc.identifier = "b_a";
@@ -276,6 +278,7 @@
     desc.isQuantized = false;
     desc.sampleType = OutputDescriptor::VariableSampleRate;
     desc.sampleRate = outRate;
+    m_baOutNo = list.size();
     list.push_back(desc);
 
     desc.identifier = "a_b_divergence";
@@ -288,6 +291,7 @@
     desc.isQuantized = false;
     desc.sampleType = OutputDescriptor::VariableSampleRate;
     desc.sampleRate = outRate;
+    m_abDivOutNo = list.size();
     list.push_back(desc);
 
     desc.identifier = "a_b_temporatio";
@@ -300,18 +304,35 @@
     desc.isQuantized = false;
     desc.sampleType = OutputDescriptor::VariableSampleRate;
     desc.sampleRate = outRate;
+    m_abRatioOutNo = list.size();
     list.push_back(desc);
 
+    Matcher::Parameters params(m_inputSampleRate, m_stepTime, m_blockSize);
+
     desc.identifier = "a_features";
     desc.name = "A Features";
     desc.description = "Spectral features extracted from performance A";
     desc.unit = "";
     desc.hasFixedBinCount = true;
-    desc.binCount = 1;
+    desc.binCount = Matcher::getFeatureSize(params);
     desc.hasKnownExtents = false;
     desc.isQuantized = false;
-    desc.sampleType = OutputDescriptor::VariableSampleRate;
+    desc.sampleType = OutputDescriptor::FixedSampleRate;
     desc.sampleRate = outRate;
+    m_aFeaturesOutNo = list.size();
+    list.push_back(desc);
+
+    desc.identifier = "b_features";
+    desc.name = "B Features";
+    desc.description = "Spectral features extracted from performance B";
+    desc.unit = "";
+    desc.hasFixedBinCount = true;
+    desc.binCount = Matcher::getFeatureSize(params);
+    desc.hasKnownExtents = false;
+    desc.isQuantized = false;
+    desc.sampleType = OutputDescriptor::FixedSampleRate;
+    desc.sampleRate = outRate;
+    m_bFeaturesOutNo = list.size();
     list.push_back(desc);
 
     return list;
@@ -336,12 +357,33 @@
     
 //    std::cerr << timestamp.toString();
 
-    feeder->feed(inputBuffers);
+    MatchFeeder::Features ff = feeder->feedAndGetFeatures(inputBuffers);
+
+    FeatureSet returnFeatures;
+
+    Feature f;
+    f.hasTimestamp = false;
+
+    for (int i = 0; i < (int)ff.f1.size(); ++i) {
+        f.values.clear();
+        for (int j = 0; j < (int)ff.f1[i].size(); ++j) {
+            f.values.push_back(ff.f1[i][j]);
+        }
+        returnFeatures[m_aFeaturesOutNo].push_back(f);
+    }
+
+    for (int i = 0; i < (int)ff.f2.size(); ++i) {
+        f.values.clear();
+        for (int j = 0; j < (int)ff.f2[i].size(); ++j) {
+            f.values.push_back(ff.f2[i][j]);
+        }
+        returnFeatures[m_bFeaturesOutNo].push_back(f);
+    }
 
 //    std::cerr << ".";
 //    std::cerr << std::endl;
 
-    return FeatureSet();
+    return returnFeatures;
 }
 
 MatchVampPlugin::FeatureSet
@@ -364,7 +406,7 @@
 
 //        std::cerr << pathx.size() << ": (" << x << "," << y << ")" << std::endl;
 
-        switch (finder->getDistance() & ADVANCE_BOTH){
+        switch (finder->getDistance() & ADVANCE_BOTH) {
         case ADVANCE_THIS:  y--; break;
         case ADVANCE_OTHER: x--; break;
         case ADVANCE_BOTH:  x--; y--; break;
@@ -399,7 +441,7 @@
         feature.timestamp = m_startTime + xt;
         feature.values.clear();
         feature.values.push_back(yt.sec + double(yt.nsec)/1.0e9);
-        returnFeatures[0].push_back(feature);
+        returnFeatures[m_pathOutNo].push_back(feature);
         
         if (x != prevx) {
 
@@ -407,12 +449,12 @@
             feature.timestamp = m_startTime + xt;
             feature.values.clear();
             feature.values.push_back(yt.sec + yt.msec()/1000.0);
-            returnFeatures[1].push_back(feature);
+            returnFeatures[m_abOutNo].push_back(feature);
 
             Vamp::RealTime diff = yt - xt;
             feature.values.clear();
             feature.values.push_back(diff.sec + diff.msec()/1000.0);
-            returnFeatures[3].push_back(feature);
+            returnFeatures[m_abDivOutNo].push_back(feature);
 
             if (i > 0) {
                 int lookback = 100; //!!! arbitrary
@@ -424,7 +466,7 @@
                     if (ratio < 8 && ratio > (1.0/8)) { //!!! just for now, since we aren't dealing properly with silence yet
                         feature.values.clear();
                         feature.values.push_back(ratio);
-                        returnFeatures[4].push_back(feature);
+                        returnFeatures[m_abRatioOutNo].push_back(feature);
                     }
                 }
             }
@@ -435,7 +477,7 @@
             feature.timestamp = m_startTime + yt;
             feature.values.clear();
             feature.values.push_back(xt.sec + xt.msec()/1000.0);
-            returnFeatures[2].push_back(feature);
+            returnFeatures[m_baOutNo].push_back(feature);
         }
 
         prevx = x;
--- a/MatchVampPlugin.h	Fri Oct 10 12:55:05 2014 +0100
+++ b/MatchVampPlugin.h	Fri Oct 10 13:16:54 2014 +0100
@@ -65,9 +65,11 @@
 
 protected:
     void createMatchers() const;
+
     mutable Matcher *pm1;
     mutable Matcher *pm2;
     mutable MatchFeeder *feeder;
+
     Vamp::RealTime m_startTime;
     int m_stepSize;
     float m_stepTime;
@@ -76,6 +78,14 @@
     bool m_begin;
     bool m_locked;
 
+    mutable int m_pathOutNo;
+    mutable int m_abOutNo;
+    mutable int m_baOutNo;
+    mutable int m_abDivOutNo;
+    mutable int m_abRatioOutNo;
+    mutable int m_aFeaturesOutNo;
+    mutable int m_bFeaturesOutNo;
+
 #ifdef _WIN32
     static HANDLE m_serialisingMutex;
 #else 
--- a/Matcher.cpp	Fri Oct 10 12:55:05 2014 +0100
+++ b/Matcher.cpp	Fri Oct 10 13:16:54 2014 +0100
@@ -19,6 +19,7 @@
 #include <iostream>
 
 #include <cstdlib>
+#include <cassert>
 
 bool Matcher::silent = true;
 
@@ -84,6 +85,8 @@
 
     initialised = true;
 
+    freqMapSize = getFeatureSize(params);
+
     makeFreqMap();
 
     initVector<double>(prevFrame, freqMapSize);
@@ -136,6 +139,16 @@
     }
 } // makeFreqMap()
 
+int
+Matcher::getFeatureSize(Parameters params)
+{
+    if (params.useChromaFrequencyMap) {
+        return 13;
+    } else {
+        return 84;
+    }
+}
+
 void
 Matcher::makeStandardFrequencyMap()
 {
@@ -151,11 +164,10 @@
     }
     while (i <= params.fftSize/2) {
         double midi = log(i*binWidth/440.0) / log(2.0) * 12 + 69;
-        if (midi > 127)
-            midi = 127;
+        if (midi > 127) midi = 127;
         freqMap[i++] = crossoverBin + lrint(midi) - crossoverMidi;
     }
-    freqMapSize = freqMap[i-1] + 1;
+    assert(freqMapSize == freqMap[i-1] + 1);
     if (!silent) {
         cerr << "Standard map size: " << freqMapSize 
              << ";  Crossover at: " << crossoverBin << endl;
@@ -177,7 +189,6 @@
         double midi = log(i*binWidth/440.0) / log(2.0) * 12 + 69;
         freqMap[i++] = (lrint(midi)) % 12 + 1;
     }
-    freqMapSize = 13;
     if (!silent) {
         cerr << "Chroma map size: " << freqMapSize 
              << ";  Crossover at: " << crossoverBin << endl;
--- a/Matcher.h	Fri Oct 10 12:55:05 2014 +0100
+++ b/Matcher.h	Fri Oct 10 13:16:54 2014 +0100
@@ -247,9 +247,6 @@
      */
     void print();
 
-    /** Gives some basic `header' information about the Matcher. */
-    string toString();
-
     /** Adds a link to the Matcher object representing the performance
      *  which is going to be matched to this one.
      *
@@ -263,6 +260,12 @@
         return frameCount;
     }
 
+    /**
+     * Return the feature vector size that will be used for the given
+     * parameters.
+     */
+    static int getFeatureSize(Parameters params);
+
 protected:
     template <typename T>
     void initVector(vector<T> &vec, int sz, T dflt = 0) {