changeset 321:213a51e197c8 livemode

Shorten duration threshold for live mode; return non-peak-picked pitch distribution from pitch distribution output
author Chris Cannam
date Wed, 29 Apr 2015 10:12:02 +0100
parents 7f9683c8de69
children 7dda913d820b
files src/Silvet.cpp src/Silvet.h
diffstat 2 files changed, 35 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/src/Silvet.cpp	Wed Apr 29 09:51:09 2015 +0100
+++ b/src/Silvet.cpp	Wed Apr 29 10:12:02 2015 +0100
@@ -710,10 +710,12 @@
         
     for (int i = 0; i < width; ++i) {
 
-        // This returns a filtered column, and pushes the
-        // up-to-max-polyphony activation column to m_pianoRoll
-        vector<double> filtered = postProcess
-            (localPitches[i], localBestShifts[i], wantShifts);
+        vector<double> filtered;
+
+        for (int j = 0; j < pack.templateNoteCount; ++j) {
+            m_postFilter[j]->push(localPitches[i][j]);
+            filtered.push_back(m_postFilter[j]->get());
+        }
 
         RealTime timestamp = getColumnTimestamp(m_pianoRoll.size() - 1);
         float inputGain = getInputGainAt(timestamp);
@@ -733,6 +735,10 @@
         }
         fs[m_chromaOutputNo].push_back(f);
 
+        // This pushes the up-to-max-polyphony activation column to
+        // m_pianoRoll
+        postProcess(localPitches[i], localBestShifts[i], wantShifts);
+
         auto events = noteTrack(shiftCount);
 
         FeatureList noteFeatures = events.first;
@@ -896,37 +902,13 @@
     return out;
 }
     
-vector<double>
+void
 Silvet::postProcess(const vector<double> &pitches,
                     const vector<int> &bestShifts,
                     bool wantShifts)
 {
     const InstrumentPack &pack(getPack(m_instrument));
 
-    vector<double> filtered;
-
-    for (int j = 0; j < pack.templateNoteCount; ++j) {
-        m_postFilter[j]->push(pitches[j]);
-        filtered.push_back(m_postFilter[j]->get());
-    }
-
-    if (m_mode == LiveMode) {
-        // In live mode with only a 12-bpo CQ, we are very likely to
-        // get clusters of two or three high scores at a time for
-        // neighbouring semitones. Eliminate these by picking only the
-        // peaks. This means we can't recognise actual semitone chords
-        // if they ever appear, but it's not as if live mode is good
-        // enough for that to be a big deal anyway.
-        for (int j = 0; j < pack.templateNoteCount; ++j) {
-            if (j > 0 && j + 1 < pack.templateNoteCount &&
-                filtered[j] >= filtered[j-1] &&
-                filtered[j] >= filtered[j+1]) {
-            } else {
-                filtered[j] = 0.0;
-            }
-        }
-    }
-
     // Threshold for level and reduce number of candidate pitches
 
     typedef std::multimap<double, int> ValueIndexMap;
@@ -934,8 +916,24 @@
     ValueIndexMap strengths;
 
     for (int j = 0; j < pack.templateNoteCount; ++j) {
-        double strength = filtered[j];
+
+        double strength = pitches[j];
         if (strength < pack.levelThreshold) continue;
+        
+        // In live mode with only a 12-bpo CQ, we are very likely to
+        // get clusters of two or three high scores at a time for
+        // neighbouring semitones. Eliminate these by picking only the
+        // peaks. This means we can't recognise actual semitone chords
+        // if they ever appear, but it's not as if live mode is good
+        // enough for that to be a big deal anyway.
+        if (m_mode == LiveMode) {
+            if (j == 0 || j + 1 == pack.templateNoteCount ||
+                pitches[j] < pitches[j-1] ||
+                pitches[j] < pitches[j+1]) {
+                continue;
+            }
+        }
+        
         strengths.insert(ValueIndexMap::value_type(strength, j));
     }
 
@@ -964,7 +962,7 @@
         m_pianoRollShifts.push_back(activeShifts);
     }
 
-    return filtered;
+    return;
 }
 
 pair<Vamp::Plugin::FeatureList, Vamp::Plugin::FeatureList>
@@ -984,7 +982,9 @@
     double columnDuration = 1.0 / m_colsPerSec;
 
     // only keep notes >= 100ms or thereabouts
-    int durationThreshold = floor(0.1 / columnDuration); // columns
+    double durationThreshSec = 0.1;
+    if (m_mode == LiveMode) durationThreshSec = 0.07;
+    int durationThreshold = floor(durationThreshSec / columnDuration); // in cols
     if (durationThreshold < 1) durationThreshold = 1;
 
     FeatureList noteFeatures, onsetFeatures;
--- a/src/Silvet.h	Wed Apr 29 09:51:09 2015 +0100
+++ b/src/Silvet.h	Wed Apr 29 10:12:02 2015 +0100
@@ -112,9 +112,9 @@
                                                     const vector<double> &column,
                                                     bool wantShifts);
     
-    vector<double> postProcess(const vector<double> &pitches,
-                               const vector<int> &bestShifts,
-                               bool wantShifts); // -> piano roll column
+    void postProcess(const vector<double> &pitches,
+                     const vector<int> &bestShifts,
+                     bool wantShifts); // -> piano roll column
 
     std::pair<FeatureList, FeatureList> noteTrack(int shiftCount); // notes, onsets