Mercurial > hg > constant-q-cpp
changeset 35:75d528478feb
Add Vamp plugin for testing with
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Wed, 06 Nov 2013 14:30:42 +0000 |
parents | e9752aa1b234 |
children | cb072f01435b |
files | vamp/CQVamp.cpp vamp/CQVamp.h vamp/Makefile vamp/libmain.cpp |
diffstat | 4 files changed, 371 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vamp/CQVamp.cpp Wed Nov 06 14:30:42 2013 +0000 @@ -0,0 +1,237 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +#include "CQVamp.h" + +#include "../cpp-qm-dsp/ConstantQ.h" + +using std::string; +using std::vector; +using std::cerr; +using std::endl; + +CQVamp::CQVamp(float inputSampleRate) : + Vamp::Plugin(inputSampleRate), + m_cq(0), + m_maxFrequency(inputSampleRate/2), + m_minFrequency(46), + m_bpo(24) +{ +} + +CQVamp::~CQVamp() +{ + delete m_cq; +} + +string +CQVamp::getIdentifier() const +{ + return "cqvamp"; +} + +string +CQVamp::getName() const +{ + return "Constant-Q Spectrogram"; +} + +string +CQVamp::getDescription() const +{ + return "Extract a spectrogram with constant ratio of centre frequency to resolution from the input audio"; +} + +string +CQVamp::getMaker() const +{ + return "Queen Mary, University of London"; +} + +int +CQVamp::getPluginVersion() const +{ + return 1; +} + +string +CQVamp::getCopyright() const +{ + return "Plugin by Chris Cannam. Method by Christian Schörkhuber and Anssi Klapuri. Copyright (c) 2013 QMUL"; +} + +CQVamp::ParameterList +CQVamp::getParameterDescriptors() const +{ + ParameterList list; + + ParameterDescriptor desc; + desc.identifier = "minfreq"; + desc.name = "Minimum Frequency"; + desc.unit = "Hz"; + desc.description = "Hint for the lowest frequency to be included in the constant-Q transform. The actual frequency range will be an integral number of octaves ending at the highest frequency specified"; + desc.minValue = 10; + desc.maxValue = m_inputSampleRate/2; + desc.defaultValue = 46; + desc.isQuantized = false; + list.push_back(desc); + + desc.identifier = "maxfreq"; + desc.name = "Maximum Frequency"; + desc.unit = "Hz"; + desc.description = "Highest frequency to be included in the constant-Q transform"; + desc.minValue = 10; + desc.maxValue = m_inputSampleRate/2; + desc.defaultValue = m_inputSampleRate/2; + desc.isQuantized = false; + list.push_back(desc); + + desc.identifier = "bpo"; + desc.name = "Bins per Octave"; + desc.unit = "bins"; + desc.description = "Number of constant-Q transform bins per octave"; + desc.minValue = 2; + desc.maxValue = 480; + desc.defaultValue = 24; + desc.isQuantized = true; + desc.quantizeStep = 1; + list.push_back(desc); + + return list; +} + +float +CQVamp::getParameter(std::string param) const +{ + if (param == "minfreq") { + return m_minFrequency; + } + if (param == "maxfreq") { + return m_maxFrequency; + } + if (param == "bpo") { + return m_bpo; + } + std::cerr << "WARNING: CQVamp::getParameter: unknown parameter \"" + << param << "\"" << std::endl; + return 0.0; +} + +void +CQVamp::setParameter(std::string param, float value) +{ + if (param == "minfreq") { + m_minFrequency = value; + } else if (param == "maxfreq") { + m_maxFrequency = value; + } else if (param == "bpo") { + m_bpo = lrintf(value); + } else { + std::cerr << "WARNING: CQVamp::setParameter: unknown parameter \"" + << param << "\"" << std::endl; + } +} + +bool +CQVamp::initialise(size_t channels, size_t stepSize, size_t blockSize) +{ + if (m_cq) { + delete m_cq; + m_cq = 0; + } + + if (channels < getMinChannelCount() || + channels > getMaxChannelCount()) return false; + + m_stepSize = stepSize; + m_blockSize = blockSize; + + m_cq = new ConstantQ + (m_inputSampleRate, m_minFrequency, m_maxFrequency, m_bpo); + + return true; +} + +void +CQVamp::reset() +{ + if (m_cq) { + delete m_cq; + m_cq = new ConstantQ + (m_inputSampleRate, m_minFrequency, m_maxFrequency, m_bpo); + } +} + +size_t +CQVamp::getPreferredStepSize() const +{ + return 0; +} + +size_t +CQVamp::getPreferredBlockSize() const +{ + return 0; +} + +CQVamp::OutputList +CQVamp::getOutputDescriptors() const +{ + OutputList list; + + OutputDescriptor d; + d.identifier = "constantq"; + d.name = "Constant-Q Spectrogram"; + d.unit = ""; + d.description = "Output of constant-Q transform, as a single vector per process block"; + d.hasFixedBinCount = true; + d.binCount = (m_cq ? m_cq->getTotalBins() : (9 * 24)); + d.hasKnownExtents = false; + d.isQuantized = false; + d.sampleType = OutputDescriptor::FixedSampleRate; + d.sampleRate = m_inputSampleRate / (m_cq ? m_cq->getColumnHop() : 256); + list.push_back(d); + + return list; +} + +CQVamp::FeatureSet +CQVamp::process(const float *const *inputBuffers, + Vamp::RealTime /* timestamp */) +{ + if (!m_cq) { + cerr << "ERROR: CQVamp::process: " + << "Plugin has not been initialised" + << endl; + return FeatureSet(); + } + + vector<double> data; + for (int i = 0; i < m_blockSize; ++i) data.push_back(inputBuffers[0][i]); + + vector<vector<double> > cqout = m_cq->process(data); + + FeatureSet returnFeatures; + + for (int i = 0; i < cqout.size(); ++i) { + + vector<float> column(m_cq->getTotalBins(), 0.f); + for (int j = 0; j < cqout[i].size(); ++j) { + column[j] = cqout[i][j]; + } + + Feature feature; + feature.hasTimestamp = false; + feature.values = column; + feature.label = ""; + returnFeatures[0].push_back(feature); + } + + return returnFeatures; +} + +CQVamp::FeatureSet +CQVamp::getRemainingFeatures() +{ + return FeatureSet(); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vamp/CQVamp.h Wed Nov 06 14:30:42 2013 +0000 @@ -0,0 +1,52 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +#ifndef CQVAMP_H +#define CQVAMP_H + +#include <vamp-sdk/Plugin.h> + +class ConstantQ; + +class CQVamp : public Vamp::Plugin +{ +public: + CQVamp(float inputSampleRate); + virtual ~CQVamp(); + + 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: + ConstantQ *m_cq; + float m_maxFrequency; + float m_minFrequency; + int m_bpo; + int m_stepSize; + int m_blockSize; +}; + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vamp/Makefile Wed Nov 06 14:30:42 2013 +0000 @@ -0,0 +1,39 @@ + +DEFINES := -DUSE_PTHREADS + +CFLAGS := -I../.. $(CFLAGS) $(DEFINES) + +#CXXFLAGS := -I../.. -Wall -fPIC -g $(CXXFLAGS) $(DEFINES) +CXXFLAGS := -I../.. -Wall -fPIC -O3 -ffast-math -ftree-vectorize $(CXXFLAGS) $(DEFINES) + +LDFLAGS := $(LDFLAGS) + +#VG := valgrind + +LIBS := ../../qm-dsp/libqm-dsp.a ../../vamp-plugin-sdk/libvamp-sdk.a -lpthread + +SOURCES := CQVamp.cpp libmain.cpp + +OBJECTS := $(SOURCES:.cpp=.o) +OBJECTS := $(OBJECTS:.c=.o) + +EXTRA_OBJECTS := ../cpp-qm-dsp/ConstantQ.o ../cpp-qm-dsp/CQKernel.o + +PLUGIN_EXT := so +PLUGIN = cqvamp.$(PLUGIN_EXT) + +all: $(PLUGIN) + +$(PLUGIN): $(OBJECTS) + $(CXX) -shared -o $@ $^ $(EXTRA_OBJECTS) $(LDFLAGS) $(LIBS) + +clean: + rm -f *.o + +depend: + makedepend -Y $(SOURCES) + +# DO NOT DELETE + +CQVamp.o: CQVamp.h ../cpp-qm-dsp/ConstantQ.h ../cpp-qm-dsp/CQKernel.h +libmain.o: CQVamp.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vamp/libmain.cpp Wed Nov 06 14:30:42 2013 +0000 @@ -0,0 +1,43 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ +/* + This file is Copyright (c) 2013 Queen Mary, University of London + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <vamp/vamp.h> +#include <vamp-sdk/PluginAdapter.h> + +#include "CQVamp.h" + +static Vamp::PluginAdapter<CQVamp> cqPluginAdapter; + +const VampPluginDescriptor * +vampGetPluginDescriptor(unsigned int version, unsigned int index) +{ + if (version < 1) return 0; + + switch (index) { + case 0: return cqPluginAdapter.getDescriptor(); + default: return 0; + } +} + +