Mercurial > hg > svcore
changeset 66:7afcfe666910
* Modify to use Vamp SDK for proper feature extraction plugins.
Requires that the vamp-plugin-sdk directory tree be present below
plugin/ (it's separate in Subversion).
author | Chris Cannam |
---|---|
date | Fri, 31 Mar 2006 15:56:35 +0000 |
parents | e1aad27029e3 |
children | eb530055ed55 |
files | base/RealTime.h plugin/DSSIPluginFactory.cpp plugin/DSSIPluginInstance.cpp plugin/DSSIPluginInstance.h plugin/FeatureExtractionPlugin.h plugin/FeatureExtractionPluginAdapter.cpp plugin/FeatureExtractionPluginAdapter.h plugin/FeatureExtractionPluginFactory.cpp plugin/FeatureExtractionPluginFactory.h plugin/FeatureExtractionPluginHostAdapter.cpp plugin/FeatureExtractionPluginHostAdapter.h plugin/LADSPAPluginInstance.cpp plugin/LADSPAPluginInstance.h plugin/PluginDescription.h plugin/PluginInstance.cpp plugin/PluginInstance.h plugin/PluginXml.cpp plugin/PluginXml.h plugin/RealTimePluginInstance.h transform/FeatureExtractionPluginTransform.cpp transform/FeatureExtractionPluginTransform.h transform/RealTimePluginTransform.cpp transform/TransformFactory.cpp |
diffstat | 23 files changed, 503 insertions(+), 1666 deletions(-) [+] |
line wrap: on
line diff
--- a/base/RealTime.h Thu Mar 30 15:00:22 2006 +0000 +++ b/base/RealTime.h Fri Mar 31 15:56:35 2006 +0000 @@ -21,6 +21,11 @@ #ifndef _REAL_TIME_H_ #define _REAL_TIME_H_ +#include "vamp-sdk/RealTime.h" +using Vamp::RealTime; + +#ifdef NOT_DEFINED + #include <iostream> #include <string> @@ -117,5 +122,7 @@ }; std::ostream &operator<<(std::ostream &out, const RealTime &rt); + +#endif #endif
--- a/plugin/DSSIPluginFactory.cpp Thu Mar 30 15:00:22 2006 +0000 +++ b/plugin/DSSIPluginFactory.cpp Fri Mar 31 15:56:35 2006 +0000 @@ -206,7 +206,10 @@ if (path == "") { path = "/usr/local/lib/dssi:/usr/lib/dssi"; char *home = getenv("HOME"); - if (home) path = std::string(home) + "/.dssi:" + path; + if (home) { + path = std::string(home) + "/dssi:" + + std::string(home) + "/.dssi:" + path; + } } std::string::size_type index = 0, newindex = 0;
--- a/plugin/DSSIPluginInstance.cpp Thu Mar 30 15:00:22 2006 +0000 +++ b/plugin/DSSIPluginInstance.cpp Fri Mar 31 15:56:35 2006 +0000 @@ -253,7 +253,7 @@ #endif if (m_latencyPort) { - if (!m_run) run(RealTime::zeroTime); + if (!m_run) run(Vamp::RealTime::zeroTime); latency = (size_t)(*m_latencyPort + 0.1); } @@ -850,7 +850,7 @@ } void -DSSIPluginInstance::sendEvent(const RealTime &eventTime, +DSSIPluginInstance::sendEvent(const Vamp::RealTime &eventTime, const void *e) { #ifdef DEBUG_DSSI_PROCESS @@ -926,7 +926,7 @@ } void -DSSIPluginInstance::run(const RealTime &blockTime) +DSSIPluginInstance::run(const Vamp::RealTime &blockTime) { static snd_seq_event_t localEventBuffer[EVENT_BUFFER_SIZE]; int evCount = 0; @@ -980,11 +980,11 @@ *ev = m_eventBuffer.peekOne(); bool accept = true; - RealTime evTime(ev->time.time.tv_sec, ev->time.time.tv_nsec); + Vamp::RealTime evTime(ev->time.time.tv_sec, ev->time.time.tv_nsec); int frameOffset = 0; if (evTime > blockTime) { - frameOffset = RealTime::realTime2Frame(evTime - blockTime, m_sampleRate); + frameOffset = Vamp::RealTime::realTime2Frame(evTime - blockTime, m_sampleRate); } #ifdef DEBUG_DSSI_PROCESS @@ -1084,7 +1084,7 @@ } void -DSSIPluginInstance::runGrouped(const RealTime &blockTime) +DSSIPluginInstance::runGrouped(const Vamp::RealTime &blockTime) { // If something else in our group has just been called for this // block time (but we haven't) then we should just write out the @@ -1156,11 +1156,11 @@ *ev = instance->m_eventBuffer.peekOne(); bool accept = true; - RealTime evTime(ev->time.time.tv_sec, ev->time.time.tv_nsec); + Vamp::RealTime evTime(ev->time.time.tv_sec, ev->time.time.tv_nsec); int frameOffset = 0; if (evTime > blockTime) { - frameOffset = RealTime::realTime2Frame(evTime - blockTime, m_sampleRate); + frameOffset = Vamp::RealTime::realTime2Frame(evTime - blockTime, m_sampleRate); } #ifdef DEBUG_DSSI_PROCESS
--- a/plugin/DSSIPluginInstance.h Thu Mar 30 15:00:22 2006 +0000 +++ b/plugin/DSSIPluginInstance.h Fri Mar 31 15:56:35 2006 +0000 @@ -53,7 +53,7 @@ virtual int getPluginVersion() const; virtual std::string getCopyright() const; - virtual void run(const RealTime &); + virtual void run(const Vamp::RealTime &); virtual unsigned int getParameterCount() const; virtual void setParameterValue(unsigned int parameter, float value); @@ -65,7 +65,7 @@ virtual void setParameter(std::string, float); virtual std::string configure(std::string key, std::string value); - virtual void sendEvent(const RealTime &eventTime, + virtual void sendEvent(const Vamp::RealTime &eventTime, const void *event); virtual void clearEvents(); @@ -126,7 +126,7 @@ void checkProgramCache() const; void initialiseGroupMembership(); - void runGrouped(const RealTime &); + void runGrouped(const Vamp::RealTime &); // For use in DSSIPluginFactory (set in the DSSI_Host_Descriptor): static int requestMidiSend(LADSPA_Handle instance, @@ -183,9 +183,9 @@ bool m_bypassed; std::string m_program; bool m_grouped; - RealTime m_lastRunTime; + Vamp::RealTime m_lastRunTime; - RealTime m_lastEventSendTime; + Vamp::RealTime m_lastEventSendTime; bool m_haveLastEventSendTime; QMutex m_processLock;
--- a/plugin/FeatureExtractionPlugin.h Thu Mar 30 15:00:22 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,318 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - Sonic Visualiser - An audio file viewer and annotation editor. - 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 _FEATURE_EXTRACTION_PLUGIN_H_ -#define _FEATURE_EXTRACTION_PLUGIN_H_ - -#include "PluginInstance.h" - -#include <string> -#include <vector> -#include <map> - -#include "base/RealTime.h" - -/** - * FeatureExtractionPlugin is a base class for plugin instance classes - * that provide feature extraction from audio or related data. - * - * In most cases, the input will be audio and the output will be a - * stream of derived data at a lower sampling resolution than the - * input. - * - * Note that this class inherits several abstract methods from - * PluginInstance, that must be implemented by the subclass. - */ - -/** - * Plugin Lifecycle - * ================ - * - * Feature extraction plugins are managed differently from real-time - * plugins. The main difference is that the parameters for a feature - * extraction plugin are configured before the plugin is used, and do - * not change during use. - * - * 1. Host constructs the plugin, passing it the input sample rate. - * The plugin may do basic initialisation, but should not do anything - * computationally expensive at this point. - * - * 2. Host may query the plugin's available outputs. - * - * 3. Host queries programs and parameter descriptors, and may set - * some or all of them. Parameters that are not explicitly set should - * take their default values as specified in the parameter descriptor. - * When a program is set, the parameter values may change and the host - * will re-query them to check. - * - * 4. Host queries the preferred step size, block size, number of - * channels, and the number of values per feature for the plugin's - * outputs. These may all vary depending on the parameter values. - * - * 5. Plugin is properly initialised with a call to initialise. This - * fixes the step size, block size, and number of channels, as well as - * all of the parameter and program settings. If the values passed in - * to initialise do not match the plugin's advertised preferred values - * from step 4, the plugin may refuse to initialise and return false - * (although if possible it should accept the new values). - * - * 6. Host will repeatedly call the process method to pass in blocks - * of input data. This method may return features extracted from that - * data (if the plugin is causal). - * - * 7. Host will call getRemainingFeatures exactly once, after all the - * input data has been processed. This may return any non-causal or - * leftover features. - * - * 8. At any point after initialise was called, the host may - * optionally call the reset method and restart processing. (This - * does not mean it can change the parameters, which are fixed from - * initialise until destruction.) - * - * A plugin does not need to handle the case where setParameter or - * selectProgram is called after initialise has been called. It's the - * host's responsibility not to do that. - */ - -class FeatureExtractionPlugin : public PluginInstance -{ -public: - /** - * Initialise a plugin to prepare it for use with the given number - * of input channels, step size (window increment, in sample - * frames) and block size (window size, in sample frames). - * - * The input sample rate should have been already specified at - * construction time. - * - * Return true for successful initialisation, false if the number - * of input channels, step size and/or block size cannot be - * supported. - */ - virtual bool initialise(size_t inputChannels, - size_t stepSize, - size_t blockSize) = 0; - - /** - * Reset the plugin after use, to prepare it for another clean - * run. Not called for the first initialisation (i.e. initialise - * must also do a reset). - */ - virtual void reset() = 0; - - /** - * Get the preferred step size (window increment -- the distance - * in sample frames between the start frames of consecutive blocks - * passed to the process() function) for the plugin. This should - * be called before initialise(). - */ - virtual size_t getPreferredStepSize() const = 0; - - /** - * Get the preferred block size (window size -- the number of - * sample frames passed in each block to the process() function). - * This should be called before initialise(). - */ - virtual size_t getPreferredBlockSize() const { return getPreferredStepSize(); } - - /** - * Get the minimum supported number of input channels. - */ - virtual size_t getMinChannelCount() const { return 1; } - - /** - * Get the maximum supported number of input channels. - */ - virtual size_t getMaxChannelCount() const { return 1; } - - struct OutputDescriptor - { - /** - * The name of the output, in computer-usable form. Should be - * reasonably short and without whitespace or punctuation. - */ - std::string name; - - /** - * The human-readable name of the output. - */ - std::string description; - - /** - * The unit of the output, in human-readable form. - */ - std::string unit; - - /** - * True if the output has the same number of values per result - * for every output result. Outputs for which this is false - * are unlikely to be very useful in a general-purpose host. - */ - bool hasFixedValueCount; - - /** - * The number of values per result of the output. Undefined - * if hasFixedValueCount is false. If this is zero, the output - * is point data (i.e. only the time of each output is of - * interest, the value list will be empty). - * - * Note that this gives the number of values of a single - * output result, not of the output stream (which has one more - * dimension: time). - */ - size_t valueCount; - - /** - * The names of each of the values, if appropriate. This is - * always optional. - */ - std::vector<std::string> valueNames; - - /** - * True if the results in the output have a fixed numeric - * range (minimum and maximum values). Undefined if - * valueCount is zero. - */ - bool hasKnownExtents; - - /** - * Minimum value of the results in the output. Undefined if - * hasKnownExtents is false or valueCount is zero. - */ - float minValue; - - /** - * Maximum value of the results in the output. Undefined if - * hasKnownExtents is false or valueCount is zero. - */ - float maxValue; - - /** - * True if the output values are quantized to a particular - * resolution. Undefined if valueCount is zero. - */ - bool isQuantized; - - /** - * Quantization resolution of the output values (e.g. 1.0 if - * they are all integers). Undefined if isQuantized is false - * or valueCount is zero. - */ - float quantizeStep; - - enum SampleType { - - /// Results from each process() align with that call's block start - OneSamplePerStep, - - /// Results are evenly spaced in time (sampleRate specified below) - FixedSampleRate, - - /// Results are unevenly spaced and have individual timestamps - VariableSampleRate - }; - - /** - * Positioning in time of the output results. - */ - SampleType sampleType; - - /** - * Sample rate of the output results. Undefined if sampleType - * is OneSamplePerStep. - * - * If sampleType is VariableSampleRate and this value is - * non-zero, then it may be used to calculate a resolution for - * the output (i.e. the "duration" of each value, in time). - * It's recommended to set this to zero if that behaviour is - * not desired. - */ - float sampleRate; - }; - - typedef std::vector<OutputDescriptor> OutputList; - - /** - * Get the outputs of this plugin. An output's index in this list - * is used as its numeric index when looking it up in the - * FeatureSet returned from the process() call. - */ - virtual OutputList getOutputDescriptors() const = 0; - - struct Feature - { - /** - * True if an output feature has its own timestamp. This is - * mandatory if the output has VariableSampleRate, and is - * likely to be disregarded otherwise. - */ - bool hasTimestamp; - - /** - * Timestamp of the output feature. This is mandatory if the - * output has VariableSampleRate, and is likely to be - * disregarded otherwise. Undefined if hasTimestamp is false. - */ - RealTime timestamp; - - /** - * Results for a single sample of this feature. If the output - * hasFixedValueCount, there must be the same number of values - * as the output's valueCount count. - */ - std::vector<float> values; - - /** - * Label for the sample of this feature. - */ - std::string label; - }; - - typedef std::vector<Feature> FeatureList; - typedef std::map<int, FeatureList> FeatureSet; // key is output no - - /** - * Process a single block of input data. inputBuffers points to - * one array of floats per input channel, and each of those arrays - * contains the blockSize number of samples (the host will - * zero-pad as necessary). The timestamp is the real time in - * seconds of the start of the supplied block of samples. - * - * Return any features that have become available after this - * process call. (These do not necessarily have to fall within - * the process block, except for OneSamplePerStep outputs.) - */ - virtual FeatureSet process(float **inputBuffers, - RealTime timestamp) = 0; - - /** - * After all blocks have been processed, calculate and return any - * remaining features derived from the complete input. - */ - virtual FeatureSet getRemainingFeatures() = 0; - - virtual std::string getType() const { return "Feature Extraction Plugin"; } - -protected: - FeatureExtractionPlugin(float inputSampleRate) : - m_inputSampleRate(inputSampleRate) { } - - float m_inputSampleRate; -}; - -#endif - - -
--- a/plugin/FeatureExtractionPluginAdapter.cpp Thu Mar 30 15:00:22 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,439 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - Sonic Visualiser - An audio file viewer and annotation editor. - 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 "FeatureExtractionPluginAdapter.h" - -FeatureExtractionPluginAdapterBase::FeatureExtractionPluginAdapterBase() : - m_populated(false) -{ -} - -const SVPPluginDescriptor * -FeatureExtractionPluginAdapterBase::getDescriptor() -{ - if (m_populated) return &m_descriptor; - - FeatureExtractionPlugin *plugin = createPlugin(48000); - - m_parameters = plugin->getParameterDescriptors(); - m_programs = plugin->getPrograms(); - - m_descriptor.name = strdup(plugin->getName().c_str()); - m_descriptor.description = strdup(plugin->getDescription().c_str()); - m_descriptor.maker = strdup(plugin->getMaker().c_str()); - m_descriptor.pluginVersion = plugin->getPluginVersion(); - m_descriptor.copyright = strdup(plugin->getCopyright().c_str()); - - m_descriptor.parameterCount = m_parameters.size(); - m_descriptor.parameters = (const SVPParameterDescriptor **) - malloc(m_parameters.size() * sizeof(SVPParameterDescriptor)); - - for (unsigned int i = 0; i < m_parameters.size(); ++i) { - SVPParameterDescriptor *desc = (SVPParameterDescriptor *) - malloc(sizeof(SVPParameterDescriptor)); - desc->name = strdup(m_parameters[i].name.c_str()); - desc->description = strdup(m_parameters[i].description.c_str()); - desc->unit = strdup(m_parameters[i].unit.c_str()); - desc->minValue = m_parameters[i].minValue; - desc->maxValue = m_parameters[i].maxValue; - desc->defaultValue = m_parameters[i].defaultValue; - desc->isQuantized = m_parameters[i].isQuantized; - desc->quantizeStep = m_parameters[i].quantizeStep; - m_descriptor.parameters[i] = desc; - } - - m_descriptor.programCount = m_programs.size(); - m_descriptor.programs = (const char **) - malloc(m_programs.size() * sizeof(const char *)); - - for (unsigned int i = 0; i < m_programs.size(); ++i) { - m_descriptor.programs[i] = strdup(m_programs[i].c_str()); - } - - m_descriptor.instantiate = svpInstantiate; - m_descriptor.cleanup = svpCleanup; - m_descriptor.initialise = svpInitialise; - m_descriptor.reset = svpReset; - m_descriptor.getParameter = svpGetParameter; - m_descriptor.setParameter = svpSetParameter; - m_descriptor.getCurrentProgram = svpGetCurrentProgram; - m_descriptor.selectProgram = svpSelectProgram; - m_descriptor.getPreferredStepSize = svpGetPreferredStepSize; - m_descriptor.getPreferredBlockSize = svpGetPreferredBlockSize; - m_descriptor.getMinChannelCount = svpGetMinChannelCount; - m_descriptor.getMaxChannelCount = svpGetMaxChannelCount; - m_descriptor.getOutputCount = svpGetOutputCount; - m_descriptor.getOutputDescriptor = svpGetOutputDescriptor; - m_descriptor.releaseOutputDescriptor = svpReleaseOutputDescriptor; - m_descriptor.process = svpProcess; - m_descriptor.getRemainingFeatures = svpGetRemainingFeatures; - m_descriptor.releaseFeatureSet = svpReleaseFeatureSet; - - m_adapterMap[&m_descriptor] = this; - - delete plugin; - - m_populated = true; - return &m_descriptor; -} - -FeatureExtractionPluginAdapterBase::~FeatureExtractionPluginAdapterBase() -{ - if (!m_populated) return; - - free((void *)m_descriptor.name); - free((void *)m_descriptor.description); - free((void *)m_descriptor.maker); - free((void *)m_descriptor.copyright); - - for (unsigned int i = 0; i < m_descriptor.parameterCount; ++i) { - const SVPParameterDescriptor *desc = m_descriptor.parameters[i]; - free((void *)desc->name); - free((void *)desc->description); - free((void *)desc->unit); - } - free((void *)m_descriptor.parameters); - - for (unsigned int i = 0; i < m_descriptor.programCount; ++i) { - free((void *)m_descriptor.programs[i]); - } - free((void *)m_descriptor.programs); - - m_adapterMap.erase(&m_descriptor); -} - -FeatureExtractionPluginAdapterBase * -FeatureExtractionPluginAdapterBase::lookupAdapter(SVPPluginHandle handle) -{ - AdapterMap::const_iterator i = m_adapterMap.find(handle); - if (i == m_adapterMap.end()) return 0; - return i->second; -} - -SVPPluginHandle -FeatureExtractionPluginAdapterBase::svpInstantiate(const SVPPluginDescriptor *desc, - float inputSampleRate) -{ - if (m_adapterMap.find(desc) == m_adapterMap.end()) return 0; - FeatureExtractionPluginAdapterBase *adapter = m_adapterMap[desc]; - if (desc != &adapter->m_descriptor) return 0; - - FeatureExtractionPlugin *plugin = adapter->createPlugin(inputSampleRate); - if (plugin) { - m_adapterMap[plugin] = adapter; - } - - return plugin; -} - -void -FeatureExtractionPluginAdapterBase::svpCleanup(SVPPluginHandle handle) -{ - FeatureExtractionPluginAdapterBase *adapter = lookupAdapter(handle); - if (!adapter) { - delete ((FeatureExtractionPlugin *)handle); - return; - } - adapter->cleanup(((FeatureExtractionPlugin *)handle)); -} - -int -FeatureExtractionPluginAdapterBase::svpInitialise(SVPPluginHandle handle, - unsigned int channels, - unsigned int stepSize, - unsigned int blockSize) -{ - bool result = ((FeatureExtractionPlugin *)handle)->initialise - (channels, stepSize, blockSize); - return result ? 1 : 0; -} - -void -FeatureExtractionPluginAdapterBase::svpReset(SVPPluginHandle handle) -{ - ((FeatureExtractionPlugin *)handle)->reset(); -} - -float -FeatureExtractionPluginAdapterBase::svpGetParameter(SVPPluginHandle handle, - int param) -{ - FeatureExtractionPluginAdapterBase *adapter = lookupAdapter(handle); - if (!adapter) return 0.0; - FeatureExtractionPlugin::ParameterList &list = adapter->m_parameters; - return ((FeatureExtractionPlugin *)handle)->getParameter(list[param].name); -} - -void -FeatureExtractionPluginAdapterBase::svpSetParameter(SVPPluginHandle handle, - int param, float value) -{ - FeatureExtractionPluginAdapterBase *adapter = lookupAdapter(handle); - if (!adapter) return; - FeatureExtractionPlugin::ParameterList &list = adapter->m_parameters; - ((FeatureExtractionPlugin *)handle)->setParameter(list[param].name, value); -} - -unsigned int -FeatureExtractionPluginAdapterBase::svpGetCurrentProgram(SVPPluginHandle handle) -{ - FeatureExtractionPluginAdapterBase *adapter = lookupAdapter(handle); - if (!adapter) return 0; - FeatureExtractionPlugin::ProgramList &list = adapter->m_programs; - std::string program = ((FeatureExtractionPlugin *)handle)->getCurrentProgram(); - for (unsigned int i = 0; i < list.size(); ++i) { - if (list[i] == program) return i; - } - return 0; -} - -void -FeatureExtractionPluginAdapterBase::svpSelectProgram(SVPPluginHandle handle, - unsigned int program) -{ - FeatureExtractionPluginAdapterBase *adapter = lookupAdapter(handle); - if (!adapter) return; - FeatureExtractionPlugin::ProgramList &list = adapter->m_programs; - ((FeatureExtractionPlugin *)handle)->selectProgram(list[program]); -} - -unsigned int -FeatureExtractionPluginAdapterBase::svpGetPreferredStepSize(SVPPluginHandle handle) -{ - return ((FeatureExtractionPlugin *)handle)->getPreferredStepSize(); -} - -unsigned int -FeatureExtractionPluginAdapterBase::svpGetPreferredBlockSize(SVPPluginHandle handle) -{ - return ((FeatureExtractionPlugin *)handle)->getPreferredBlockSize(); -} - -unsigned int -FeatureExtractionPluginAdapterBase::svpGetMinChannelCount(SVPPluginHandle handle) -{ - return ((FeatureExtractionPlugin *)handle)->getMinChannelCount(); -} - -unsigned int -FeatureExtractionPluginAdapterBase::svpGetMaxChannelCount(SVPPluginHandle handle) -{ - return ((FeatureExtractionPlugin *)handle)->getMaxChannelCount(); -} - -unsigned int -FeatureExtractionPluginAdapterBase::svpGetOutputCount(SVPPluginHandle handle) -{ - FeatureExtractionPluginAdapterBase *adapter = lookupAdapter(handle); - if (!adapter) return 0; - return adapter->getOutputCount((FeatureExtractionPlugin *)handle); -} - -SVPOutputDescriptor * -FeatureExtractionPluginAdapterBase::svpGetOutputDescriptor(SVPPluginHandle handle, - unsigned int i) -{ - FeatureExtractionPluginAdapterBase *adapter = lookupAdapter(handle); - if (!adapter) return 0; - return adapter->getOutputDescriptor((FeatureExtractionPlugin *)handle, i); -} - -void -FeatureExtractionPluginAdapterBase::svpReleaseOutputDescriptor(SVPOutputDescriptor *desc) -{ - if (desc->name) free((void *)desc->name); - if (desc->description) free((void *)desc->description); - if (desc->unit) free((void *)desc->unit); - for (unsigned int i = 0; i < desc->valueCount; ++i) { - free((void *)desc->valueNames[i]); - } - if (desc->valueNames) free((void *)desc->valueNames); - free((void *)desc); -} - -SVPFeatureList ** -FeatureExtractionPluginAdapterBase::svpProcess(SVPPluginHandle handle, - float **inputBuffers, - int sec, - int nsec) -{ - FeatureExtractionPluginAdapterBase *adapter = lookupAdapter(handle); - if (!adapter) return 0; - return adapter->process((FeatureExtractionPlugin *)handle, - inputBuffers, sec, nsec); -} - -SVPFeatureList ** -FeatureExtractionPluginAdapterBase::svpGetRemainingFeatures(SVPPluginHandle handle) -{ - FeatureExtractionPluginAdapterBase *adapter = lookupAdapter(handle); - if (!adapter) return 0; - return adapter->getRemainingFeatures((FeatureExtractionPlugin *)handle); -} - -void -FeatureExtractionPluginAdapterBase::svpReleaseFeatureSet(SVPFeatureList **fs) -{ - if (!fs) return; - for (unsigned int i = 0; fs[i]; ++i) { - for (unsigned int j = 0; j < fs[i]->featureCount; ++j) { - SVPFeature *feature = &fs[i]->features[j]; - if (feature->values) free((void *)feature->values); - if (feature->label) free((void *)feature->label); - free((void *)feature); - } - if (fs[i]->features) free((void *)fs[i]->features); - free((void *)fs[i]); - } - free((void *)fs); -} - -void -FeatureExtractionPluginAdapterBase::cleanup(FeatureExtractionPlugin *plugin) -{ - if (m_pluginOutputs.find(plugin) != m_pluginOutputs.end()) { - delete m_pluginOutputs[plugin]; - m_pluginOutputs.erase(plugin); - } - m_adapterMap.erase(plugin); - delete ((FeatureExtractionPlugin *)plugin); -} - -void -FeatureExtractionPluginAdapterBase::checkOutputMap(FeatureExtractionPlugin *plugin) -{ - if (!m_pluginOutputs[plugin]) { - m_pluginOutputs[plugin] = new FeatureExtractionPlugin::OutputList - (plugin->getOutputDescriptors()); - } -} - -unsigned int -FeatureExtractionPluginAdapterBase::getOutputCount(FeatureExtractionPlugin *plugin) -{ - checkOutputMap(plugin); - return m_pluginOutputs[plugin]->size(); -} - -SVPOutputDescriptor * -FeatureExtractionPluginAdapterBase::getOutputDescriptor(FeatureExtractionPlugin *plugin, - unsigned int i) -{ - checkOutputMap(plugin); - FeatureExtractionPlugin::OutputDescriptor &od = - (*m_pluginOutputs[plugin])[i]; - - SVPOutputDescriptor *desc = (SVPOutputDescriptor *) - malloc(sizeof(SVPOutputDescriptor)); - - desc->name = strdup(od.name.c_str()); - desc->description = strdup(od.description.c_str()); - desc->unit = strdup(od.unit.c_str()); - desc->hasFixedValueCount = od.hasFixedValueCount; - desc->valueCount = od.valueCount; - - desc->valueNames = (const char **) - malloc(od.valueCount * sizeof(const char *)); - - for (unsigned int i = 0; i < od.valueCount; ++i) { - desc->valueNames[i] = strdup(od.valueNames[i].c_str()); - } - - desc->hasKnownExtents = od.hasKnownExtents; - desc->minValue = od.minValue; - desc->maxValue = od.maxValue; - desc->isQuantized = od.isQuantized; - desc->quantizeStep = od.quantizeStep; - - switch (od.sampleType) { - case FeatureExtractionPlugin::OutputDescriptor::OneSamplePerStep: - desc->sampleType = svpOneSamplePerStep; break; - case FeatureExtractionPlugin::OutputDescriptor::FixedSampleRate: - desc->sampleType = svpFixedSampleRate; break; - case FeatureExtractionPlugin::OutputDescriptor::VariableSampleRate: - desc->sampleType = svpVariableSampleRate; break; - } - - desc->sampleRate = od.sampleRate; - - return desc; -} - -SVPFeatureList ** -FeatureExtractionPluginAdapterBase::process(FeatureExtractionPlugin *plugin, - float **inputBuffers, - int sec, int nsec) -{ - RealTime rt(sec, nsec); - return convertFeatures(plugin->process(inputBuffers, rt)); -} - -SVPFeatureList ** -FeatureExtractionPluginAdapterBase::getRemainingFeatures(FeatureExtractionPlugin *plugin) -{ - return convertFeatures(plugin->getRemainingFeatures()); -} - -SVPFeatureList ** -FeatureExtractionPluginAdapterBase::convertFeatures(const FeatureExtractionPlugin::FeatureSet &features) -{ - unsigned int n = 0; - if (features.begin() != features.end()) { - FeatureExtractionPlugin::FeatureSet::const_iterator i = features.end(); - --i; - n = i->first + 1; - } - - if (!n) return 0; - - SVPFeatureList **fs = (SVPFeatureList **) - malloc((n + 1) * sizeof(SVPFeatureList *)); - - for (unsigned int i = 0; i < n; ++i) { - fs[i] = (SVPFeatureList *)malloc(sizeof(SVPFeatureList)); - if (features.find(i) == features.end()) { - fs[i]->featureCount = 0; - fs[i]->features = 0; - } else { - FeatureExtractionPlugin::FeatureSet::const_iterator fi = - features.find(i); - const FeatureExtractionPlugin::FeatureList &fl = fi->second; - fs[i]->featureCount = fl.size(); - fs[i]->features = (SVPFeature *)malloc(fl.size() * - sizeof(SVPFeature)); - for (unsigned int j = 0; j < fl.size(); ++j) { - fs[i]->features[j].hasTimestamp = fl[j].hasTimestamp; - fs[i]->features[j].sec = fl[j].timestamp.sec; - fs[i]->features[j].nsec = fl[j].timestamp.nsec; - fs[i]->features[j].valueCount = fl[j].values.size(); - fs[i]->features[j].values = (float *)malloc - (fs[i]->features[j].valueCount * sizeof(float)); - for (unsigned int k = 0; k < fs[i]->features[j].valueCount; ++k) { - fs[i]->features[j].values[k] = fl[j].values[k]; - } - fs[i]->features[j].label = strdup(fl[j].label.c_str()); - } - } - } - - fs[n] = 0; - - return fs; -} - -FeatureExtractionPluginAdapterBase::AdapterMap -FeatureExtractionPluginAdapterBase::m_adapterMap; - -
--- a/plugin/FeatureExtractionPluginAdapter.h Thu Mar 30 15:00:22 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,126 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - Sonic Visualiser - An audio file viewer and annotation editor. - 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 _FEATURE_EXTRACTION_PLUGIN_ADAPTER_H_ -#define _FEATURE_EXTRACTION_PLUGIN_ADAPTER_H_ - -#include "api/svp.h" -#include "FeatureExtractionPlugin.h" - -#include <map> - -class FeatureExtractionPluginAdapterBase -{ -public: - virtual ~FeatureExtractionPluginAdapterBase(); - const SVPPluginDescriptor *getDescriptor(); - -protected: - FeatureExtractionPluginAdapterBase(); - - virtual FeatureExtractionPlugin *createPlugin(float inputSampleRate) = 0; - - static SVPPluginHandle svpInstantiate(const SVPPluginDescriptor *desc, - float inputSampleRate); - - static void svpCleanup(SVPPluginHandle handle); - - static int svpInitialise(SVPPluginHandle handle, unsigned int channels, - unsigned int stepSize, unsigned int blockSize); - - static void svpReset(SVPPluginHandle handle); - - static float svpGetParameter(SVPPluginHandle handle, int param); - static void svpSetParameter(SVPPluginHandle handle, int param, float value); - - static unsigned int svpGetCurrentProgram(SVPPluginHandle handle); - static void svpSelectProgram(SVPPluginHandle handle, unsigned int program); - - static unsigned int svpGetPreferredStepSize(SVPPluginHandle handle); - static unsigned int svpGetPreferredBlockSize(SVPPluginHandle handle); - static unsigned int svpGetMinChannelCount(SVPPluginHandle handle); - static unsigned int svpGetMaxChannelCount(SVPPluginHandle handle); - - static unsigned int svpGetOutputCount(SVPPluginHandle handle); - - static SVPOutputDescriptor *svpGetOutputDescriptor(SVPPluginHandle handle, - unsigned int i); - - static void svpReleaseOutputDescriptor(SVPOutputDescriptor *desc); - - static SVPFeatureList **svpProcess(SVPPluginHandle handle, - float **inputBuffers, - int sec, - int nsec); - - static SVPFeatureList **svpGetRemainingFeatures(SVPPluginHandle handle); - - static void svpReleaseFeatureSet(SVPFeatureList **fs); - - void cleanup(FeatureExtractionPlugin *plugin); - void checkOutputMap(FeatureExtractionPlugin *plugin); - unsigned int getOutputCount(FeatureExtractionPlugin *plugin); - SVPOutputDescriptor *getOutputDescriptor(FeatureExtractionPlugin *plugin, - unsigned int i); - SVPFeatureList **process(FeatureExtractionPlugin *plugin, - float **inputBuffers, - int sec, int nsec); - SVPFeatureList **getRemainingFeatures(FeatureExtractionPlugin *plugin); - SVPFeatureList **convertFeatures(const FeatureExtractionPlugin::FeatureSet &features); - - typedef std::map<const void *, FeatureExtractionPluginAdapterBase *> AdapterMap; - static AdapterMap m_adapterMap; - static FeatureExtractionPluginAdapterBase *lookupAdapter(SVPPluginHandle); - - bool m_populated; - SVPPluginDescriptor m_descriptor; - FeatureExtractionPlugin::ParameterList m_parameters; - FeatureExtractionPlugin::ProgramList m_programs; - - typedef std::map<FeatureExtractionPlugin *, - FeatureExtractionPlugin::OutputList *> OutputMap; - OutputMap m_pluginOutputs; - - typedef std::map<FeatureExtractionPlugin *, - SVPFeature ***> FeatureBufferMap; - FeatureBufferMap m_pluginFeatures; -}; - -template <typename Plugin> -class FeatureExtractionPluginAdapter : public FeatureExtractionPluginAdapterBase -{ -public: - FeatureExtractionPluginAdapter() : FeatureExtractionPluginAdapterBase() { } - ~FeatureExtractionPluginAdapter() { } - -protected: - FeatureExtractionPlugin *createPlugin(float inputSampleRate) { - Plugin *plugin = new Plugin(inputSampleRate); - FeatureExtractionPlugin *fep = - dynamic_cast<FeatureExtractionPlugin *>(plugin); - if (!fep) { - std::cerr << "ERROR: FeatureExtractionPlugin::createPlugin: " - << "Plugin is not a feature extraction plugin" - << std::endl; - delete plugin; - return 0; - } - return fep; - } -}; - - -#endif -
--- a/plugin/FeatureExtractionPluginFactory.cpp Thu Mar 30 15:00:22 2006 +0000 +++ b/plugin/FeatureExtractionPluginFactory.cpp Fri Mar 31 15:56:35 2006 +0000 @@ -22,6 +22,15 @@ #include "plugins/SpectralCentroid.h" //!!! #include "plugins/TonalChangeDetect.h" //!!! +#include "vamp/vamp.h" +#include "vamp-sdk/PluginHostAdapter.h" + +#include "base/System.h" + +#include <QDir> +#include <QFile> +#include <QFileInfo> + #include <iostream> static FeatureExtractionPluginFactory *_nativeInstance = 0; @@ -29,7 +38,7 @@ FeatureExtractionPluginFactory * FeatureExtractionPluginFactory::instance(QString pluginType) { - if (pluginType == "sv") { + if (pluginType == "vamp" || pluginType == "sv") { //!!! if (!_nativeInstance) { std::cerr << "FeatureExtractionPluginFactory::instance(" << pluginType.toStdString() << "): creating new FeatureExtractionPluginFactory" << std::endl; @@ -50,12 +59,43 @@ } std::vector<QString> +FeatureExtractionPluginFactory::getPluginPath() +{ + std::vector<QString> path; + std::string envPath; + + char *cpath = getenv("Vamp_PATH"); + if (cpath) envPath = cpath; + + if (envPath == "") { + //!!! system dependent + envPath = "/usr/local/lib/vamp:/usr/lib/vamp"; + char *chome = getenv("HOME"); + if (chome) { + envPath = std::string(chome) + "/vamp:" + + std::string(chome) + "/.vamp:" + envPath; + } + } + + std::string::size_type index = 0, newindex = 0; + + while ((newindex = envPath.find(':', index)) < envPath.size()) { + path.push_back(envPath.substr(index, newindex - index).c_str()); + index = newindex + 1; + } + + path.push_back(envPath.substr(index).c_str()); + + return path; +} + +std::vector<QString> FeatureExtractionPluginFactory::getAllPluginIdentifiers() { FeatureExtractionPluginFactory *factory; std::vector<QString> rv; - factory = instance("sv"); + factory = instance("vamp"); if (factory) { std::vector<QString> tmp = factory->getPluginIdentifiers(); for (size_t i = 0; i < tmp.size(); ++i) { @@ -77,48 +117,196 @@ rv.push_back("sv:_builtin:zerocrossing"); //!!! rv.push_back("sv:_builtin:spectralcentroid"); //!!! rv.push_back("sv:_builtin:tonalchange"); //!!! + + std::vector<QString> path = getPluginPath(); + + for (std::vector<QString>::iterator i = path.begin(); i != path.end(); ++i) { + + std::cerr << "FeatureExtractionPluginFactory::getPluginIdentifiers: scanning directory " << i->toStdString() << std::endl; + + QDir pluginDir(*i, PLUGIN_GLOB, + QDir::Name | QDir::IgnoreCase, + QDir::Files | QDir::Readable); + + for (unsigned int j = 0; j < pluginDir.count(); ++j) { + + QString soname = pluginDir.filePath(pluginDir[j]); + + void *libraryHandle = DLOPEN(soname, RTLD_LAZY); + + if (!libraryHandle) { + std::cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: Failed to load library " << soname.toStdString() << std::endl; + continue; + } + + VampGetPluginDescriptorFunction fn = (VampGetPluginDescriptorFunction) + DLSYM(libraryHandle, "vampGetPluginDescriptor"); + + if (!fn) { + std::cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: No descriptor function in " << soname.toStdString() << std::endl; + if (DLCLOSE(libraryHandle) != 0) { + std::cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: Failed to unload library " << soname.toStdString() << std::endl; + } + continue; + } + + const VampPluginDescriptor *descriptor = 0; + int index = 0; + + while ((descriptor = fn(index))) { + QString id = QString("vamp:%1:%2").arg(soname).arg(descriptor->name); + rv.push_back(id); + std::cerr << "Found id " << id.toStdString() << std::endl; + ++index; + } + + if (DLCLOSE(libraryHandle) != 0) { + std::cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: Failed to unload library " << soname.toStdString() << std::endl; + } + } + } + return rv; } -FeatureExtractionPlugin * +QString +FeatureExtractionPluginFactory::findPluginFile(QString soname, QString inDir) +{ + QString file = ""; + + if (inDir != "") { + + QDir dir(inDir, PLUGIN_GLOB, + QDir::Name | QDir::IgnoreCase, + QDir::Files | QDir::Readable); + if (!dir.exists()) return ""; + + file = dir.filePath(QFileInfo(soname).fileName()); + if (QFileInfo(file).exists()) { + return file; + } + + for (unsigned int j = 0; j < dir.count(); ++j) { + file = dir.filePath(dir[j]); + if (QFileInfo(file).baseName() == QFileInfo(soname).baseName()) { + return file; + } + } + + return ""; + + } else { + + QFileInfo fi(soname); + if (fi.exists()) return soname; + + if (fi.isAbsolute() && fi.absolutePath() != "") { + file = findPluginFile(soname, fi.absolutePath()); + if (file != "") return file; + } + + std::vector<QString> path = getPluginPath(); + for (std::vector<QString>::iterator i = path.begin(); + i != path.end(); ++i) { + if (*i != "") { + file = findPluginFile(soname, *i); + if (file != "") return file; + } + } + + return ""; + } +} + +Vamp::Plugin * FeatureExtractionPluginFactory::instantiatePlugin(QString identifier, float inputSampleRate) { - QString type, soName, label; - PluginIdentifier::parseIdentifier(identifier, type, soName, label); - if (type != "sv") { + Vamp::Plugin *rv = 0; + + const VampPluginDescriptor *descriptor = 0; + int index = 0; + + QString type, soname, label; + PluginIdentifier::parseIdentifier(identifier, type, soname, label); + if (type != "vamp" && type != "sv") { //!!! std::cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Wrong factory for plugin type " << type.toStdString() << std::endl; return 0; } //!!! - if (soName != PluginIdentifier::BUILTIN_PLUGIN_SONAME) { - std::cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Non-built-in plugins not yet supported (paradoxically enough)" << std::endl; - return 0; + if (type == "sv" && soname == PluginIdentifier::BUILTIN_PLUGIN_SONAME) { + + if (label == "beats") { + return new BeatDetector(inputSampleRate); //!!! + } + + if (label == "chromagram") { + return new ChromagramPlugin(inputSampleRate); //!!! + } + + if (label == "zerocrossing") { + return new ZeroCrossing(inputSampleRate); //!!! + } + + if (label == "spectralcentroid") { + return new SpectralCentroid(inputSampleRate); //!!! + } + + if (label == "tonalchange") { + return new TonalChangeDetect(inputSampleRate); //!!! + } + + std::cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Unknown plugin \"" << identifier.toStdString() << "\"" << std::endl; + + return 0; } - if (label == "beats") { - return new BeatDetector(inputSampleRate); //!!! + QString found = findPluginFile(soname); + + if (found == "") { + std::cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Failed to find library file " << soname.toStdString() << std::endl; + } else if (found != soname) { + std::cerr << "FeatureExtractionPluginFactory::instantiatePlugin: WARNING: Given library name was " << soname.toStdString() << ", found at " << found.toStdString() << std::endl; } - if (label == "chromagram") { - return new ChromagramPlugin(inputSampleRate); //!!! + soname = found; + + void *libraryHandle = DLOPEN(soname, RTLD_LAZY); + + if (!libraryHandle) { + std::cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Failed to load library " << soname.toStdString() << std::endl; + return 0; } - if (label == "zerocrossing") { - return new ZeroCrossing(inputSampleRate); //!!! + VampGetPluginDescriptorFunction fn = (VampGetPluginDescriptorFunction) + DLSYM(libraryHandle, "vampGetPluginDescriptor"); + + if (!fn) { + std::cerr << "FeatureExtractionPluginFactory::instantiatePlugin: No descriptor function in " << soname.toStdString() << std::endl; + goto done; } - if (label == "spectralcentroid") { - return new SpectralCentroid(inputSampleRate); //!!! + while ((descriptor = fn(index))) { + if (label == descriptor->name) break; + ++index; } - if (label == "tonalchange") { - return new TonalChangeDetect(inputSampleRate); //!!! + if (!descriptor) { + std::cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Failed to find plugin \"" << label.toStdString() << "\" in library " << soname.toStdString() << std::endl; + goto done; } - std::cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Unknown plugin \"" << identifier.toStdString() << "\"" << std::endl; - - return 0; + rv = new Vamp::PluginHostAdapter(descriptor, inputSampleRate); + + //!!! need to dlclose() when plugins from a given library are unloaded + +done: + if (!rv) { + if (DLCLOSE(libraryHandle) != 0) { + std::cerr << "WARNING: FeatureExtractionPluginFactory::instantiatePlugin: Failed to unload library " << soname.toStdString() << std::endl; + } + } + return rv; }
--- a/plugin/FeatureExtractionPluginFactory.h Thu Mar 30 15:00:22 2006 +0000 +++ b/plugin/FeatureExtractionPluginFactory.h Fri Mar 31 15:56:35 2006 +0000 @@ -19,7 +19,7 @@ #include <QString> #include <vector> -class FeatureExtractionPlugin; +namespace Vamp { class Plugin; } class FeatureExtractionPluginFactory { @@ -28,12 +28,16 @@ static FeatureExtractionPluginFactory *instanceFor(QString identifier); static std::vector<QString> getAllPluginIdentifiers(); - std::vector<QString> getPluginIdentifiers(); + virtual std::vector<QString> getPluginPath(); + + virtual std::vector<QString> getPluginIdentifiers(); + + virtual QString findPluginFile(QString soname, QString inDir = ""); // We don't set blockSize or channels on this -- they're // negotiated and handled via initialize() on the plugin - virtual FeatureExtractionPlugin *instantiatePlugin(QString identifier, - float inputSampleRate); + virtual Vamp::Plugin *instantiatePlugin(QString identifier, + float inputSampleRate); protected: };
--- a/plugin/FeatureExtractionPluginHostAdapter.cpp Thu Mar 30 15:00:22 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,278 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - Sonic Visualiser - An audio file viewer and annotation editor. - 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 "FeatureExtractionPluginHostAdapter.h" - -FeatureExtractionPluginHostAdapter::FeatureExtractionPluginHostAdapter(const SVPPluginDescriptor *descriptor, - float inputSampleRate) : - FeatureExtractionPlugin(inputSampleRate), - m_descriptor(descriptor) -{ - m_handle = m_descriptor->instantiate(m_descriptor, inputSampleRate); -} - -FeatureExtractionPluginHostAdapter::~FeatureExtractionPluginHostAdapter() -{ - if (m_handle) m_descriptor->cleanup(m_handle); -} - -bool -FeatureExtractionPluginHostAdapter::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 -FeatureExtractionPluginHostAdapter::reset() -{ - if (!m_handle) return; - m_descriptor->reset(m_handle); -} - -std::string -FeatureExtractionPluginHostAdapter::getName() const -{ - return m_descriptor->name; -} - -std::string -FeatureExtractionPluginHostAdapter::getDescription() const -{ - return m_descriptor->description; -} - -std::string -FeatureExtractionPluginHostAdapter::getMaker() const -{ - return m_descriptor->maker; -} - -int -FeatureExtractionPluginHostAdapter::getPluginVersion() const -{ - return m_descriptor->pluginVersion; -} - -std::string -FeatureExtractionPluginHostAdapter::getCopyright() const -{ - return m_descriptor->copyright; -} - -FeatureExtractionPluginHostAdapter::ParameterList -FeatureExtractionPluginHostAdapter::getParameterDescriptors() const -{ - ParameterList list; - for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) { - const SVPParameterDescriptor *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 -FeatureExtractionPluginHostAdapter::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 -FeatureExtractionPluginHostAdapter::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; - } - } -} - -FeatureExtractionPluginHostAdapter::ProgramList -FeatureExtractionPluginHostAdapter::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 -FeatureExtractionPluginHostAdapter::getCurrentProgram() const -{ - if (!m_handle) return ""; - - int pn = m_descriptor->getCurrentProgram(m_handle); - return m_descriptor->programs[pn]; -} - -void -FeatureExtractionPluginHostAdapter::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 -FeatureExtractionPluginHostAdapter::getPreferredStepSize() const -{ - if (!m_handle) return 0; - return m_descriptor->getPreferredStepSize(m_handle); -} - -size_t -FeatureExtractionPluginHostAdapter::getPreferredBlockSize() const -{ - if (!m_handle) return 0; - return m_descriptor->getPreferredBlockSize(m_handle); -} - -FeatureExtractionPluginHostAdapter::OutputList -FeatureExtractionPluginHostAdapter::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) { - SVPOutputDescriptor *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]); - } - d.hasKnownExtents = sd->hasKnownExtents; - d.minValue = sd->minValue; - d.maxValue = sd->maxValue; - d.isQuantized = sd->isQuantized; - d.quantizeStep = sd->quantizeStep; - - switch (sd->sampleType) { - case svpOneSamplePerStep: - d.sampleType = OutputDescriptor::OneSamplePerStep; break; - case svpFixedSampleRate: - d.sampleType = OutputDescriptor::FixedSampleRate; break; - case svpVariableSampleRate: - d.sampleType = OutputDescriptor::VariableSampleRate; break; - } - - d.sampleRate = sd->sampleRate; - - list.push_back(d); - - m_descriptor->releaseOutputDescriptor(sd); - } - - return list; -} - -FeatureExtractionPluginHostAdapter::FeatureSet -FeatureExtractionPluginHostAdapter::process(float **inputBuffers, - RealTime timestamp) -{ - FeatureSet fs; - if (!m_handle) return fs; - - int sec = timestamp.sec; - int nsec = timestamp.nsec; - - SVPFeatureList **features = m_descriptor->process(m_handle, - inputBuffers, - sec, nsec); - - convertFeatures(features, fs); - m_descriptor->releaseFeatureSet(features); - return fs; -} - -FeatureExtractionPluginHostAdapter::FeatureSet -FeatureExtractionPluginHostAdapter::getRemainingFeatures() -{ - FeatureSet fs; - if (!m_handle) return fs; - - SVPFeatureList **features = m_descriptor->getRemainingFeatures(m_handle); - - convertFeatures(features, fs); - m_descriptor->releaseFeatureSet(features); - return fs; -} - -void -FeatureExtractionPluginHostAdapter::convertFeatures(SVPFeatureList **features, - FeatureSet &fs) -{ - for (unsigned int i = 0; features[i]; ++i) { - - SVPFeatureList &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); - } - } - } -} -
--- a/plugin/FeatureExtractionPluginHostAdapter.h Thu Mar 30 15:00:22 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - Sonic Visualiser - An audio file viewer and annotation editor. - 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 _FEATURE_EXTRACTION_PLUGIN_HOST_ADAPTER_H_ -#define _FEATURE_EXTRACTION_PLUGIN_HOST_ADAPTER_H_ - -#include "api/svp.h" - -#include "FeatureExtractionPlugin.h" - -class FeatureExtractionPluginHostAdapter : public FeatureExtractionPlugin -{ -public: - FeatureExtractionPluginHostAdapter(const SVPPluginDescriptor *descriptor, - float inputSampleRate); - virtual ~FeatureExtractionPluginHostAdapter(); - - bool initialise(size_t channels, size_t stepSize, size_t blockSize); - void reset(); - - 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(SVPFeatureList **, FeatureSet &); - - const SVPPluginDescriptor *m_descriptor; - SVPPluginHandle m_handle; -}; - -#endif - -
--- a/plugin/LADSPAPluginInstance.cpp Thu Mar 30 15:00:22 2006 +0000 +++ b/plugin/LADSPAPluginInstance.cpp Fri Mar 31 15:56:35 2006 +0000 @@ -224,7 +224,7 @@ LADSPAPluginInstance::getLatency() { if (m_latencyPort) { - if (!m_run) run(RealTime::zeroTime); + if (!m_run) run(Vamp::RealTime::zeroTime); if (*m_latencyPort > 0) return (size_t)*m_latencyPort; } return 0; @@ -441,7 +441,7 @@ } void -LADSPAPluginInstance::run(const RealTime &) +LADSPAPluginInstance::run(const Vamp::RealTime &) { if (!m_descriptor || !m_descriptor->run) return;
--- a/plugin/LADSPAPluginInstance.h Thu Mar 30 15:00:22 2006 +0000 +++ b/plugin/LADSPAPluginInstance.h Fri Mar 31 15:56:35 2006 +0000 @@ -49,7 +49,7 @@ virtual int getPluginVersion() const; virtual std::string getCopyright() const; - virtual void run(const RealTime &rt); + virtual void run(const Vamp::RealTime &rt); virtual unsigned int getParameterCount() const; virtual void setParameterValue(unsigned int parameter, float value);
--- a/plugin/PluginDescription.h Thu Mar 30 15:00:22 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - Sonic Visualiser - An audio file viewer and annotation editor. - 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 _PLUGIN_DESCRIPTION_H_ -#define _PLUGIN_DESCRIPTION_H_ - -struct PluginDescription -{ -
--- a/plugin/PluginInstance.cpp Thu Mar 30 15:00:22 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,146 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - Sonic Visualiser - An audio file viewer and annotation editor. - 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 "PluginInstance.h" - -#include <QRegExp> -#include <QXmlAttributes> - -#include <QDomDocument> -#include <QDomElement> -#include <QDomNamedNodeMap> -#include <QDomAttr> - -#include <iostream> - -QString -PluginInstance::toXmlString(QString indent, QString extraAttributes) const -{ - QString s; - s += indent; - - s += QString("<plugin name=\"%1\" description=\"%2\" maker=\"%3\" version=\"%4\" copyright=\"%5\" %6 ") - .arg(encodeEntities(QString(getName().c_str()))) - .arg(encodeEntities(QString(getDescription().c_str()))) - .arg(encodeEntities(QString(getMaker().c_str()))) - .arg(getPluginVersion()) - .arg(encodeEntities(QString(getCopyright().c_str()))) - .arg(extraAttributes); - - if (!getPrograms().empty()) { - s += QString("program=\"%1\" ") - .arg(encodeEntities(getCurrentProgram().c_str())); - } - - ParameterList parameters = getParameterDescriptors(); - - for (ParameterList::const_iterator i = parameters.begin(); - i != parameters.end(); ++i) { - s += QString("param-%1=\"%2\" ") - .arg(stripInvalidParameterNameCharacters(QString(i->name.c_str()))) - .arg(getParameter(i->name)); - } - - s += "/>\n"; - return s; -} - -#define CHECK_ATTRIBUTE(ATTRIBUTE, ACCESSOR) \ - QString ATTRIBUTE = attrs.value(#ATTRIBUTE); \ - if (ATTRIBUTE != "" && ATTRIBUTE != ACCESSOR().c_str()) { \ - std::cerr << "WARNING: PluginInstance::setParameters: Plugin " \ - << #ATTRIBUTE << " does not match (attributes have \"" \ - << ATTRIBUTE.toStdString() << "\", my " \ - << #ATTRIBUTE << " is \"" << ACCESSOR() << "\")" << std::endl; \ - } - -void -PluginInstance::setParameters(const QXmlAttributes &attrs) -{ - CHECK_ATTRIBUTE(name, getName); - CHECK_ATTRIBUTE(description, getDescription); - CHECK_ATTRIBUTE(maker, getMaker); - CHECK_ATTRIBUTE(copyright, getCopyright); - - bool ok; - int version = attrs.value("version").trimmed().toInt(&ok); - if (ok && version != getPluginVersion()) { - std::cerr << "WARNING: PluginInstance::setParameters: Plugin version does not match (attributes have " << version << ", my version is " << getPluginVersion() << ")" << std::endl; - } - - if (!getPrograms().empty()) { - selectProgram(attrs.value("program").toStdString()); - } - - ParameterList parameters = getParameterDescriptors(); - - for (ParameterList::const_iterator i = parameters.begin(); - i != parameters.end(); ++i) { - QString name = QString("param-%1") - .arg(stripInvalidParameterNameCharacters - (QString(i->name.c_str()))); - if (attrs.value(name) == "") { - std::cerr << "PluginInstance::setParameters: no parameter \"" << i->name << "\" (attribute \"" << name.toStdString() << "\")" << std::endl; - continue; - } - bool ok; - float value = attrs.value(name).trimmed().toFloat(&ok); - if (ok) { - setParameter(i->name, value); - } else { - std::cerr << "WARNING: PluginInstance::setParameters: Invalid value \"" << attrs.value(name).toStdString() << "\" for parameter \"" << i->name << "\" (attribute \"" << name.toStdString() << "\")" << std::endl; - } - } -} - -void -PluginInstance::setParametersFromXml(QString xml) -{ - QDomDocument doc; - - QString error; - int errorLine; - int errorColumn; - - if (!doc.setContent(xml, false, &error, &errorLine, &errorColumn)) { - std::cerr << "PluginInstance::setParametersFromXml: Error in parsing XML: " << error.toStdString() << " at line " << errorLine << ", column " << errorColumn << std::endl; - std::cerr << "Input follows:" << std::endl; - std::cerr << xml.toStdString() << std::endl; - std::cerr << "Input ends." << std::endl; - return; - } - - QDomElement pluginElt = doc.firstChildElement("plugin"); - QDomNamedNodeMap attrNodes = pluginElt.attributes(); - QXmlAttributes attrs; - - for (int i = 0; i < attrNodes.length(); ++i) { - QDomAttr attr = attrNodes.item(i).toAttr(); - if (attr.isNull()) continue; - std::cerr << "Adding attribute \"" << attr.name().toStdString() - << "\" with value \"" << attr.value().toStdString() << "\"" << std::endl; - attrs.append(attr.name(), "", "", attr.value()); - } - - setParameters(attrs); -} - -QString -PluginInstance::stripInvalidParameterNameCharacters(QString s) const -{ - s.replace(QRegExp("[^a-zA-Z0-9_]*"), ""); - return s; -} -
--- a/plugin/PluginInstance.h Thu Mar 30 15:00:22 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,191 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - Sonic Visualiser - An audio file viewer and annotation editor. - 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 _PLUGIN_INSTANCE_H_ -#define _PLUGIN_INSTANCE_H_ - -#include <string> -#include <vector> - -#include "base/XmlExportable.h" - -class QXmlAttributes; - -/** - * A base class for plugins with optional configurable parameters, - * programs, etc. - * - * This does not provide the necessary interfaces to instantiate or - * run a plugin -- that depends on the plugin subclass, as different - * plugin types may have quite different operating structures. This - * class just specifies the necessary interface to show editable - * controls for the plugin to the user. - */ - -class PluginInstance : public XmlExportable -{ -public: - /** - * Get the computer-usable name of the plugin. This should be - * reasonably short and contain no whitespace or punctuation - * characters. It may be shown to the user, but it won't be the - * main method for a user to identify a plugin (that will be the - * description, below). - */ - virtual std::string getName() const = 0; - - /** - * Get a human-readable description of the plugin. This should be - * self-contained, as it may be shown to the user in isolation - * without also showing the plugin's "name". - */ - virtual std::string getDescription() const = 0; - - /** - * Get the name of the author or vendor of the plugin in - * human-readable form. - */ - virtual std::string getMaker() const = 0; - - /** - * Get the version number of the plugin. - */ - virtual int getPluginVersion() const = 0; - - /** - * Get the copyright statement or licensing summary of the plugin. - */ - virtual std::string getCopyright() const = 0; - - /** - * Get the type of plugin (e.g. DSSI, etc). This is likely to be - * implemented by the immediate subclass, not by actual plugins. - */ - virtual std::string getType() const = 0; - - - struct ParameterDescriptor - { - /** - * The name of the parameter, in computer-usable form. Should - * be reasonably short, and may only contain the characters - * [a-zA-Z0-9_]. - */ - std::string name; - - /** - * The human-readable name of the parameter. - */ - std::string description; - - /** - * The unit of the parameter, in human-readable form. - */ - std::string unit; - - /** - * The minimum value of the parameter. - */ - float minValue; - - /** - * The maximum value of the parameter. - */ - float maxValue; - - /** - * The default value of the parameter. - */ - float defaultValue; - - /** - * True if the parameter values are quantized to a particular - * resolution. - */ - bool isQuantized; - - /** - * Quantization resolution of the parameter values (e.g. 1.0 - * if they are all integers). Undefined if isQuantized is - * false. - */ - float quantizeStep; - }; - - typedef std::vector<ParameterDescriptor> ParameterList; - - /** - * Get the controllable parameters of this plugin. - */ - virtual ParameterList getParameterDescriptors() const { - return ParameterList(); - } - - /** - * Get the value of a named parameter. The argument is the name - * field from that parameter's descriptor. - */ - virtual float getParameter(std::string) const { return 0.0; } - - /** - * Set a named parameter. The first argument is the name field - * from that parameter's descriptor. - */ - virtual void setParameter(std::string, float) { } - - - typedef std::vector<std::string> ProgramList; - - /** - * Get the program settings available in this plugin. - * The programs must have unique names. - */ - virtual ProgramList getPrograms() const { return ProgramList(); } - - /** - * Get the current program. - */ - virtual std::string getCurrentProgram() const { return ""; } - - /** - * Select a program. (If the given program name is not one of the - * available programs, do nothing.) - */ - virtual void selectProgram(std::string) { } - - /** - * Export plugin settings to XML. - */ - virtual QString toXmlString(QString indent = "", - QString extraAttributes = "") const; - - /** - * Set the parameters and program of a plugin from a set of XML - * attributes. This is a partial inverse of toXmlString. - */ - virtual void setParameters(const QXmlAttributes &); - - /** - * Set the parameters and program of a plugin from an XML plugin - * element as returned by toXmlString. This is a partial inverse - * of toXmlString. - */ - virtual void setParametersFromXml(QString xml); - -protected: - QString stripInvalidParameterNameCharacters(QString) const; -}; - -#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/PluginXml.cpp Fri Mar 31 15:56:35 2006 +0000 @@ -0,0 +1,160 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + 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 "PluginXml.h" + +#include <QRegExp> +#include <QXmlAttributes> + +#include <QDomDocument> +#include <QDomElement> +#include <QDomNamedNodeMap> +#include <QDomAttr> + +#include "vamp-sdk/PluginBase.h" + +#include <iostream> + +PluginXml::PluginXml(Vamp::PluginBase *plugin) : + m_plugin(plugin) +{ +} + +PluginXml::~PluginXml() { } + +QString +PluginXml::toXmlString(QString indent, QString extraAttributes) const +{ + QString s; + s += indent; + + s += QString("<plugin name=\"%1\" description=\"%2\" maker=\"%3\" version=\"%4\" copyright=\"%5\" %6 ") + .arg(encodeEntities(QString(m_plugin->getName().c_str()))) + .arg(encodeEntities(QString(m_plugin->getDescription().c_str()))) + .arg(encodeEntities(QString(m_plugin->getMaker().c_str()))) + .arg(m_plugin->getPluginVersion()) + .arg(encodeEntities(QString(m_plugin->getCopyright().c_str()))) + .arg(extraAttributes); + + if (!m_plugin->getPrograms().empty()) { + s += QString("program=\"%1\" ") + .arg(encodeEntities(m_plugin->getCurrentProgram().c_str())); + } + + Vamp::PluginBase::ParameterList parameters = + m_plugin->getParameterDescriptors(); + + for (Vamp::PluginBase::ParameterList::const_iterator i = parameters.begin(); + i != parameters.end(); ++i) { + s += QString("param-%1=\"%2\" ") + .arg(stripInvalidParameterNameCharacters(QString(i->name.c_str()))) + .arg(m_plugin->getParameter(i->name)); + } + + s += "/>\n"; + return s; +} + +#define CHECK_ATTRIBUTE(ATTRIBUTE, ACCESSOR) \ + QString ATTRIBUTE = attrs.value(#ATTRIBUTE); \ + if (ATTRIBUTE != "" && ATTRIBUTE != ACCESSOR().c_str()) { \ + std::cerr << "WARNING: PluginXml::setParameters: Plugin " \ + << #ATTRIBUTE << " does not match (attributes have \"" \ + << ATTRIBUTE.toStdString() << "\", my " \ + << #ATTRIBUTE << " is \"" << ACCESSOR() << "\")" << std::endl; \ + } + +void +PluginXml::setParameters(const QXmlAttributes &attrs) +{ + CHECK_ATTRIBUTE(name, m_plugin->getName); + CHECK_ATTRIBUTE(description, m_plugin->getDescription); + CHECK_ATTRIBUTE(maker, m_plugin->getMaker); + CHECK_ATTRIBUTE(copyright, m_plugin->getCopyright); + + bool ok; + int version = attrs.value("version").trimmed().toInt(&ok); + if (ok && version != m_plugin->getPluginVersion()) { + std::cerr << "WARNING: PluginXml::setParameters: Plugin version does not match (attributes have " << version << ", my version is " << m_plugin->getPluginVersion() << ")" << std::endl; + } + + if (!m_plugin->getPrograms().empty()) { + m_plugin->selectProgram(attrs.value("program").toStdString()); + } + + Vamp::PluginBase::ParameterList parameters = + m_plugin->getParameterDescriptors(); + + for (Vamp::PluginBase::ParameterList::const_iterator i = + parameters.begin(); i != parameters.end(); ++i) { + + QString name = QString("param-%1") + .arg(stripInvalidParameterNameCharacters + (QString(i->name.c_str()))); + + if (attrs.value(name) == "") { + std::cerr << "PluginXml::setParameters: no parameter \"" << i->name << "\" (attribute \"" << name.toStdString() << "\")" << std::endl; + continue; + } + + bool ok; + float value = attrs.value(name).trimmed().toFloat(&ok); + if (ok) { + m_plugin->setParameter(i->name, value); + } else { + std::cerr << "WARNING: PluginXml::setParameters: Invalid value \"" << attrs.value(name).toStdString() << "\" for parameter \"" << i->name << "\" (attribute \"" << name.toStdString() << "\")" << std::endl; + } + } +} + +void +PluginXml::setParametersFromXml(QString xml) +{ + QDomDocument doc; + + QString error; + int errorLine; + int errorColumn; + + if (!doc.setContent(xml, false, &error, &errorLine, &errorColumn)) { + std::cerr << "PluginXml::setParametersFromXml: Error in parsing XML: " << error.toStdString() << " at line " << errorLine << ", column " << errorColumn << std::endl; + std::cerr << "Input follows:" << std::endl; + std::cerr << xml.toStdString() << std::endl; + std::cerr << "Input ends." << std::endl; + return; + } + + QDomElement pluginElt = doc.firstChildElement("plugin"); + QDomNamedNodeMap attrNodes = pluginElt.attributes(); + QXmlAttributes attrs; + + for (unsigned int i = 0; i < attrNodes.length(); ++i) { + QDomAttr attr = attrNodes.item(i).toAttr(); + if (attr.isNull()) continue; + std::cerr << "Adding attribute \"" << attr.name().toStdString() + << "\" with value \"" << attr.value().toStdString() << "\"" << std::endl; + attrs.append(attr.name(), "", "", attr.value()); + } + + setParameters(attrs); +} + +QString +PluginXml::stripInvalidParameterNameCharacters(QString s) const +{ + s.replace(QRegExp("[^a-zA-Z0-9_]*"), ""); + return s; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/PluginXml.h Fri Mar 31 15:56:35 2006 +0000 @@ -0,0 +1,56 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + 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 _PLUGIN_XML_H_ +#define _PLUGIN_XML_H_ + +#include "base/XmlExportable.h" + +namespace Vamp { class PluginBase; } + +class QXmlAttributes; + +class PluginXml : public XmlExportable +{ +public: + PluginXml(Vamp::PluginBase *plugin); + virtual ~PluginXml(); + + /** + * Export plugin settings to XML. + */ + virtual QString toXmlString(QString indent = "", + QString extraAttributes = "") const; + + /** + * Set the parameters and program of a plugin from a set of XML + * attributes. This is a partial inverse of toXmlString. + */ + virtual void setParameters(const QXmlAttributes &); + + /** + * Set the parameters and program of a plugin from an XML plugin + * element as returned by toXmlString. This is a partial inverse + * of toXmlString. + */ + virtual void setParametersFromXml(QString xml); + +protected: + QString stripInvalidParameterNameCharacters(QString) const; + + Vamp::PluginBase *m_plugin; +}; + +#endif
--- a/plugin/RealTimePluginInstance.h Thu Mar 30 15:00:22 2006 +0000 +++ b/plugin/RealTimePluginInstance.h Fri Mar 31 15:56:35 2006 +0000 @@ -21,15 +21,14 @@ #ifndef _REALTIME_PLUGIN_INSTANCE_H_ #define _REALTIME_PLUGIN_INSTANCE_H_ -#include "PluginInstance.h" +#include "vamp-sdk/PluginBase.h" +#include "vamp-sdk/RealTime.h" #include <QString> #include <QStringList> #include <vector> #include <string> -#include "base/RealTime.h" - class RealTimePluginFactory; /** @@ -72,7 +71,7 @@ static const int SampleRate = 8; } -class RealTimePluginInstance : public PluginInstance +class RealTimePluginInstance : public Vamp::PluginBase { public: typedef float sample_t; @@ -88,7 +87,7 @@ * may be of interest to synths etc that may have queued events * waiting. Other plugins can ignore it. */ - virtual void run(const RealTime &blockStartTime) = 0; + virtual void run(const Vamp::RealTime &blockStartTime) = 0; virtual size_t getBufferSize() const = 0; @@ -115,7 +114,7 @@ virtual std::string configure(std::string /* key */, std::string /* value */) { return std::string(); } - virtual void sendEvent(const RealTime & /* eventTime */, + virtual void sendEvent(const Vamp::RealTime & /* eventTime */, const void * /* event */) { } virtual void clearEvents() { }
--- a/transform/FeatureExtractionPluginTransform.cpp Thu Mar 30 15:00:22 2006 +0000 +++ b/transform/FeatureExtractionPluginTransform.cpp Fri Mar 31 15:56:35 2006 +0000 @@ -17,7 +17,8 @@ #include "FeatureExtractionPluginTransform.h" #include "plugin/FeatureExtractionPluginFactory.h" -#include "plugin/FeatureExtractionPlugin.h" +#include "plugin/PluginXml.h" +#include "vamp-sdk/Plugin.h" #include "base/Model.h" #include "model/SparseOneDimensionalModel.h" @@ -58,10 +59,10 @@ } if (configurationXml != "") { - m_plugin->setParametersFromXml(configurationXml); + PluginXml(m_plugin).setParametersFromXml(configurationXml); } - FeatureExtractionPlugin::OutputList outputs = + Vamp::Plugin::OutputList outputs = m_plugin->getOutputDescriptors(); if (outputs.empty()) { @@ -73,7 +74,7 @@ for (size_t i = 0; i < outputs.size(); ++i) { if (outputName == "" || outputs[i].name == outputName.toStdString()) { m_outputFeatureNo = i; - m_descriptor = new FeatureExtractionPlugin::OutputDescriptor + m_descriptor = new Vamp::Plugin::OutputDescriptor (outputs[i]); break; } @@ -106,17 +107,17 @@ switch (m_descriptor->sampleType) { - case FeatureExtractionPlugin::OutputDescriptor::VariableSampleRate: + case Vamp::Plugin::OutputDescriptor::VariableSampleRate: if (m_descriptor->sampleRate != 0.0) { modelResolution = size_t(modelRate / m_descriptor->sampleRate + 0.001); } break; - case FeatureExtractionPlugin::OutputDescriptor::OneSamplePerStep: + case Vamp::Plugin::OutputDescriptor::OneSamplePerStep: modelResolution = m_plugin->getPreferredStepSize(); break; - case FeatureExtractionPlugin::OutputDescriptor::FixedSampleRate: + case Vamp::Plugin::OutputDescriptor::FixedSampleRate: modelRate = m_descriptor->sampleRate; break; } @@ -130,7 +131,7 @@ // We don't have a sparse 3D model m_descriptor->sampleType == - FeatureExtractionPlugin::OutputDescriptor::VariableSampleRate) { + Vamp::Plugin::OutputDescriptor::VariableSampleRate) { SparseTimeValueModel *model = new SparseTimeValueModel (modelRate, modelResolution, minValue, maxValue, false); @@ -239,11 +240,11 @@ } } - FeatureExtractionPlugin::FeatureSet features = m_plugin->process - (buffers, RealTime::frame2RealTime(blockFrame, sampleRate)); + Vamp::Plugin::FeatureSet features = m_plugin->process + (buffers, Vamp::RealTime::frame2RealTime(blockFrame, sampleRate)); for (size_t fi = 0; fi < features[m_outputFeatureNo].size(); ++fi) { - FeatureExtractionPlugin::Feature feature = + Vamp::Plugin::Feature feature = features[m_outputFeatureNo][fi]; addFeature(blockFrame, feature); } @@ -256,10 +257,10 @@ blockFrame += stepSize; } - FeatureExtractionPlugin::FeatureSet features = m_plugin->getRemainingFeatures(); + Vamp::Plugin::FeatureSet features = m_plugin->getRemainingFeatures(); for (size_t fi = 0; fi < features[m_outputFeatureNo].size(); ++fi) { - FeatureExtractionPlugin::Feature feature = + Vamp::Plugin::Feature feature = features[m_outputFeatureNo][fi]; addFeature(blockFrame, feature); } @@ -270,7 +271,7 @@ void FeatureExtractionPluginTransform::addFeature(size_t blockFrame, - const FeatureExtractionPlugin::Feature &feature) + const Vamp::Plugin::Feature &feature) { size_t inputRate = m_input->getSampleRate(); @@ -285,7 +286,7 @@ size_t frame = blockFrame; if (m_descriptor->sampleType == - FeatureExtractionPlugin::OutputDescriptor::VariableSampleRate) { + Vamp::Plugin::OutputDescriptor::VariableSampleRate) { if (!feature.hasTimestamp) { std::cerr @@ -294,16 +295,16 @@ << std::endl; return; } else { - frame = RealTime::realTime2Frame(feature.timestamp, inputRate); + frame = Vamp::RealTime::realTime2Frame(feature.timestamp, inputRate); } } else if (m_descriptor->sampleType == - FeatureExtractionPlugin::OutputDescriptor::FixedSampleRate) { + Vamp::Plugin::OutputDescriptor::FixedSampleRate) { if (feature.hasTimestamp) { //!!! warning: sampleRate may be non-integral - frame = RealTime::realTime2Frame(feature.timestamp, - m_descriptor->sampleRate); + frame = Vamp::RealTime::realTime2Frame(feature.timestamp, + m_descriptor->sampleRate); } else { frame = m_output->getEndFrame() + 1; } @@ -317,7 +318,7 @@ } else if (valueCount == 1 || m_descriptor->sampleType == - FeatureExtractionPlugin::OutputDescriptor::VariableSampleRate) { + Vamp::Plugin::OutputDescriptor::VariableSampleRate) { float value = 0.0; if (feature.values.size() > 0) value = feature.values[0]; @@ -353,7 +354,7 @@ } else if (valueCount == 1 || m_descriptor->sampleType == - FeatureExtractionPlugin::OutputDescriptor::VariableSampleRate) { + Vamp::Plugin::OutputDescriptor::VariableSampleRate) { SparseTimeValueModel *model = getOutput<SparseTimeValueModel>(); if (!model) return;
--- a/transform/FeatureExtractionPluginTransform.h Thu Mar 30 15:00:22 2006 +0000 +++ b/transform/FeatureExtractionPluginTransform.h Fri Mar 31 15:56:35 2006 +0000 @@ -17,7 +17,8 @@ #define _FEATURE_EXTRACTION_PLUGIN_TRANSFORM_H_ #include "Transform.h" -#include "FeatureExtractionPlugin.h" + +#include "vamp-sdk/Plugin.h" class DenseTimeValueModel; @@ -34,13 +35,13 @@ protected: virtual void run(); - FeatureExtractionPlugin *m_plugin; + Vamp::Plugin *m_plugin; int m_channel; - FeatureExtractionPlugin::OutputDescriptor *m_descriptor; + Vamp::Plugin::OutputDescriptor *m_descriptor; int m_outputFeatureNo; void addFeature(size_t blockFrame, - const FeatureExtractionPlugin::Feature &feature); + const Vamp::Plugin::Feature &feature); void setCompletion(int);
--- a/transform/RealTimePluginTransform.cpp Thu Mar 30 15:00:22 2006 +0000 +++ b/transform/RealTimePluginTransform.cpp Fri Mar 31 15:56:35 2006 +0000 @@ -18,6 +18,7 @@ #include "plugin/RealTimePluginFactory.h" #include "plugin/RealTimePluginInstance.h" +#include "plugin/PluginXml.h" #include "base/Model.h" #include "model/SparseTimeValueModel.h" @@ -61,7 +62,7 @@ } if (configurationXml != "") { - m_plugin->setParametersFromXml(configurationXml); + PluginXml(m_plugin).setParametersFromXml(configurationXml); } if (m_outputNo >= m_plugin->getControlOutputCount()) { @@ -145,7 +146,7 @@ } } - m_plugin->run(RealTime::frame2RealTime(blockFrame, sampleRate)); + m_plugin->run(Vamp::RealTime::frame2RealTime(blockFrame, sampleRate)); float value = m_plugin->getControlOutputValue(m_outputNo);
--- a/transform/TransformFactory.cpp Thu Mar 30 15:00:22 2006 +0000 +++ b/transform/TransformFactory.cpp Fri Mar 31 15:56:35 2006 +0000 @@ -20,6 +20,7 @@ #include "plugin/FeatureExtractionPluginFactory.h" #include "plugin/RealTimePluginFactory.h" +#include "plugin/PluginXml.h" #include "widgets/PluginParameterDialog.h" @@ -139,7 +140,7 @@ continue; } - FeatureExtractionPlugin *plugin = + Vamp::Plugin *plugin = factory->instantiatePlugin(pluginId, 48000); if (!plugin) { @@ -148,7 +149,7 @@ } QString pluginDescription = plugin->getDescription().c_str(); - FeatureExtractionPlugin::OutputList outputs = + Vamp::Plugin::OutputList outputs = plugin->getOutputDescriptors(); for (size_t j = 0; j < outputs.size(); ++j) { @@ -305,7 +306,7 @@ if (FeatureExtractionPluginFactory::instanceFor(id)) { - FeatureExtractionPlugin *plugin = + Vamp::Plugin *plugin = FeatureExtractionPluginFactory::instanceFor(id)-> instantiatePlugin(id, 48000); if (!plugin) return false; @@ -346,7 +347,7 @@ std::cerr << "last configuration: " << configurationXml.toStdString() << std::endl; - PluginInstance *plugin = 0; + Vamp::PluginBase *plugin = 0; if (FeatureExtractionPluginFactory::instanceFor(id)) { @@ -361,7 +362,7 @@ if (plugin) { if (configurationXml != "") { - plugin->setParametersFromXml(configurationXml); + PluginXml(plugin).setParametersFromXml(configurationXml); } int sourceChannels = 1; @@ -386,7 +387,7 @@ if (dialog->exec() == QDialog::Accepted) { ok = true; } - configurationXml = plugin->toXmlString(); + configurationXml = PluginXml(plugin).toXmlString(); channel = dialog->getChannel(); delete dialog; delete plugin;