* Add hasDuration to output descriptors
[vamp-aubio-plugins.git] / plugins / Notes.cpp
index eb68cee..11a73c2 100644 (file)
@@ -4,7 +4,7 @@
     Vamp feature extraction plugins using Paul Brossier's Aubio library.
 
     Centre for Digital Music, Queen Mary, University of London.
     Vamp feature extraction plugins using Paul Brossier's Aubio library.
 
     Centre for Digital Music, Queen Mary, University of London.
-    This file copyright 2006 Chris Cannam.
+    This file copyright 2006-2008 Chris Cannam and QMUL.
     
     This program is free software; you can redistribute it and/or
     modify it under the terms of the GNU General Public License as
     
     This program is free software; you can redistribute it and/or
     modify it under the terms of the GNU General Public License as
@@ -22,8 +22,9 @@ using std::vector;
 using std::cerr;
 using std::endl;
 
 using std::cerr;
 using std::endl;
 
-Notes::Notes(float inputSampleRate) :
+Notes::Notes(float inputSampleRate, unsigned int apiVersion) :
     Plugin(inputSampleRate),
     Plugin(inputSampleRate),
+    m_apiVersion(apiVersion),
     m_ibuf(0),
     m_fftgrain(0),
     m_onset(0),
     m_ibuf(0),
     m_fftgrain(0),
     m_onset(0),
@@ -43,6 +44,12 @@ Notes::Notes(float inputSampleRate) :
     m_avoidLeaps(false),
     m_prevPitch(-1)
 {
     m_avoidLeaps(false),
     m_prevPitch(-1)
 {
+    if (apiVersion == 1) {
+        cerr << "vamp-aubio: WARNING: using compatibility version 1 of the Vamp API for note\n"
+             << "tracker plugin: upgrade your host to v2 for proper duration support" << endl;
+    } else {
+        cerr << "vamp-aubio: NOTE: using v2 API for true durations" << endl;
+    }
 }
 
 Notes::~Notes()
 }
 
 Notes::~Notes()
@@ -57,18 +64,24 @@ Notes::~Notes()
 }
 
 string
 }
 
 string
-Notes::getName() const
+Notes::getIdentifier() const
 {
     return "aubionotes";
 }
 
 string
 {
     return "aubionotes";
 }
 
 string
-Notes::getDescription() const
+Notes::getName() const
 {
     return "Aubio Note Tracker";
 }
 
 string
 {
     return "Aubio Note Tracker";
 }
 
 string
