# HG changeset patch # User cannam # Date 1143817229 0 # Node ID ad9aa1881a709132c7f9b328e6edf814ecce1305 # Parent 6479539d1b32056cb2477596121ab072e31e5b42 * Add most basic load-library-and-list-plugins host diff -r 6479539d1b32 -r ad9aa1881a70 Makefile --- a/Makefile Fri Mar 31 14:21:51 2006 +0000 +++ b/Makefile Fri Mar 31 15:00:29 2006 +0000 @@ -1,12 +1,21 @@ -all: +all: examples/plugins.so host/simplehost test + +examples/plugins.so: $(MAKE) -C examples all +host/simplehost: + $(MAKE) -C host all + +test: + $(MAKE) -C host test + clean: $(MAKE) -C examples clean distclean: $(MAKE) -C examples distclean + $(MAKE) -C host distclean rm -f *~ *.bak $(TARGET) diff -r 6479539d1b32 -r ad9aa1881a70 examples/Makefile --- a/examples/Makefile Fri Mar 31 14:21:51 2006 +0000 +++ b/examples/Makefile Fri Mar 31 15:00:29 2006 +0000 @@ -9,10 +9,10 @@ LDFLAGS := -shared -Wl,-Bsymbolic -APIFILES := $(SDKPATH)/PluginAdapter.cpp $(SDKPATH)/RealTime.cpp +SDKFILES := $(SDKPATH)/PluginAdapter.cpp $(SDKPATH)/RealTime.cpp plugins.so: $(OBJECTS) - $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $(TARGET) $(APIFILES) $(OBJECTS) + $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $(TARGET) $(SDKFILES) $(OBJECTS) all: $(TARGET) @@ -22,3 +22,5 @@ distclean: clean rm -f *~ *.bak $(TARGET) +ZeroCrossing.o: ZeroCrossing.cpp ../vamp/vamp.h ../sdk/PluginAdapter.h ../sdk/PluginAdapter.cpp ../sdk/RealTime.h ../sdk/RealTime.cpp ../sdk/Plugin.h ../sdk/PluginBase.h +SpectralCentroid.o: SpectralCentroid.cpp ../vamp/vamp.h ../sdk/PluginAdapter.h ../sdk/PluginAdapter.cpp ../sdk/RealTime.h ../sdk/RealTime.cpp ../sdk/Plugin.h ../sdk/PluginBase.h diff -r 6479539d1b32 -r ad9aa1881a70 host/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/host/Makefile Fri Mar 31 15:00:29 2006 +0000 @@ -0,0 +1,24 @@ + +SDKPATH := ../sdk +APIPATH := ../vamp + +CXXFLAGS := $(CXXFLAGS) -O2 -Wall -I$(SDKPATH) -I$(APIPATH) +LIBS := $(LIBS) -ldl + +SDKFILES := $(SDKPATH)/PluginHostAdapter.cpp $(SDKPATH)/RealTime.cpp + +simplehost: simplehost.o + $(CXX) $(CXXFLAGS) -o simplehost $(SDKFILES) simplehost.o $(LIBS) + +all: simplehost + +test: + simplehost ../examples/plugins.so + +clean: + rm -f simplehost.o + +distclean: clean + rm -f simplehost *~ *.bak + +simplehost.o: simplehost.cpp system.h ../vamp/vamp.h ../sdk/PluginHostAdapter.h ../sdk/PluginHostAdapter.cpp ../sdk/RealTime.h ../sdk/RealTime.cpp ../sdk/Plugin.h ../sdk/PluginBase.h diff -r 6479539d1b32 -r ad9aa1881a70 host/simplehost.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/host/simplehost.cpp Fri Mar 31 15:00:29 2006 +0000 @@ -0,0 +1,101 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + 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 X CONSORTIUM 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#include + +#include "vamp.h" + +#include "PluginHostAdapter.h" + +#include "system.h" + +/* + A very simple Vamp plugin host. So far all this does is load the + plugin library given on the command line and dump out the names of + the plugins found in it. +*/ + +int main(int argc, char **argv) +{ + if (argc != 2) { + std::cerr << "Usage: " << argv[0] << " pluginlibrary.so" << std::endl; + return 2; + } + + std::cerr << std::endl << argv[0] << ": Running..." << std::endl; + + std::string soname = argv[1]; + + void *libraryHandle = DLOPEN(soname, RTLD_LAZY); + + if (!libraryHandle) { + std::cerr << argv[0] << ": Failed to open plugin library " + << soname << std::endl; + return 1; + } + + std::cout << argv[0] << ": Opened plugin library " << soname << std::endl; + + VampGetPluginDescriptorFunction fn = (VampGetPluginDescriptorFunction) + DLSYM(libraryHandle, "vampGetPluginDescriptor"); + + if (!fn) { + std::cerr << argv[0] << ": No Vamp descriptor function in library " + << soname << std::endl; + DLCLOSE(libraryHandle); + return 1; + } + + std::cout << argv[0] << ": Found plugin descriptor function" << std::endl; + + int index = 0; + const VampPluginDescriptor *descriptor = 0; + + while ((descriptor = fn(index))) { + + Vamp::PluginHostAdapter adapter(descriptor, 48000); + std::cout << argv[0] << ": Plugin " << (index+1) + << " is \"" << adapter.getName() << "\"" << std::endl; + + ++index; + } + + std::cout << argv[0] << ": Done\n" << std::endl; + + DLCLOSE(libraryHandle); + return 0; +} + diff -r 6479539d1b32 -r ad9aa1881a70 host/system.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/host/system.h Fri Mar 31 15:00:29 2006 +0000 @@ -0,0 +1,65 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + 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 X CONSORTIUM 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _SYSTEM_H_ +#define _SYSTEM_H_ + +#ifdef _WIN32 + +#include + +#define DLOPEN(a,b) LoadLibrary((a).c_str()) +#define DLSYM(a,b) GetProcAddress((HINSTANCE)(a),(b)) +#define DLCLOSE(a) FreeLibrary((HINSTANCE)(a)) +#define DLERROR() "" + +#define PLUGIN_GLOB "*.dll" + +#else + +#include + +#define DLOPEN(a,b) dlopen((a).c_str(),(b)) +#define DLSYM(a,b) dlsym((a),(b)) +#define DLCLOSE(a) dlclose((a)) +#define DLERROR() dlerror() + +#define PLUGIN_GLOB "*.so" + +#endif + +#endif + diff -r 6479539d1b32 -r ad9aa1881a70 sdk/PluginHostAdapter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdk/PluginHostAdapter.cpp Fri Mar 31 15:00:29 2006 +0000 @@ -0,0 +1,314 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + 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 X CONSORTIUM 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#include "PluginHostAdapter.h" + +namespace Vamp +{ + +PluginHostAdapter::PluginHostAdapter(const VampPluginDescriptor *descriptor, + float inputSampleRate) : + Plugin(inputSampleRate), + m_descriptor(descriptor) +{ + std::cerr << "PluginHostAdapter::PluginHostAdapter (plugin = " << descriptor->name << ")" << std::endl; + m_handle = m_descriptor->instantiate(m_descriptor, inputSampleRate); +} + +PluginHostAdapter::~PluginHostAdapter() +{ + if (m_handle) m_descriptor->cleanup(m_handle); +} + +bool +PluginHostAdapter::initialise(size_t channels, + size_t stepSize, + size_t blockSize) +{ + if (!m_handle) return false; + return m_descriptor->initialise(m_handle, channels, stepSize, blockSize) ? + true : false; +} + +void +PluginHostAdapter::reset() +{ + if (!m_handle) return; + m_descriptor->reset(m_handle); +} + +PluginHostAdapter::InputDomain +PluginHostAdapter::getInputDomain() const +{ + if (m_descriptor->inputDomain == vampFrequencyDomain) { + return FrequencyDomain; + } else { + return TimeDomain; + } +} + +std::string +PluginHostAdapter::getName() const +{ + return m_descriptor->name; +} + +std::string +PluginHostAdapter::getDescription() const +{ + return m_descriptor->description; +} + +std::string +PluginHostAdapter::getMaker() const +{ + return m_descriptor->maker; +} + +int +PluginHostAdapter::getPluginVersion() const +{ + return m_descriptor->pluginVersion; +} + +std::string +PluginHostAdapter::getCopyright() const +{ + return m_descriptor->copyright; +} + +PluginHostAdapter::ParameterList +PluginHostAdapter::getParameterDescriptors() const +{ + ParameterList list; + for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) { + const VampParameterDescriptor *spd = m_descriptor->parameters[i]; + ParameterDescriptor pd; + pd.name = spd->name; + pd.description = spd->description; + pd.unit = spd->unit; + pd.minValue = spd->minValue; + pd.maxValue = spd->maxValue; + pd.defaultValue = spd->defaultValue; + pd.isQuantized = spd->isQuantized; + pd.quantizeStep = spd->quantizeStep; + list.push_back(pd); + } + return list; +} + +float +PluginHostAdapter::getParameter(std::string param) const +{ + if (!m_handle) return 0.0; + + for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) { + if (param == m_descriptor->parameters[i]->name) { + return m_descriptor->getParameter(m_handle, i); + } + } + + return 0.0; +} + +void +PluginHostAdapter::setParameter(std::string param, + float value) +{ + if (!m_handle) return; + + for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) { + if (param == m_descriptor->parameters[i]->name) { + m_descriptor->setParameter(m_handle, i, value); + return; + } + } +} + +PluginHostAdapter::ProgramList +PluginHostAdapter::getPrograms() const +{ + ProgramList list; + + for (unsigned int i = 0; i < m_descriptor->programCount; ++i) { + list.push_back(m_descriptor->programs[i]); + } + + return list; +} + +std::string +PluginHostAdapter::getCurrentProgram() const +{ + if (!m_handle) return ""; + + int pn = m_descriptor->getCurrentProgram(m_handle); + return m_descriptor->programs[pn]; +} + +void +PluginHostAdapter::selectProgram(std::string program) +{ + if (!m_handle) return; + + for (unsigned int i = 0; i < m_descriptor->programCount; ++i) { + if (program == m_descriptor->programs[i]) { + m_descriptor->selectProgram(m_handle, i); + return; + } + } +} + +size_t +PluginHostAdapter::getPreferredStepSize() const +{ + if (!m_handle) return 0; + return m_descriptor->getPreferredStepSize(m_handle); +} + +size_t +PluginHostAdapter::getPreferredBlockSize() const +{ + if (!m_handle) return 0; + return m_descriptor->getPreferredBlockSize(m_handle); +} + +PluginHostAdapter::OutputList +PluginHostAdapter::getOutputDescriptors() const +{ + OutputList list; + if (!m_handle) return list; + + unsigned int count = m_descriptor->getOutputCount(m_handle); + + for (unsigned int i = 0; i < count; ++i) { + VampOutputDescriptor *sd = m_descriptor->getOutputDescriptor(m_handle, i); + OutputDescriptor d; + d.name = sd->name; + d.description = sd->description; + d.unit = sd->unit; + d.hasFixedValueCount = sd->hasFixedValueCount; + d.valueCount = sd->valueCount; + for (unsigned int j = 0; j < sd->valueCount; ++j) { + d.valueNames.push_back(sd->valueNames[i] ? sd->valueNames[i] : ""); + } + d.hasKnownExtents = sd->hasKnownExtents; + d.minValue = sd->minValue; + d.maxValue = sd->maxValue; + d.isQuantized = sd->isQuantized; + d.quantizeStep = sd->quantizeStep; + + switch (sd->sampleType) { + case vampOneSamplePerStep: + d.sampleType = OutputDescriptor::OneSamplePerStep; break; + case vampFixedSampleRate: + d.sampleType = OutputDescriptor::FixedSampleRate; break; + case vampVariableSampleRate: + d.sampleType = OutputDescriptor::VariableSampleRate; break; + } + + d.sampleRate = sd->sampleRate; + + list.push_back(d); + + m_descriptor->releaseOutputDescriptor(sd); + } + + return list; +} + +PluginHostAdapter::FeatureSet +PluginHostAdapter::process(float **inputBuffers, + RealTime timestamp) +{ + FeatureSet fs; + if (!m_handle) return fs; + + int sec = timestamp.sec; + int nsec = timestamp.nsec; + + VampFeatureList **features = m_descriptor->process(m_handle, + inputBuffers, + sec, nsec); + + convertFeatures(features, fs); + m_descriptor->releaseFeatureSet(features); + return fs; +} + +PluginHostAdapter::FeatureSet +PluginHostAdapter::getRemainingFeatures() +{ + FeatureSet fs; + if (!m_handle) return fs; + + VampFeatureList **features = m_descriptor->getRemainingFeatures(m_handle); + + convertFeatures(features, fs); + m_descriptor->releaseFeatureSet(features); + return fs; +} + +void +PluginHostAdapter::convertFeatures(VampFeatureList **features, + FeatureSet &fs) +{ + for (unsigned int i = 0; features[i]; ++i) { + + VampFeatureList &list = *features[i]; + + if (list.featureCount > 0) { + + for (unsigned int j = 0; j < list.featureCount; ++j) { + + Feature feature; + feature.hasTimestamp = list.features[j].hasTimestamp; + feature.timestamp = RealTime(list.features[j].sec, + list.features[j].nsec); + + for (unsigned int k = 0; k < list.features[j].valueCount; ++k) { + feature.values.push_back(list.features[j].values[k]); + } + + feature.label = list.features[j].label; + + fs[i].push_back(feature); + } + } + } +} + +} diff -r 6479539d1b32 -r ad9aa1881a70 sdk/PluginHostAdapter.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdk/PluginHostAdapter.h Fri Mar 31 15:00:29 2006 +0000 @@ -0,0 +1,92 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + 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 X CONSORTIUM 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _PLUGIN_HOST_ADAPTER_H_ +#define _PLUGIN_HOST_ADAPTER_H_ + +#include "vamp.h" + +#include "Plugin.h" + +namespace Vamp { + +class PluginHostAdapter : public Plugin +{ +public: + PluginHostAdapter(const VampPluginDescriptor *descriptor, + float inputSampleRate); + virtual ~PluginHostAdapter(); + + bool initialise(size_t channels, size_t stepSize, size_t blockSize); + void reset(); + + InputDomain getInputDomain() 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); + + ProgramList getPrograms() const; + std::string getCurrentProgram() const; + void selectProgram(std::string); + + size_t getPreferredStepSize() const; + size_t getPreferredBlockSize() const; + + OutputList getOutputDescriptors() const; + + FeatureSet process(float **inputBuffers, RealTime timestamp); + + FeatureSet getRemainingFeatures(); + +protected: + void convertFeatures(VampFeatureList **, FeatureSet &); + + const VampPluginDescriptor *m_descriptor; + VampPluginHandle m_handle; +}; + +} + +#endif + +