# HG changeset patch # User cannam # Date 1178724097 0 # Node ID 09a1aac6c362eed1e80db704060da9c6c9f68f46 # Parent 4ab6224110eff2c066472bc9b6fef2a233e2b448 * add wrapper base * make loader able to look up categories diff -r 4ab6224110ef -r 09a1aac6c362 Makefile --- a/Makefile Fri May 04 15:21:12 2007 +0000 +++ b/Makefile Wed May 09 15:21:37 2007 +0000 @@ -80,6 +80,7 @@ $(HOSTSDKDIR)/PluginHostAdapter.h \ $(HOSTSDKDIR)/PluginInputDomainAdapter.h \ $(HOSTSDKDIR)/PluginLoader.h \ + $(HOSTSDKDIR)/PluginWrapper.h \ $(SDKDIR)/RealTime.h SDK_OBJECTS = \ @@ -90,6 +91,7 @@ $(HOSTSDKDIR)/PluginHostAdapter.o \ $(HOSTSDKDIR)/PluginInputDomainAdapter.o \ $(HOSTSDKDIR)/PluginLoader.o \ + $(HOSTSDKDIR)/PluginWrapper.o \ $(SDKDIR)/RealTime.o SDK_STATIC = \ diff -r 4ab6224110ef -r 09a1aac6c362 host/vamp-simple-host.cpp --- a/host/vamp-simple-host.cpp Fri May 04 15:21:12 2007 +0000 +++ b/host/vamp-simple-host.cpp Wed May 09 15:21:37 2007 +0000 @@ -376,7 +376,7 @@ LibraryMap libraryMap; for (size_t i = 0; i < plugins.size(); ++i) { - std::string path = loader.getLibraryPath(plugins[i]); + std::string path = loader.getLibraryPathForPlugin(plugins[i]); libraryMap.insert(LibraryMap::value_type(path, plugins[i])); } @@ -407,6 +407,17 @@ << plugin->getIdentifier() << "\"" << " [" << plugin->getMaker() << "]" << endl; +// cerr << "looking up category for " << key << " ..." << endl; + Vamp::PluginLoader::PluginCategoryHierarchy category = + loader.getPluginCategory(key); + if (!category.empty()) { + cerr << " "; + for (size_t ci = 0; ci < category.size(); ++ci) { + cerr << " > " << category[ci]; + } + cerr << endl; + } + if (plugin->getDescription() != "") { cerr << " - " << plugin->getDescription() << endl; } diff -r 4ab6224110ef -r 09a1aac6c362 vamp-hostsdk/PluginInputDomainAdapter.cpp --- a/vamp-hostsdk/PluginInputDomainAdapter.cpp Fri May 04 15:21:12 2007 +0000 +++ b/vamp-hostsdk/PluginInputDomainAdapter.cpp Wed May 09 15:21:37 2007 +0000 @@ -41,8 +41,7 @@ namespace Vamp { PluginInputDomainAdapter::PluginInputDomainAdapter(Plugin *plugin) : - Plugin(0), - m_plugin(plugin), + PluginWrapper(plugin), m_channels(0), m_blockSize(0), m_freqbuf(0) @@ -51,7 +50,6 @@ PluginInputDomainAdapter::~PluginInputDomainAdapter() { - delete m_plugin; } bool @@ -87,88 +85,10 @@ return m_plugin->initialise(channels, stepSize, blockSize); } -void -PluginInputDomainAdapter::reset() +Plugin::InputDomain +PluginInputDomainAdapter::getInputDomain() const { - m_plugin->reset(); -} - -unsigned int -PluginInputDomainAdapter::getVampApiVersion() const -{ - return m_plugin->getVampApiVersion(); -} - -std::string -PluginInputDomainAdapter::getIdentifier() const -{ - return m_plugin->getIdentifier(); -} - -std::string -PluginInputDomainAdapter::getName() const -{ - return m_plugin->getName(); -} - -std::string -PluginInputDomainAdapter::getDescription() const -{ - return m_plugin->getDescription(); -} - -std::string -PluginInputDomainAdapter::getMaker() const -{ - return m_plugin->getMaker(); -} - -int -PluginInputDomainAdapter::getPluginVersion() const -{ - return m_plugin->getPluginVersion(); -} - -std::string -PluginInputDomainAdapter::getCopyright() const -{ - return m_plugin->getCopyright(); -} - -PluginBase::ParameterList -PluginInputDomainAdapter::getParameterDescriptors() const -{ - return m_plugin->getParameterDescriptors(); -} - -float -PluginInputDomainAdapter::getParameter(std::string parameter) const -{ - return m_plugin->getParameter(parameter); -} - -void -PluginInputDomainAdapter::setParameter(std::string parameter, float value) -{ - m_plugin->setParameter(parameter, value); -} - -PluginBase::ProgramList -PluginInputDomainAdapter::getPrograms() const -{ - return m_plugin->getPrograms(); -} - -std::string -PluginInputDomainAdapter::getCurrentProgram() const -{ - return m_plugin->getCurrentProgram(); -} - -void -PluginInputDomainAdapter::selectProgram(std::string program) -{ - m_plugin->selectProgram(program); + return TimeDomain; } size_t @@ -195,23 +115,6 @@ return block; } -size_t -PluginInputDomainAdapter::getMinChannelCount() const -{ - return m_plugin->getMinChannelCount(); -} - -size_t PluginInputDomainAdapter::getMaxChannelCount() const -{ - return m_plugin->getMaxChannelCount(); -} - -Plugin::OutputList -PluginInputDomainAdapter::getOutputDescriptors() const -{ - return m_plugin->getOutputDescriptors(); -} - Plugin::FeatureSet PluginInputDomainAdapter::process(const float *const *inputBuffers, RealTime timestamp) { @@ -249,12 +152,6 @@ return m_plugin->process(m_freqbuf, timestamp); } -Plugin::FeatureSet -PluginInputDomainAdapter::getRemainingFeatures() -{ - return m_plugin->getRemainingFeatures(); -} - void PluginInputDomainAdapter::fft(unsigned int n, bool inverse, double *ri, double *ii, double *ro, double *io) diff -r 4ab6224110ef -r 09a1aac6c362 vamp-hostsdk/PluginInputDomainAdapter.h --- a/vamp-hostsdk/PluginInputDomainAdapter.h Fri May 04 15:21:12 2007 +0000 +++ b/vamp-hostsdk/PluginInputDomainAdapter.h Wed May 09 15:21:37 2007 +0000 @@ -36,7 +36,7 @@ #ifndef _PLUGIN_INPUT_DOMAIN_ADAPTER_H_ -#include +#include "PluginWrapper.h" namespace Vamp { @@ -62,45 +62,21 @@ //delegates all calls through to it; the subclass can then override //only the ones it needs to handle. -class PluginInputDomainAdapter : public Plugin +class PluginInputDomainAdapter : public PluginWrapper { public: PluginInputDomainAdapter(Plugin *plugin); // I take ownership of plugin virtual ~PluginInputDomainAdapter(); bool initialise(size_t channels, size_t stepSize, size_t blockSize); - void reset(); - InputDomain getInputDomain() const { return Plugin::TimeDomain; } - - unsigned int getVampApiVersion() const; - 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); - - ProgramList getPrograms() const; - std::string getCurrentProgram() const; - void selectProgram(std::string); + InputDomain getInputDomain() const; size_t getPreferredStepSize() const; size_t getPreferredBlockSize() const; - size_t getMinChannelCount() const; - size_t getMaxChannelCount() const; - - OutputList getOutputDescriptors() const; - FeatureSet process(const float *const *inputBuffers, RealTime timestamp); - FeatureSet getRemainingFeatures(); - protected: Plugin *m_plugin; size_t m_channels; diff -r 4ab6224110ef -r 09a1aac6c362 vamp-hostsdk/PluginLoader.cpp --- a/vamp-hostsdk/PluginLoader.cpp Fri May 04 15:21:12 2007 +0000 +++ b/vamp-hostsdk/PluginLoader.cpp Wed May 09 15:21:37 2007 +0000 @@ -39,8 +39,12 @@ #include "system.h" +#include + #include // POSIX directory open and read +using namespace std; + namespace Vamp { PluginLoader::PluginLoader() @@ -51,47 +55,34 @@ { } -std::vector +vector PluginLoader::listPlugins() { if (m_pluginLibraryMap.empty()) { - std::vector path = PluginHostAdapter::getPluginPath(); + vector path = PluginHostAdapter::getPluginPath(); size_t suffixLen = strlen(PLUGIN_SUFFIX); for (size_t i = 0; i < path.size(); ++i) { + + vector files = getFilesInDir(path[i], PLUGIN_SUFFIX); + - DIR *d = opendir(path[i].c_str()); - if (!d) { -// perror("Failed to open directory"); - continue; - } - - struct dirent *e = 0; - while ((e = readdir(d))) { + for (vector::iterator fi = files.begin(); + fi != files.end(); ++fi) { - if (!(e->d_type & DT_REG) || !e->d_name) { - continue; - } + string basename = *fi; + basename = basename.substr(0, basename.length() - suffixLen - 1); - int len = strlen(e->d_name); - if (len < int(suffixLen + 2) || - e->d_name[len - suffixLen - 1] != '.' || - strcmp(e->d_name + len - suffixLen, PLUGIN_SUFFIX)) { - continue; - } - - std::string basename = e->d_name; - basename = basename.substr(0, basename.length() - suffixLen - 1); - std::string fullPath = path[i].c_str(); - fullPath = fullPath + "/" + e->d_name; + string fullPath = path[i]; + fullPath = fullPath + "/" + *fi; //!!! systemize void *handle = DLOPEN(fullPath, RTLD_LAZY); if (!handle) { - std::cerr << "Vamp::PluginLoader: " << e->d_name + cerr << "Vamp::PluginLoader: " << *fi << ": unable to load library (" << DLERROR() - << ")" << std::endl; + << ")" << endl; continue; } @@ -118,13 +109,11 @@ DLCLOSE(handle); } - - closedir(d); } } - std::vector plugins; - for (std::map::iterator mi = + vector plugins; + for (map::iterator mi = m_pluginLibraryMap.begin(); mi != m_pluginLibraryMap.end(); ++mi) { plugins.push_back(mi->first); @@ -133,34 +122,42 @@ return plugins; } -std::string -PluginLoader::getLibraryPath(PluginKey key) +PluginLoader::PluginCategoryHierarchy +PluginLoader::getPluginCategory(PluginKey plugin) +{ + if (m_taxonomy.empty()) generateTaxonomy(); + if (m_taxonomy.find(plugin) == m_taxonomy.end()) return PluginCategoryHierarchy(); + return m_taxonomy[plugin]; +} + +string +PluginLoader::getLibraryPathForPlugin(PluginKey plugin) { if (m_pluginLibraryMap.empty()) (void)listPlugins(); - if (m_pluginLibraryMap.find(key) == m_pluginLibraryMap.end()) return ""; - return m_pluginLibraryMap[key]; + if (m_pluginLibraryMap.find(plugin) == m_pluginLibraryMap.end()) return ""; + return m_pluginLibraryMap[plugin]; } Plugin * PluginLoader::load(PluginKey key, float inputSampleRate) { - std::string fullPath = getLibraryPath(key); + string fullPath = getLibraryPathForPlugin(key); if (fullPath == "") return 0; - std::string::size_type ki = key.find(':'); - if (ki == std::string::npos) { + string::size_type ki = key.find(':'); + if (ki == string::npos) { //!!! flag error return 0; } - std::string identifier = key.substr(ki + 1); + string identifier = key.substr(ki + 1); void *handle = DLOPEN(fullPath, RTLD_LAZY); if (!handle) { - std::cerr << "Vamp::PluginLoader: " << fullPath + cerr << "Vamp::PluginLoader: " << fullPath << ": unable to load library (" << DLERROR() - << ")" << std::endl; + << ")" << endl; return 0; } @@ -179,7 +176,7 @@ const VampPluginDescriptor *descriptor = 0; while ((descriptor = fn(VAMP_API_VERSION, index))) { - if (std::string(descriptor->identifier) == identifier) { + if (string(descriptor->identifier) == identifier) { return new Vamp::PluginHostAdapter(descriptor, inputSampleRate); } ++index; @@ -189,5 +186,118 @@ return 0; } +vector +PluginLoader::getFilesInDir(string dir, string extension) +{ + vector files; + + DIR *d = opendir(dir.c_str()); + if (!d) return files; + + struct dirent *e = 0; + while ((e = readdir(d))) { + + if (!(e->d_type & DT_REG) || !e->d_name) { + continue; + } + + int len = strlen(e->d_name); + if (len < int(extension.length() + 2) || + e->d_name[len - extension.length() - 1] != '.' || + strcmp(e->d_name + len - extension.length(), extension.c_str())) { + continue; + } + + files.push_back(e->d_name); + } + + closedir(d); + + return files; } +void +PluginLoader::generateTaxonomy() +{ +// cerr << "PluginLoader::generateTaxonomy" << endl; + + vector path = PluginHostAdapter::getPluginPath(); + string libfragment = "/lib/"; + vector catpath; + + string suffix = "cat"; + + for (vector::iterator i = path.begin(); + i != path.end(); ++i) { + + string dir = *i; + string::size_type li = dir.find(libfragment); + + if (li != string::npos) { + catpath.push_back + (dir.substr(0, li) + + "/share/" + + dir.substr(li + libfragment.length())); + } + + catpath.push_back(dir); + } + + char buffer[1024]; + + for (vector::iterator i = catpath.begin(); + i != catpath.end(); ++i) { + + vector files = getFilesInDir(*i, suffix); + + for (vector::iterator fi = files.begin(); + fi != files.end(); ++fi) { + + string filepath = *i + "/" + *fi; //!!! systemize + ifstream is(filepath.c_str(), ifstream::in | ifstream::binary); + + if (is.fail()) { +// cerr << "failed to open: " << filepath << endl; + continue; + } + +// cerr << "opened: " << filepath << endl; + + while (!!is.getline(buffer, 1024)) { + + string line(buffer); + +// cerr << "line = " << line << endl; + + string::size_type di = line.find("::"); + if (di == string::npos) continue; + + string id = line.substr(0, di); + string encodedCat = line.substr(di + 2); + + if (id.substr(0, 5) != "vamp:") continue; + id = id.substr(5); + + while (encodedCat.length() >= 1 && + encodedCat[encodedCat.length()-1] == '\r') { + encodedCat = encodedCat.substr(0, encodedCat.length()-1); + } + +// cerr << "id = " << id << ", cat = " << encodedCat << endl; + + PluginCategoryHierarchy category; + string::size_type ai; + while ((ai = encodedCat.find(" > ")) != string::npos) { + category.push_back(encodedCat.substr(0, ai)); + encodedCat = encodedCat.substr(ai + 3); + } + if (encodedCat != "") category.push_back(encodedCat); + + m_taxonomy[id] = category; + } + } + } +} + + +} diff -r 4ab6224110ef -r 09a1aac6c362 vamp-hostsdk/PluginLoader.h --- a/vamp-hostsdk/PluginLoader.h Fri May 04 15:21:12 2007 +0000 +++ b/vamp-hostsdk/PluginLoader.h Wed May 09 15:21:37 2007 +0000 @@ -52,6 +52,7 @@ virtual ~PluginLoader(); typedef std::string PluginKey; + typedef std::vector PluginCategoryHierarchy; std::vector listPlugins(); //!!! pass in version number? @@ -59,12 +60,17 @@ //have to consider library loading issues -- do we have a wrapper //class that tells us when it's been deleted, and keep a reference //count for the dynamic library? - Plugin *load(PluginKey key, float inputSampleRate); + Plugin *load(PluginKey plugin, float inputSampleRate); - std::string getLibraryPath(PluginKey key); + PluginCategoryHierarchy getPluginCategory(PluginKey plugin); + + std::string getLibraryPathForPlugin(PluginKey plugin); protected: std::map m_pluginLibraryMap; + std::map m_taxonomy; + void generateTaxonomy(); + std::vector getFilesInDir(std::string dir, std::string ext); }; } diff -r 4ab6224110ef -r 09a1aac6c362 vamp-hostsdk/PluginWrapper.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vamp-hostsdk/PluginWrapper.cpp Wed May 09 15:21:37 2007 +0000 @@ -0,0 +1,189 @@ +/* -*- 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 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. + + 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 "PluginWrapper.h" + +namespace Vamp { + +PluginWrapper::PluginWrapper(Plugin *plugin) : + Plugin(0) +{ +} + +PluginWrapper::~PluginWrapper() +{ + delete m_plugin; +} + +bool +PluginWrapper::initialise(size_t channels, size_t stepSize, size_t blockSize) +{ + return m_plugin->initialise(channels, stepSize, blockSize); +} + +void +PluginWrapper::reset() +{ + m_plugin->reset(); +} + +Plugin::InputDomain +PluginWrapper::getInputDomain() const +{ + return m_plugin->getInputDomain(); +} + +unsigned int +PluginWrapper::getVampApiVersion() const +{ + return m_plugin->getVampApiVersion(); +} + +std::string +PluginWrapper::getIdentifier() const +{ + return m_plugin->getIdentifier(); +} + +std::string +PluginWrapper::getName() const +{ + return m_plugin->getName(); +} + +std::string +PluginWrapper::getDescription() const +{ + return m_plugin->getDescription(); +} + +std::string +PluginWrapper::getMaker() const +{ + return m_plugin->getMaker(); +} + +int +PluginWrapper::getPluginVersion() const +{ + return m_plugin->getPluginVersion(); +} + +std::string +PluginWrapper::getCopyright() const +{ + return m_plugin->getCopyright(); +} + +PluginBase::ParameterList +PluginWrapper::getParameterDescriptors() const +{ + return m_plugin->getParameterDescriptors(); +} + +float +PluginWrapper::getParameter(std::string parameter) const +{ + return m_plugin->getParameter(parameter); +} + +void +PluginWrapper::setParameter(std::string parameter, float value) +{ + m_plugin->setParameter(parameter, value); +} + +PluginBase::ProgramList +PluginWrapper::getPrograms() const +{ + return m_plugin->getPrograms(); +} + +std::string +PluginWrapper::getCurrentProgram() const +{ + return m_plugin->getCurrentProgram(); +} + +void +PluginWrapper::selectProgram(std::string program) +{ + m_plugin->selectProgram(program); +} + +size_t +PluginWrapper::getPreferredStepSize() const +{ + return m_plugin->getPreferredStepSize(); +} + +size_t +PluginWrapper::getPreferredBlockSize() const +{ + return m_plugin->getPreferredBlockSize(); +} + +size_t +PluginWrapper::getMinChannelCount() const +{ + return m_plugin->getMinChannelCount(); +} + +size_t PluginWrapper::getMaxChannelCount() const +{ + return m_plugin->getMaxChannelCount(); +} + +Plugin::OutputList +PluginWrapper::getOutputDescriptors() const +{ + return m_plugin->getOutputDescriptors(); +} + +Plugin::FeatureSet +PluginWrapper::process(const float *const *inputBuffers, RealTime timestamp) +{ + return m_plugin->process(inputBuffers, timestamp); +} + +Plugin::FeatureSet +PluginWrapper::getRemainingFeatures() +{ + return m_plugin->getRemainingFeatures(); +} + +} + diff -r 4ab6224110ef -r 09a1aac6c362 vamp-hostsdk/PluginWrapper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vamp-hostsdk/PluginWrapper.h Wed May 09 15:21:37 2007 +0000 @@ -0,0 +1,88 @@ +/* -*- 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 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. + + 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_WRAPPER_H_ + +#include + +namespace Vamp { + +class PluginWrapper : public Plugin +{ +public: + virtual ~PluginWrapper(); + + bool initialise(size_t channels, size_t stepSize, size_t blockSize); + void reset(); + + InputDomain getInputDomain() const; + + unsigned int getVampApiVersion() const; + 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); + + ProgramList getPrograms() const; + std::string getCurrentProgram() const; + void selectProgram(std::string); + + size_t getPreferredStepSize() const; + size_t getPreferredBlockSize() const; + + size_t getMinChannelCount() const; + size_t getMaxChannelCount() const; + + OutputList getOutputDescriptors() const; + + FeatureSet process(const float *const *inputBuffers, RealTime timestamp); + + FeatureSet getRemainingFeatures(); + +protected: + PluginWrapper(Plugin *plugin); // I take ownership of plugin + Plugin *m_plugin; +}; + +} + +#endif