+Notes::getDescription() const
+{
+    return "Estimate note onset positions, pitches and durations";
+}
+
+string
 Notes::getMaker() const
 {
     return "Paul Brossier (plugin by Chris Cannam)";
 Notes::getMaker() const
 {
     return "Paul Brossier (plugin by Chris Cannam)";
@@ -77,7 +90,8 @@ Notes::getMaker() const
 int
 Notes::getPluginVersion() const
 {
 int
 Notes::getPluginVersion() const
 {
-    return 1;
+    if (m_apiVersion == 1) return 2;
+    return 3;
 }
 
 string
 }
 
 string
@@ -149,8 +163,8 @@ Notes::getParameterDescriptors() const
     ParameterList list;
     
     ParameterDescriptor desc;
     ParameterList list;
     
     ParameterDescriptor desc;
-    desc.name = "onsettype";
-    desc.description = "Onset Detection Function Type";
+    desc.identifier = "onsettype";
+    desc.name = "Onset Detection Function Type";
     desc.minValue = 0;
     desc.maxValue = 6;
     desc.defaultValue = (int)aubio_onset_complex;
     desc.minValue = 0;
     desc.maxValue = 6;
     desc.defaultValue = (int)aubio_onset_complex;
@@ -166,8 +180,8 @@ Notes::getParameterDescriptors() const
     list.push_back(desc);
 
     desc = ParameterDescriptor();
     list.push_back(desc);
 
     desc = ParameterDescriptor();
-    desc.name = "pitchtype";
-    desc.description = "Pitch Detection Function Type";
+    desc.identifier = "pitchtype";
+    desc.name = "Pitch Detection Function Type";
     desc.minValue = 0;
     desc.maxValue = 4;
     desc.defaultValue = (int)aubio_pitch_yinfft;
     desc.minValue = 0;
     desc.maxValue = 4;
     desc.defaultValue = (int)aubio_pitch_yinfft;
@@ -181,8 +195,8 @@ Notes::getParameterDescriptors() const
     list.push_back(desc);
 
     desc = ParameterDescriptor();
     list.push_back(desc);
 
     desc = ParameterDescriptor();
-    desc.name = "minpitch";
-    desc.description = "Minimum Pitch";
+    desc.identifier = "minpitch";
+    desc.name = "Minimum Pitch";
     desc.minValue = 0;
     desc.maxValue = 127;
     desc.defaultValue = 32;
     desc.minValue = 0;
     desc.maxValue = 127;
     desc.defaultValue = 32;
@@ -192,8 +206,8 @@ Notes::getParameterDescriptors() const
     list.push_back(desc);
 
     desc = ParameterDescriptor();
     list.push_back(desc);
 
     desc = ParameterDescriptor();
-    desc.name = "maxpitch";
-    desc.description = "Maximum Pitch";
+    desc.identifier = "maxpitch";
+    desc.name = "Maximum Pitch";
     desc.minValue = 0;
     desc.maxValue = 127;
     desc.defaultValue = 95;
     desc.minValue = 0;
     desc.maxValue = 127;
     desc.defaultValue = 95;
@@ -203,8 +217,8 @@ Notes::getParameterDescriptors() const
     list.push_back(desc);
 
     desc = ParameterDescriptor();
     list.push_back(desc);
 
     desc = ParameterDescriptor();
-    desc.name = "wraprange";
-    desc.description = "Fold Higher or Lower Notes into Range";
+    desc.identifier = "wraprange";
+    desc.name = "Fold Higher or Lower Notes into Range";
     desc.minValue = 0;
     desc.maxValue = 1;
     desc.defaultValue = 0;
     desc.minValue = 0;
     desc.maxValue = 1;
     desc.defaultValue = 0;
@@ -213,8 +227,8 @@ Notes::getParameterDescriptors() const
     list.push_back(desc);
 
     desc = ParameterDescriptor();
     list.push_back(desc);
 
     desc = ParameterDescriptor();
-    desc.name = "avoidleaps";
-    desc.description = "Avoid Multi-Octave Jumps";
+    desc.identifier = "avoidleaps";
+    desc.name = "Avoid Multi-Octave Jumps";
     desc.minValue = 0;
     desc.maxValue = 1;
     desc.defaultValue = 0;
     desc.minValue = 0;
     desc.maxValue = 1;
     desc.defaultValue = 0;
@@ -223,8 +237,8 @@ Notes::getParameterDescriptors() const
     list.push_back(desc);
 
     desc = ParameterDescriptor();
     list.push_back(desc);
 
     desc = ParameterDescriptor();
-    desc.name = "peakpickthreshold";
-    desc.description = "Peak Picker Threshold";
+    desc.identifier = "peakpickthreshold";
+    desc.name = "Peak Picker Threshold";
     desc.minValue = 0;
     desc.maxValue = 1;
     desc.defaultValue = 0.3;
     desc.minValue = 0;
     desc.maxValue = 1;
     desc.defaultValue = 0.3;
@@ -232,8 +246,8 @@ Notes::getParameterDescriptors() const
     list.push_back(desc);
 
     desc = ParameterDescriptor();
     list.push_back(desc);
 
     desc = ParameterDescriptor();
-    desc.name = "silencethreshold";
-    desc.description = "Silence Threshold";
+    desc.identifier = "silencethreshold";
+    desc.name = "Silence Threshold";
     desc.minValue = -120;
     desc.maxValue = 0;
     desc.defaultValue = -90;
     desc.minValue = -120;
     desc.maxValue = 0;
     desc.defaultValue = -90;
@@ -310,14 +324,23 @@ Notes::getOutputDescriptors() const
     OutputList list;
 
     OutputDescriptor d;
     OutputList list;
 
     OutputDescriptor d;
-    d.name = "notes";
+    d.identifier = "notes";
+    d.name = "Notes";
     d.unit = "Hz";
     d.unit = "Hz";
-    d.description = "Notes";
     d.hasFixedBinCount = true;
     d.hasFixedBinCount = true;
-    d.binCount = 2;
-    d.binNames.push_back("Frequency");
-    d.binNames.push_back("Duration");
-    d.binNames.push_back("Velocity");
+
+    if (m_apiVersion == 1) {
+        d.binCount = 3;
+        d.binNames.push_back("Frequency");
+        d.binNames.push_back("Duration");
+        d.binNames.push_back("Velocity");
+    } else {
+        d.binCount = 2;
+        d.binNames.push_back("Frequency");
+        d.binNames.push_back("Velocity");
+        d.hasDuration = true;
+    }
+
     d.hasKnownExtents = false;
     d.isQuantized = false;
     d.sampleType = OutputDescriptor::VariableSampleRate;
     d.hasKnownExtents = false;
     d.isQuantized = false;
     d.sampleType = OutputDescriptor::VariableSampleRate;
@@ -389,7 +412,7 @@ Notes::pushNote(FeatureSet &fs, const Vamp::RealTime &offTime)
     if (median < 45.0) return;
 
     float freq = median;
     if (median < 45.0) return;
 
     float freq = median;
-    int midiPitch = (int)FLOOR(aubio_freqtomidi(freq) + 0.5);
+    int midiPitch = (int)floor(aubio_freqtomidi(freq) + 0.5);
     
     if (m_avoidLeaps) {
         if (m_prevPitch >= 0) {
     
     if (m_avoidLeaps) {
         if (m_prevPitch >= 0) {
@@ -423,9 +446,19 @@ Notes::pushNote(FeatureSet &fs, const Vamp::RealTime &offTime)
     if (m_currentOnset < m_delay) m_currentOnset = m_delay;
     feature.timestamp = m_currentOnset - m_delay;
     feature.values.push_back(freq);
     if (m_currentOnset < m_delay) m_currentOnset = m_delay;
     feature.timestamp = m_currentOnset - m_delay;
     feature.values.push_back(freq);
-    feature.values.push_back
-        (Vamp::RealTime::realTime2Frame(offTime, lrintf(m_inputSampleRate)) -
-         Vamp::RealTime::realTime2Frame(m_currentOnset, lrintf(m_inputSampleRate)));
+
+    if (m_apiVersion == 1) {
+        feature.values.push_back
+            (Vamp::RealTime::realTime2Frame
+             (offTime, lrintf(m_inputSampleRate)) -
+             Vamp::RealTime::realTime2Frame
+             (m_currentOnset, lrintf(m_inputSampleRate)));
+        feature.hasDuration = false;
+    } else {
+        feature.hasDuration = true;
+        feature.duration = offTime - m_currentOnset;
+    }
+
     feature.values.push_back(m_currentLevel);
     fs[0].push_back(feature);
 }
     feature.values.push_back(m_currentLevel);
     fs[0].push_back(feature);
 }