Makefile.inc: move defaults up, set to sdk 2.5
[vamp-aubio-plugins.git] / plugins / Silence.cpp
index c7d2713..c58e217 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
@@ -25,7 +25,6 @@ Silence::Silence(float inputSampleRate) :
     Plugin(inputSampleRate),
     m_ibuf(0),
     m_pbuf(0),
     Plugin(inputSampleRate),
     m_ibuf(0),
     m_pbuf(0),
-    m_tmpptrs(0),
     m_threshold(-80),
     m_prevSilent(false),
     m_first(true)
     m_threshold(-80),
     m_prevSilent(false),
     m_first(true)
@@ -36,7 +35,6 @@ Silence::~Silence()
 {
     if (m_ibuf) del_fvec(m_ibuf);
     if (m_pbuf) del_fvec(m_pbuf);
 {
     if (m_ibuf) del_fvec(m_ibuf);
     if (m_pbuf) del_fvec(m_pbuf);
-    if (m_tmpptrs) delete[] m_tmpptrs;
 }
 
 string
 }
 
 string
@@ -66,7 +64,7 @@ Silence::getMaker() const
 int
 Silence::getPluginVersion() const
 {
 int
 Silence::getPluginVersion() const
 {
-    return 1;
+    return 4;
 }
 
 string
 }
 
 string
@@ -78,13 +76,16 @@ Silence::getCopyright() const
 bool
 Silence::initialise(size_t channels, size_t stepSize, size_t blockSize)
 {
 bool
 Silence::initialise(size_t channels, size_t stepSize, size_t blockSize)
 {
-    m_channelCount = channels;
+    if (channels != 1) {
+        std::cerr << "Silence::initialise: channels must be 1" << std::endl;
+        return false;
+    }
+
     m_stepSize = stepSize;
     m_blockSize = blockSize;
 
     m_stepSize = stepSize;
     m_blockSize = blockSize;
 
-    m_ibuf = new_fvec(stepSize, channels);
-    m_pbuf = new_fvec(stepSize, channels);
-    m_tmpptrs = new smpl_t *[channels];
+    m_ibuf = new_fvec(stepSize);
+    m_pbuf = new_fvec(stepSize);
 
     return true;
 }
 
     return true;
 }
@@ -116,6 +117,7 @@ Silence::getParameterDescriptors() const
     desc = ParameterDescriptor();
     desc.identifier = "silencethreshold";
     desc.name = "Silence Threshold";
     desc = ParameterDescriptor();
     desc.identifier = "silencethreshold";
     desc.name = "Silence Threshold";
+    desc.description = "Threshold for silence detection";
     desc.minValue = -120;
     desc.maxValue = 0;
     desc.defaultValue = -80;
     desc.minValue = -120;
     desc.maxValue = 0;
     desc.defaultValue = -80;
@@ -150,22 +152,27 @@ Silence::getOutputDescriptors() const
     OutputList list;
 
     OutputDescriptor d;
     OutputList list;
 
     OutputDescriptor d;
-    d.identifier = "silencestart";
-    d.name = "Beginnings of Silent Regions";
-    d.description = "Return a single instant at the point where each silent region begins";
+
+    d.identifier = "silent";
+    d.name = "Silent Regions";
+    d.description = "Return an interval covering each silent region";
     d.hasFixedBinCount = true;
     d.binCount = 0;
     d.hasFixedBinCount = true;
     d.binCount = 0;
+    d.hasKnownExtents = false;
     d.sampleType = OutputDescriptor::VariableSampleRate;
     d.sampleRate = 0;
     d.sampleType = OutputDescriptor::VariableSampleRate;
     d.sampleRate = 0;
+    d.hasDuration = true;
     list.push_back(d);
 
     list.push_back(d);
 
-    d.identifier = "silenceend";
-    d.name = "Ends of Silent Regions";
-    d.description = "Return a single instant at the point where each silent region ends";
+    d.identifier = "noisy";
+    d.name = "Non-Silent Regions";
+    d.description = "Return an interval covering each non-silent region";
     d.hasFixedBinCount = true;
     d.binCount = 0;
     d.hasFixedBinCount = true;
     d.binCount = 0;
+    d.hasKnownExtents = false;
     d.sampleType = OutputDescriptor::VariableSampleRate;
     d.sampleRate = 0;
     d.sampleType = OutputDescriptor::VariableSampleRate;
     d.sampleRate = 0;
+    d.hasDuration = true;
     list.push_back(d);
 
     d.identifier = "silencelevel";
     list.push_back(d);
 
     d.identifier = "silencelevel";
