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
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version. See the file
COPYING included with this distribution for more information.
-
*/
#include <math.h>
using std::cerr;
using std::endl;
-Silence::Silence(float inputSampleRate) :
+Silence::Silence(float inputSampleRate, unsigned int apiVersion) :
Plugin(inputSampleRate),
+ m_apiVersion(apiVersion),
m_ibuf(0),
m_pbuf(0),
m_tmpptrs(0),
- m_threshold(-70),
+ m_threshold(-80),
m_prevSilent(false),
m_first(true)
{
+ if (m_apiVersion == 1) {
+ cerr << "vamp-aubio: WARNING: using compatibility version 1 of the Vamp API for silence\n"
+ << "detector plugin: upgrade your host to v2 for proper duration support" << endl;
+ }
}
Silence::~Silence()
int
Silence::getPluginVersion() const
{
- return 1;
+ if (m_apiVersion == 1) return 2;
+ return 3;
}
string
desc.name = "Silence Threshold";
desc.minValue = -120;
desc.maxValue = 0;
- desc.defaultValue = -70;
+ desc.defaultValue = -80;
desc.unit = "dB";
desc.isQuantized = false;
list.push_back(desc);
OutputList list;
OutputDescriptor d;
- d.identifier = "silencestart";
- d.name = "Starts of Silent Regions";
- d.description = "Return a single instant at the point where each silent region begins";
- d.hasFixedBinCount = true;
- d.binCount = 0;
- d.sampleType = OutputDescriptor::VariableSampleRate;
- 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.hasFixedBinCount = true;
- d.binCount = 0;
- d.sampleType = OutputDescriptor::VariableSampleRate;
- list.push_back(d);
+ if (m_apiVersion == 1) {
+
+ d.identifier = "silencestart";
+ d.name = "Beginnings of Silent Regions";
+ d.description = "Return a single instant at the point where each silent region begins";
+ d.hasFixedBinCount = true;
+ d.binCount = 0;
+ d.hasKnownExtents = false;
+ d.sampleType = OutputDescriptor::VariableSampleRate;
+ d.sampleRate = 0;
+ 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.hasFixedBinCount = true;
+ d.binCount = 0;
+ d.hasKnownExtents = false;
+ d.sampleType = OutputDescriptor::VariableSampleRate;
+ d.sampleRate = 0;
+ list.push_back(d);
+
+ } else {
+
+ d.identifier = "silent";
+ d.name = "Silent Regions";
+ d.description = "Return an interval covering each silent region";
+ d.hasFixedBinCount = true;
+ d.binCount = 0;
+ d.hasKnownExtents = false;
+ d.sampleType = OutputDescriptor::VariableSampleRate;
+ d.sampleRate = 0;
+ d.hasDuration = true;
+ list.push_back(d);
+
+ 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.hasKnownExtents = false;
+ d.sampleType = OutputDescriptor::VariableSampleRate;
+ d.sampleRate = 0;
+ d.hasDuration = true;
+ list.push_back(d);
+ }
d.identifier = "silencelevel";
d.name = "Silence Test";
d.isQuantized = true;
d.quantizeStep = 1;
d.sampleType = OutputDescriptor::VariableSampleRate;
+ d.sampleRate = 0;
list.push_back(d);
return list;
vec.channels = m_channelCount;
vec.data = m_tmpptrs;
- if (silent) {
- std::cerr << "silence at " << timestamp << std::endl;
- }
-
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;
}
bool subsilent = aubio_silence_detection(&vec, m_threshold);
if (silent == subsilent) {
- std::cerr << "silent == subsilent at " << i << " after" << std::endl;
off = i;
break;
}
}
bool subsilent = aubio_silence_detection(&vec, m_threshold);
if (!subsilent) {
- std::cerr << "non-silence at " << i << " samples before" << std::endl;
off = -(long)i;
break;
- } else {
- std::cerr << "silence at " << i << " samples before" << std::endl;
}
}
} else {
feature.timestamp = featureStamp;
feature.values.push_back(silent ? 0 : 1);
returnFeatures[2].push_back(feature);
+
feature.values.clear();
- if (silent) {
- returnFeatures[0].push_back(feature);
+ if (m_apiVersion == 1) {
+ if (silent) {
+ returnFeatures[0].push_back(feature);
+ } else {
+ returnFeatures[1].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) {
+ // becoming silent, so this is a non-silent region
+ returnFeatures[1].push_back(feature);
+ } else {
+ // becoming non-silent, so this is a silent region
+ returnFeatures[0].push_back(feature);
+ }
+ }
+ m_lastChange = featureStamp;
+ }
m_prevSilent = silent;
m_first = false;
m_ibuf->data = m_pbuf->data;
m_pbuf->data = tmpdata;
+ m_lastTimestamp = timestamp;
+
return returnFeatures;
}
Silence::FeatureSet
Silence::getRemainingFeatures()
{
+ FeatureSet returnFeatures;
+
+ if (m_prevSilent) {
+ 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) {
+ returnFeatures[0].push_back(feature);
+ } else {
+ returnFeatures[1].push_back(feature);
+ }
+ }
+ }
+
return FeatureSet();
}