From: Chris Cannam Date: Tue, 9 Oct 2007 15:42:36 +0000 (+0000) Subject: * Add silence detector. But I'm not happy with its results: take a look at X-Git-Tag: hgimport~33 X-Git-Url: https://git.aubio.org/?p=vamp-aubio-plugins.git;a=commitdiff_plain;h=d8075e20c6eaafa643b543d08c1299ea16b7e150 * Add silence detector. But I'm not happy with its results: take a look at the aubio silence detection code and see what's up --- diff --git a/libmain.cpp b/libmain.cpp index 9298fe8..787ef0c 100644 --- a/libmain.cpp +++ b/libmain.cpp @@ -21,11 +21,13 @@ #include "plugins/Pitch.h" #include "plugins/Notes.h" #include "plugins/Tempo.h" +#include "plugins/Silence.h" static Vamp::PluginAdapter onsetAdapter; static Vamp::PluginAdapter pitchAdapter; static Vamp::PluginAdapter notesAdapter; static Vamp::PluginAdapter tempoAdapter; +static Vamp::PluginAdapter silenceAdapter; const VampPluginDescriptor *vampGetPluginDescriptor(unsigned int vampApiVersion, unsigned int index) @@ -37,6 +39,7 @@ const VampPluginDescriptor *vampGetPluginDescriptor(unsigned int vampApiVersion, case 1: return pitchAdapter.getDescriptor(); case 2: return notesAdapter.getDescriptor(); case 3: return tempoAdapter.getDescriptor(); + case 4: return silenceAdapter.getDescriptor(); default: return 0; } } diff --git a/plugins/Silence.cpp b/plugins/Silence.cpp new file mode 100644 index 0000000..01d516b --- /dev/null +++ b/plugins/Silence.cpp @@ -0,0 +1,285 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + 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 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 +#include "Silence.h" + +using std::string; +using std::vector; +using std::cerr; +using std::endl; + +Silence::Silence(float inputSampleRate) : + Plugin(inputSampleRate), + m_ibuf(0), + m_pbuf(0), + m_tmpptrs(0), + m_threshold(-70), + m_prevSilent(false), + m_first(true) +{ +} + +Silence::~Silence() +{ + if (m_ibuf) del_fvec(m_ibuf); + if (m_pbuf) del_fvec(m_pbuf); + if (m_tmpptrs) delete[] m_tmpptrs; +} + +string +Silence::getIdentifier() const +{ + return "aubiosilence"; +} + +string +Silence::getName() const +{ + return "Aubio Silence Detector"; +} + +string +Silence::getDescription() const +{ + return "Detect levels below a certain threshold"; +} + +string +Silence::getMaker() const +{ + return "Paul Brossier (plugin by Chris Cannam)"; +} + +int +Silence::getPluginVersion() const +{ + return 1; +} + +string +Silence::getCopyright() const +{ + return "GPL"; +} + +bool +Silence::initialise(size_t channels, size_t stepSize, size_t blockSize) +{ + m_channelCount = channels; + m_stepSize = stepSize; + m_blockSize = blockSize; + + m_ibuf = new_fvec(stepSize, channels); + m_pbuf = new_fvec(stepSize, channels); + m_tmpptrs = new smpl_t *[channels]; + + return true; +} + +void +Silence::reset() +{ + m_first = true; +} + +size_t +Silence::getPreferredStepSize() const +{ + return 1024; +} + +size_t +Silence::getPreferredBlockSize() const +{ + return 1024; +} + +Silence::ParameterList +Silence::getParameterDescriptors() const +{ + ParameterList list; + ParameterDescriptor desc; + + desc = ParameterDescriptor(); + desc.identifier = "silencethreshold"; + desc.name = "Silence Threshold"; + desc.minValue = -120; + desc.maxValue = 0; + desc.defaultValue = -70; + desc.unit = "dB"; + desc.isQuantized = false; + list.push_back(desc); + + return list; +} + +float +Silence::getParameter(std::string param) const +{ + if (param == "silencethreshold") { + return m_threshold; + } else { + return 0.0; + } +} + +void +Silence::setParameter(std::string param, float value) +{ + if (param == "silencethreshold") { + m_threshold = value; + } +} + +Silence::OutputList +Silence::getOutputDescriptors() const +{ + 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); + + d.identifier = "silencelevel"; + d.name = "Silence Test"; + d.description = "Return a function that switches from 1 to 0 when silence falls, and back again when it ends"; + d.hasFixedBinCount = true; + d.binCount = 1; + d.hasKnownExtents = true; + d.minValue = 0; + d.maxValue = 1; + d.isQuantized = true; + d.quantizeStep = 1; + d.sampleType = OutputDescriptor::VariableSampleRate; + list.push_back(d); + + return list; +} + +Silence::FeatureSet +Silence::process(const float *const *inputBuffers, + 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); + } + } + + bool silent = aubio_silence_detection(m_ibuf, m_threshold); + FeatureSet returnFeatures; + + if (m_first || m_prevSilent != silent) { + + Vamp::RealTime featureStamp = timestamp; + + if ((silent && !m_first) || !silent) { + + // refine our result + + long off = 0; + size_t incr = 16; + if (incr > m_stepSize/8) incr = m_stepSize/8; + + fvec_t vec; + vec.length = incr * 4; + 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; + } + } + + 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; + } + 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 { + } + + featureStamp = timestamp + Vamp::RealTime::frame2RealTime + (off, lrintf(m_inputSampleRate)); + } + + Feature feature; + feature.hasTimestamp = true; + 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); + } else { + returnFeatures[1].push_back(feature); + } + + m_prevSilent = silent; + m_first = false; + } + + // 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; + m_ibuf->data = m_pbuf->data; + m_pbuf->data = tmpdata; + + return returnFeatures; +} + +Silence::FeatureSet +Silence::getRemainingFeatures() +{ + return FeatureSet(); +} + diff --git a/plugins/Silence.h b/plugins/Silence.h new file mode 100644 index 0000000..35b3fad --- /dev/null +++ b/plugins/Silence.h @@ -0,0 +1,68 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + 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 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. + +*/ + +#ifndef _SILENCE_PLUGIN_H_ +#define _SILENCE_PLUGIN_H_ + +#include +#include + +class Silence : public Vamp::Plugin +{ +public: + Silence(float inputSampleRate); + virtual ~Silence(); + + bool initialise(size_t channels, size_t stepSize, size_t blockSize); + void reset(); + + InputDomain getInputDomain() const { return TimeDomain; } + + std::string getIdentifier() const; + std::string getName() const; + std::string getDescription() const; + std::string getMaker() const; + int getPluginVersion() const; + std::string getCopyright() const; + + ParameterList getParameterDescriptors() const; + float getParameter(std::string) const; + void setParameter(std::string, float); + + size_t getPreferredStepSize() const; + size_t getPreferredBlockSize() const; + + OutputList getOutputDescriptors() const; + + FeatureSet process(const float *const *inputBuffers, + Vamp::RealTime timestamp); + + FeatureSet getRemainingFeatures(); + +protected: + fvec_t *m_ibuf; + fvec_t *m_pbuf; + smpl_t **m_tmpptrs; + float m_threshold; + size_t m_stepSize; + size_t m_blockSize; + size_t m_channelCount; + bool m_prevSilent; + bool m_first; +}; + + +#endif diff --git a/vamp-aubio.cat b/vamp-aubio.cat index 10ba08c..025f1be 100644 --- a/vamp-aubio.cat +++ b/vamp-aubio.cat @@ -2,3 +2,4 @@ vamp:vamp-aubio:aubionotes::Notes vamp:vamp-aubio:aubioonset::Time > Onsets vamp:vamp-aubio:aubiotempo::Time > Tempo vamp:vamp-aubio:aubiopitch::Pitch +vamp:vamp-aubio:aubiosilence::Low Level Features