@@ -190,9 +197,7 @@ Silence::process(const float *const *inputBuffers,
                  Vamp::RealTime timestamp)
 {
     for (size_t i = 0; i < m_stepSize; ++i) {
                  Vamp::RealTime timestamp)
 {
     for (size_t i = 0; i < m_stepSize; ++i) {
-        for (size_t j = 0; j < m_channelCount; ++j) {
-            fvec_write_sample(m_ibuf, inputBuffers[j][i], j, i);
-        }
+        fvec_set_sample(m_ibuf, inputBuffers[0][i], i);
     }
 
     bool silent = aubio_silence_detection(m_ibuf, m_threshold);
     }
 
     bool silent = aubio_silence_detection(m_ibuf, m_threshold);
@@ -212,13 +217,9 @@ Silence::process(const float *const *inputBuffers,
 
             fvec_t vec;
             vec.length = incr * 4;
 
             fvec_t vec;
             vec.length = incr * 4;
-            vec.channels = m_channelCount;
-            vec.data = m_tmpptrs;
             
             for (size_t i = 0; i < m_stepSize - incr * 4; i += incr) {
             
             for (size_t i = 0; i < m_stepSize - incr * 4; i += incr) {
-                for (size_t j = 0; j < m_channelCount; ++j) {
-                    m_tmpptrs[j] = m_ibuf->data[j] + i;
-                }
+                vec.data = m_ibuf->data + i;
                 bool subsilent = aubio_silence_detection(&vec, m_threshold);
                 if (silent == subsilent) {
                     off = i;
                 bool subsilent = aubio_silence_detection(&vec, m_threshold);
                 if (silent == subsilent) {
                     off = i;
@@ -228,9 +229,7 @@ Silence::process(const float *const *inputBuffers,
 
             if (silent && (off == 0)) {
                 for (size_t i = 0; i < m_stepSize - incr; i += incr) {
 
             if (silent && (off == 0)) {
                 for (size_t i = 0; i < m_stepSize - incr; i += incr) {
-                    for (size_t j = 0; j < m_channelCount; ++j) {
-                        m_tmpptrs[j] = m_pbuf->data[j] + m_stepSize - i - incr;
-                    }
+                    vec.data = m_pbuf->data + m_stepSize - i - incr;
                     bool subsilent = aubio_silence_detection(&vec, m_threshold);
                     if (!subsilent) {
                         off = -(long)i;
                     bool subsilent = aubio_silence_detection(&vec, m_threshold);
                     if (!subsilent) {
                         off = -(long)i;
@@ -249,13 +248,24 @@ Silence::process(const float *const *inputBuffers,
         feature.timestamp = featureStamp;
         feature.values.push_back(silent ? 0 : 1);
         returnFeatures[2].push_back(feature);
         feature.timestamp = featureStamp;
         feature.values.push_back(silent ? 0 : 1);
         returnFeatures[2].push_back(feature);
+
         feature.values.clear();
 
         feature.values.clear();
 
-        if (silent) {
-            returnFeatures[0].push_back(feature);
-        } else {
-            returnFeatures[1].push_back(feature);
-        }            
+        if (!m_first) {
+            feature.timestamp = m_lastChange;
+            feature.hasDuration = true;
+            feature.duration = featureStamp - m_lastChange;
+            if (silent) {
+                // non-silent regions feature
+                // (becoming silent, so this is a non-silent region)
+                returnFeatures[1].push_back(feature);
+            } else {
+                // silent regions feature
+                // (becoming non-silent, so this is a silent region)
+                returnFeatures[0].push_back(feature);
+            }                    
+        }
+        m_lastChange = featureStamp;
 
         m_prevSilent = silent;
         m_first = false;
 
         m_prevSilent = silent;
         m_first = false;
@@ -264,16 +274,47 @@ Silence::process(const float *const *inputBuffers,
     // swap ibuf and pbuf data pointers, so that this block's data is
     // available in pbuf when processing the next block, without
     // having to allocate new storage for it
     // swap ibuf and pbuf data pointers, so that this block's data is
     // available in pbuf when processing the next block, without
     // having to allocate new storage for it
-    smpl_t **tmpdata = m_ibuf->data;
+    smpl_t *tmpdata = m_ibuf->data;
     m_ibuf->data = m_pbuf->data;
     m_pbuf->data = tmpdata;
 
     m_ibuf->data = m_pbuf->data;
     m_pbuf->data = tmpdata;
 
+    m_lastTimestamp = timestamp;
+
     return returnFeatures;
 }
 
 Silence::FeatureSet
 Silence::getRemainingFeatures()
 {
     return returnFeatures;
 }
 
 Silence::FeatureSet
 Silence::getRemainingFeatures()
 {
-    return FeatureSet();
+    FeatureSet returnFeatures;
+    
+//    std::cerr << "Silence::getRemainingFeatures: m_lastTimestamp = " << m_lastTimestamp << ", m_lastChange = " << m_lastChange << ", m_apiVersion = " << m_apiVersion << ", m_prevSilent = " << m_prevSilent << std::endl;
+
+    if (m_lastTimestamp > m_lastChange) {
+
+        Feature feature;
+        feature.hasTimestamp = true;
+
+        feature.timestamp = m_lastChange;
+        feature.hasDuration = true;
+        feature.duration = m_lastTimestamp - m_lastChange;
+        if (m_prevSilent) {
+            // silent regions feature
+            returnFeatures[0].push_back(feature);
+        } else {
+            // non-silent regions feature
+            returnFeatures[1].push_back(feature);
+        }
+
+        if (!m_prevSilent) {
+            Feature silenceTestFeature;
+            silenceTestFeature.hasTimestamp = true;
+            silenceTestFeature.timestamp = m_lastTimestamp;
+            silenceTestFeature.values.push_back(0);
+            returnFeatures[2].push_back(silenceTestFeature);
+        }
+    }
+
+    return returnFeatures;
 }
 
 }