diff src/Silvet.cpp @ 55:384338fa460d preshift

Support shifts as an additional dimension (as in the original model). Also return velocity as well.
author Chris Cannam
date Tue, 08 Apr 2014 13:30:32 +0100
parents 22553e7b2a63
children 49c0a139f165
line wrap: on
line diff
--- a/src/Silvet.cpp	Mon Apr 07 17:36:40 2014 +0100
+++ b/src/Silvet.cpp	Tue Apr 08 13:30:32 2014 +0100
@@ -17,6 +17,7 @@
 #include "EM.h"
 
 #include "maths/MedianFilter.h"
+#include "maths/MathUtilities.h"
 #include "dsp/rateconversion/Resampler.h"
 
 #include "constant-q-cpp/cpp-qm-dsp/CQInterpolated.h"
@@ -35,8 +36,6 @@
 static int processingBPO = 60;
 static int processingHeight = 545;
 static int processingNotes = 88;
-static int processingShifts = 5;
-static int processingPitches = processingNotes * processingShifts;
 
 Silvet::Silvet(float inputSampleRate) :
     Plugin(inputSampleRate),
@@ -235,9 +234,9 @@
     d.description = "Estimated pitch activation matrix";
     d.unit = "";
     d.hasFixedBinCount = true;
-    d.binCount = processingPitches;
+    d.binCount = processingNotes;
     d.binNames.clear();
-    for (int i = 0; i < processingPitches; ++i) {
+    for (int i = 0; i < processingNotes; ++i) {
         d.binNames.push_back(noteName(i));
     }
     d.hasKnownExtents = false;
@@ -404,12 +403,12 @@
 
         vector<double> pitches = em.getPitchDistribution();
         
-        for (int j = 0; j < processingPitches; ++j) {
+        for (int j = 0; j < processingNotes; ++j) {
             pitches[j] *= sum;
         }
 
         Feature f;
-        for (int j = 0; j < processingPitches; ++j) {
+        for (int j = 0; j < processingNotes; ++j) {
             f.values.push_back(float(pitches[j]));
         }
         fs[m_pitchOutputNo].push_back(f);
@@ -504,12 +503,7 @@
     vector<double> filtered;
 
     for (int j = 0; j < processingNotes; ++j) {
-        double noteSum = 0.0;
-        for (int s = 0; s < processingShifts; ++s) {
-            double val = pitches[j * processingShifts + s];
-            noteSum += val;
-        }
-        m_postFilter[j]->push(noteSum);
+        m_postFilter[j]->push(pitches[j]);
         filtered.push_back(m_postFilter[j]->get());
     }
 
@@ -525,13 +519,13 @@
         strengths.insert(ValueIndexMap::value_type(filtered[j], j));
     }
 
-    set<int> active;
+    map<int, double> active;
     ValueIndexMap::const_iterator si = strengths.end();
     while (int(active.size()) < polyphony) {
         --si;
         if (si->first < threshold) break;
         cerr << si->second << " : " << si->first << endl;
-        active.insert(si->second);
+        active[si->second] = si->first;
         if (si == strengths.begin()) break;
     }
 
@@ -556,10 +550,10 @@
     // we have 25 columns per second
     double columnDuration = 1.0 / 25.0;
     
-    for (set<int>::const_iterator ni = m_pianoRoll[width-1].begin();
+    for (map<int, double>::const_iterator ni = m_pianoRoll[width-1].begin();
          ni != m_pianoRoll[width-1].end(); ++ni) {
 
-        int note = *ni;
+        int note = ni->first;
         
         if (active.find(note) != active.end()) {
             // the note is still playing
@@ -570,7 +564,10 @@
         int end = width;
         int start = end-1;
 
+        vector<double> strengths;
+
         while (m_pianoRoll[start].find(note) != m_pianoRoll[start].end()) {
+            strengths.push_back(m_pianoRoll[start][note]);
             --start;
         }
         ++start;
@@ -582,13 +579,18 @@
             continue;
         }
 
+        double medianStrength = MathUtilities::median
+            (strengths.data(), strengths.size());
+        int velocity = medianStrength * 2;
+        if (velocity > 127) velocity = 127;
+
         Feature nf;
         nf.hasTimestamp = true;
         nf.timestamp = RealTime::fromSeconds(columnDuration * start);
         nf.hasDuration = true;
         nf.duration = RealTime::fromSeconds(columnDuration * duration);
         nf.values.push_back(noteFrequency(note));
-        nf.values.push_back(80.f); //!!! todo: calculate velocity
+        nf.values.push_back(velocity);
         nf.label = noteName(note);
         noteFeatures.push_back(nf);
     }