# HG changeset patch # User cannam # Date 1143817707 0 # Node ID 0133b3513e2b0986d687a6efa707b9a986d0407e # Parent 274e883b5975a525853727069d815a6076a43a91 * Renamed sdk to vamp-sdk diff -r 274e883b5975 -r 0133b3513e2b sdk/Plugin.h --- a/sdk/Plugin.h Fri Mar 31 15:06:47 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,369 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - Vamp - - An API for audio analysis and feature extraction plugins. - - Centre for Digital Music, Queen Mary, University of London. - Copyright 2006 Chris Cannam. - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR - ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the names of the Centre for - Digital Music; Queen Mary, University of London; and Chris Cannam - shall not be used in advertising or otherwise to promote the sale, - use or other dealings in this Software without prior written - authorization. -*/ - -#ifndef _VAMP_PLUGIN_H_ -#define _VAMP_PLUGIN_H_ - -#include "PluginBase.h" -#include "RealTime.h" - -#include -#include -#include - -namespace Vamp { - -/** - * Vamp::Plugin 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 - * PluginBase, that must be implemented by the subclass. - */ - -/** - * Plugin Lifecycle - * ================ - * - * Feature extraction plugins are managed differently from real-time - * plugins (such as VST effects). 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. - * (Note however that you cannot make the number of distinct outputs - * dependent on parameter values; nor can you make any of these depend - * on the number of input channels.) - * - * 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 Plugin : public PluginBase -{ -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; - - enum InputDomain { TimeDomain, FrequencyDomain }; - - /** - * Get the plugin's required input domain. If this is TimeDomain, - * the samples provided to the process() function (below) will be - * in the time domain, as for a traditional audio processing - * plugin. If this is FrequencyDomain, the host will carry out a - * windowed FFT of size equal to the negotiated block size on the - * data before passing the frequency bin data in to process(). - * The plugin does not get to choose the window type -- the host - * will either let the user do so, or will use a Hanning window. - */ - virtual InputDomain getInputDomain() const = 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 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 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 values; - - /** - * Label for the sample of this feature. - */ - std::string label; - }; - - typedef std::vector FeatureList; - typedef std::map FeatureSet; // key is output no - - /** - * Process a single block of input data. - * - * If the plugin's inputDomain is TimeDomain, inputBuffers will - * point to one array of floats per input channel, and each of - * these arrays will contain blockSize consecutive audio samples - * (the host will zero-pad as necessary). - * - * If the plugin's inputDomain is FrequencyDomain, inputBuffers - * will point to one array of floats per input channel, and each - * of these arrays will contain blockSize/2 consecutive pairs of - * real and imaginary component floats corresponding to bins - * 0..(blockSize/2-1) of the FFT output. - * - * 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: - Plugin(float inputSampleRate) : - m_inputSampleRate(inputSampleRate) { } - - float m_inputSampleRate; -}; - -} - -#endif - - - diff -r 274e883b5975 -r 0133b3513e2b sdk/PluginAdapter.cpp --- a/sdk/PluginAdapter.cpp Fri Mar 31 15:06:47 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,473 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - Vamp - - An API for audio analysis and feature extraction plugins. - - Centre for Digital Music, Queen Mary, University of London. - Copyright 2006 Chris Cannam. - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR - ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the names of the Centre for - Digital Music; Queen Mary, University of London; and Chris Cannam - shall not be used in advertising or otherwise to promote the sale, - use or other dealings in this Software without prior written - authorization. -*/ - -#include "PluginAdapter.h" - -namespace Vamp { - -PluginAdapterBase::PluginAdapterBase() : - m_populated(false) -{ -} - -const VampPluginDescriptor * -PluginAdapterBase::getDescriptor() -{ - if (m_populated) return &m_descriptor; - - Plugin *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 VampParameterDescriptor **) - malloc(m_parameters.size() * sizeof(VampParameterDescriptor)); - - for (unsigned int i = 0; i < m_parameters.size(); ++i) { - VampParameterDescriptor *desc = (VampParameterDescriptor *) - malloc(sizeof(VampParameterDescriptor)); - 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()); - } - - if (plugin->getInputDomain() == Plugin::FrequencyDomain) { - m_descriptor.inputDomain = vampFrequencyDomain; - } else { - m_descriptor.inputDomain = vampTimeDomain; - } - - m_descriptor.instantiate = vampInstantiate; - m_descriptor.cleanup = vampCleanup; - m_descriptor.initialise = vampInitialise; - m_descriptor.reset = vampReset; - m_descriptor.getParameter = vampGetParameter; - m_descriptor.setParameter = vampSetParameter; - m_descriptor.getCurrentProgram = vampGetCurrentProgram; - m_descriptor.selectProgram = vampSelectProgram; - m_descriptor.getPreferredStepSize = vampGetPreferredStepSize; - m_descriptor.getPreferredBlockSize = vampGetPreferredBlockSize; - m_descriptor.getMinChannelCount = vampGetMinChannelCount; - m_descriptor.getMaxChannelCount = vampGetMaxChannelCount; - m_descriptor.getOutputCount = vampGetOutputCount; - m_descriptor.getOutputDescriptor = vampGetOutputDescriptor; - m_descriptor.releaseOutputDescriptor = vampReleaseOutputDescriptor; - m_descriptor.process = vampProcess; - m_descriptor.getRemainingFeatures = vampGetRemainingFeatures; - m_descriptor.releaseFeatureSet = vampReleaseFeatureSet; - - m_adapterMap[&m_descriptor] = this; - - delete plugin; - - m_populated = true; - return &m_descriptor; -} - -PluginAdapterBase::~PluginAdapterBase() -{ - 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 VampParameterDescriptor *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); -} - -PluginAdapterBase * -PluginAdapterBase::lookupAdapter(VampPluginHandle handle) -{ - AdapterMap::const_iterator i = m_adapterMap.find(handle); - if (i == m_adapterMap.end()) return 0; - return i->second; -} - -VampPluginHandle -PluginAdapterBase::vampInstantiate(const VampPluginDescriptor *desc, - float inputSampleRate) -{ - if (m_adapterMap.find(desc) == m_adapterMap.end()) return 0; - PluginAdapterBase *adapter = m_adapterMap[desc]; - if (desc != &adapter->m_descriptor) return 0; - - Plugin *plugin = adapter->createPlugin(inputSampleRate); - if (plugin) { - m_adapterMap[plugin] = adapter; - } - - return plugin; -} - -void -PluginAdapterBase::vampCleanup(VampPluginHandle handle) -{ - PluginAdapterBase *adapter = lookupAdapter(handle); - if (!adapter) { - delete ((Plugin *)handle); - return; - } - adapter->cleanup(((Plugin *)handle)); -} - -int -PluginAdapterBase::vampInitialise(VampPluginHandle handle, - unsigned int channels, - unsigned int stepSize, - unsigned int blockSize) -{ - bool result = ((Plugin *)handle)->initialise - (channels, stepSize, blockSize); - return result ? 1 : 0; -} - -void -PluginAdapterBase::vampReset(VampPluginHandle handle) -{ - ((Plugin *)handle)->reset(); -} - -float -PluginAdapterBase::vampGetParameter(VampPluginHandle handle, - int param) -{ - PluginAdapterBase *adapter = lookupAdapter(handle); - if (!adapter) return 0.0; - Plugin::ParameterList &list = adapter->m_parameters; - return ((Plugin *)handle)->getParameter(list[param].name); -} - -void -PluginAdapterBase::vampSetParameter(VampPluginHandle handle, - int param, float value) -{ - PluginAdapterBase *adapter = lookupAdapter(handle); - if (!adapter) return; - Plugin::ParameterList &list = adapter->m_parameters; - ((Plugin *)handle)->setParameter(list[param].name, value); -} - -unsigned int -PluginAdapterBase::vampGetCurrentProgram(VampPluginHandle handle) -{ - PluginAdapterBase *adapter = lookupAdapter(handle); - if (!adapter) return 0; - Plugin::ProgramList &list = adapter->m_programs; - std::string program = ((Plugin *)handle)->getCurrentProgram(); - for (unsigned int i = 0; i < list.size(); ++i) { - if (list[i] == program) return i; - } - return 0; -} - -void -PluginAdapterBase::vampSelectProgram(VampPluginHandle handle, - unsigned int program) -{ - PluginAdapterBase *adapter = lookupAdapter(handle); - if (!adapter) return; - Plugin::ProgramList &list = adapter->m_programs; - ((Plugin *)handle)->selectProgram(list[program]); -} - -unsigned int -PluginAdapterBase::vampGetPreferredStepSize(VampPluginHandle handle) -{ - return ((Plugin *)handle)->getPreferredStepSize(); -} - -unsigned int -PluginAdapterBase::vampGetPreferredBlockSize(VampPluginHandle handle) -{ - return ((Plugin *)handle)->getPreferredBlockSize(); -} - -unsigned int -PluginAdapterBase::vampGetMinChannelCount(VampPluginHandle handle) -{ - return ((Plugin *)handle)->getMinChannelCount(); -} - -unsigned int -PluginAdapterBase::vampGetMaxChannelCount(VampPluginHandle handle) -{ - return ((Plugin *)handle)->getMaxChannelCount(); -} - -unsigned int -PluginAdapterBase::vampGetOutputCount(VampPluginHandle handle) -{ - PluginAdapterBase *adapter = lookupAdapter(handle); - if (!adapter) return 0; - return adapter->getOutputCount((Plugin *)handle); -} - -VampOutputDescriptor * -PluginAdapterBase::vampGetOutputDescriptor(VampPluginHandle handle, - unsigned int i) -{ - PluginAdapterBase *adapter = lookupAdapter(handle); - if (!adapter) return 0; - return adapter->getOutputDescriptor((Plugin *)handle, i); -} - -void -PluginAdapterBase::vampReleaseOutputDescriptor(VampOutputDescriptor *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); -} - -VampFeatureList ** -PluginAdapterBase::vampProcess(VampPluginHandle handle, - float **inputBuffers, - int sec, - int nsec) -{ - PluginAdapterBase *adapter = lookupAdapter(handle); - if (!adapter) return 0; - return adapter->process((Plugin *)handle, - inputBuffers, sec, nsec); -} - -VampFeatureList ** -PluginAdapterBase::vampGetRemainingFeatures(VampPluginHandle handle) -{ - PluginAdapterBase *adapter = lookupAdapter(handle); - if (!adapter) return 0; - return adapter->getRemainingFeatures((Plugin *)handle); -} - -void -PluginAdapterBase::vampReleaseFeatureSet(VampFeatureList **fs) -{ - if (!fs) return; - for (unsigned int i = 0; fs[i]; ++i) { - for (unsigned int j = 0; j < fs[i]->featureCount; ++j) { - VampFeature *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 -PluginAdapterBase::cleanup(Plugin *plugin) -{ - if (m_pluginOutputs.find(plugin) != m_pluginOutputs.end()) { - delete m_pluginOutputs[plugin]; - m_pluginOutputs.erase(plugin); - } - m_adapterMap.erase(plugin); - delete ((Plugin *)plugin); -} - -void -PluginAdapterBase::checkOutputMap(Plugin *plugin) -{ - if (!m_pluginOutputs[plugin]) { - m_pluginOutputs[plugin] = new Plugin::OutputList - (plugin->getOutputDescriptors()); - } -} - -unsigned int -PluginAdapterBase::getOutputCount(Plugin *plugin) -{ - checkOutputMap(plugin); - return m_pluginOutputs[plugin]->size(); -} - -VampOutputDescriptor * -PluginAdapterBase::getOutputDescriptor(Plugin *plugin, - unsigned int i) -{ - checkOutputMap(plugin); - Plugin::OutputDescriptor &od = - (*m_pluginOutputs[plugin])[i]; - - VampOutputDescriptor *desc = (VampOutputDescriptor *) - malloc(sizeof(VampOutputDescriptor)); - - 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) { - if (i < od.valueNames.size()) { - desc->valueNames[i] = strdup(od.valueNames[i].c_str()); - } else { - desc->valueNames[i] = 0; - } - } - - desc->hasKnownExtents = od.hasKnownExtents; - desc->minValue = od.minValue; - desc->maxValue = od.maxValue; - desc->isQuantized = od.isQuantized; - desc->quantizeStep = od.quantizeStep; - - switch (od.sampleType) { - case Plugin::OutputDescriptor::OneSamplePerStep: - desc->sampleType = vampOneSamplePerStep; break; - case Plugin::OutputDescriptor::FixedSampleRate: - desc->sampleType = vampFixedSampleRate; break; - case Plugin::OutputDescriptor::VariableSampleRate: - desc->sampleType = vampVariableSampleRate; break; - } - - desc->sampleRate = od.sampleRate; - - return desc; -} - -VampFeatureList ** -PluginAdapterBase::process(Plugin *plugin, - float **inputBuffers, - int sec, int nsec) -{ - RealTime rt(sec, nsec); - return convertFeatures(plugin->process(inputBuffers, rt)); -} - -VampFeatureList ** -PluginAdapterBase::getRemainingFeatures(Plugin *plugin) -{ - return convertFeatures(plugin->getRemainingFeatures()); -} - -VampFeatureList ** -PluginAdapterBase::convertFeatures(const Plugin::FeatureSet &features) -{ - unsigned int n = 0; - if (features.begin() != features.end()) { - Plugin::FeatureSet::const_iterator i = features.end(); - --i; - n = i->first + 1; - } - - if (!n) return 0; - - VampFeatureList **fs = (VampFeatureList **) - malloc((n + 1) * sizeof(VampFeatureList *)); - - for (unsigned int i = 0; i < n; ++i) { - fs[i] = (VampFeatureList *)malloc(sizeof(VampFeatureList)); - if (features.find(i) == features.end()) { - fs[i]->featureCount = 0; - fs[i]->features = 0; - } else { - Plugin::FeatureSet::const_iterator fi = - features.find(i); - const Plugin::FeatureList &fl = fi->second; - fs[i]->featureCount = fl.size(); - fs[i]->features = (VampFeature *)malloc(fl.size() * - sizeof(VampFeature)); - 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; -} - -PluginAdapterBase::AdapterMap -PluginAdapterBase::m_adapterMap; - -} - diff -r 274e883b5975 -r 0133b3513e2b sdk/PluginAdapter.h --- a/sdk/PluginAdapter.h Fri Mar 31 15:06:47 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,147 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - Vamp - - An API for audio analysis and feature extraction plugins. - - Centre for Digital Music, Queen Mary, University of London. - Copyright 2006 Chris Cannam. - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR - ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the names of the Centre for - Digital Music; Queen Mary, University of London; and Chris Cannam - shall not be used in advertising or otherwise to promote the sale, - use or other dealings in this Software without prior written - authorization. -*/ - -#ifndef _PLUGIN_ADAPTER_H_ -#define _PLUGIN_ADAPTER_H_ - -#include "vamp.h" -#include "Plugin.h" - -#include - -namespace Vamp { - -class PluginAdapterBase -{ -public: - virtual ~PluginAdapterBase(); - const VampPluginDescriptor *getDescriptor(); - -protected: - PluginAdapterBase(); - - virtual Plugin *createPlugin(float inputSampleRate) = 0; - - static VampPluginHandle vampInstantiate(const VampPluginDescriptor *desc, - float inputSampleRate); - - static void vampCleanup(VampPluginHandle handle); - - static int vampInitialise(VampPluginHandle handle, unsigned int channels, - unsigned int stepSize, unsigned int blockSize); - - static void vampReset(VampPluginHandle handle); - - static float vampGetParameter(VampPluginHandle handle, int param); - static void vampSetParameter(VampPluginHandle handle, int param, float value); - - static unsigned int vampGetCurrentProgram(VampPluginHandle handle); - static void vampSelectProgram(VampPluginHandle handle, unsigned int program); - - static unsigned int vampGetPreferredStepSize(VampPluginHandle handle); - static unsigned int vampGetPreferredBlockSize(VampPluginHandle handle); - static unsigned int vampGetMinChannelCount(VampPluginHandle handle); - static unsigned int vampGetMaxChannelCount(VampPluginHandle handle); - - static unsigned int vampGetOutputCount(VampPluginHandle handle); - - static VampOutputDescriptor *vampGetOutputDescriptor(VampPluginHandle handle, - unsigned int i); - - static void vampReleaseOutputDescriptor(VampOutputDescriptor *desc); - - static VampFeatureList **vampProcess(VampPluginHandle handle, - float **inputBuffers, - int sec, - int nsec); - - static VampFeatureList **vampGetRemainingFeatures(VampPluginHandle handle); - - static void vampReleaseFeatureSet(VampFeatureList **fs); - - void cleanup(Plugin *plugin); - void checkOutputMap(Plugin *plugin); - unsigned int getOutputCount(Plugin *plugin); - VampOutputDescriptor *getOutputDescriptor(Plugin *plugin, - unsigned int i); - VampFeatureList **process(Plugin *plugin, - float **inputBuffers, - int sec, int nsec); - VampFeatureList **getRemainingFeatures(Plugin *plugin); - VampFeatureList **convertFeatures(const Plugin::FeatureSet &features); - - typedef std::map AdapterMap; - static AdapterMap m_adapterMap; - static PluginAdapterBase *lookupAdapter(VampPluginHandle); - - bool m_populated; - VampPluginDescriptor m_descriptor; - Plugin::ParameterList m_parameters; - Plugin::ProgramList m_programs; - - typedef std::map OutputMap; - OutputMap m_pluginOutputs; - - typedef std::map FeatureBufferMap; - FeatureBufferMap m_pluginFeatures; -}; - -template -class PluginAdapter : public PluginAdapterBase -{ -public: - PluginAdapter() : PluginAdapterBase() { } - ~PluginAdapter() { } - -protected: - Plugin *createPlugin(float inputSampleRate) { - P *p = new P(inputSampleRate); - Plugin *plugin = dynamic_cast(p); - if (!plugin) { - std::cerr << "ERROR: PluginAdapter::createPlugin: " - << "Template type is not a plugin!" - << std::endl; - delete p; - return 0; - } - return plugin; - } -}; - -} - -#endif - diff -r 274e883b5975 -r 0133b3513e2b sdk/PluginBase.h --- a/sdk/PluginBase.h Fri Mar 31 15:06:47 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,190 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - Vamp - - An API for audio analysis and feature extraction plugins. - - Centre for Digital Music, Queen Mary, University of London. - Copyright 2006 Chris Cannam. - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR - ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the names of the Centre for - Digital Music; Queen Mary, University of London; and Chris Cannam - shall not be used in advertising or otherwise to promote the sale, - use or other dealings in this Software without prior written - authorization. -*/ - -#ifndef _VAMP_PLUGIN_BASE_H_ -#define _VAMP_PLUGIN_BASE_H_ - -#include -#include - -namespace Vamp { - -/** - * 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 PluginBase -{ -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 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 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) { } -}; - -} - -#endif diff -r 274e883b5975 -r 0133b3513e2b sdk/PluginHostAdapter.cpp --- a/sdk/PluginHostAdapter.cpp Fri Mar 31 15:06:47 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,314 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - Vamp - - An API for audio analysis and feature extraction plugins. - - Centre for Digital Music, Queen Mary, University of London. - Copyright 2006 Chris Cannam. - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR - ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the names of the Centre for - Digital Music; Queen Mary, University of London; and Chris Cannam - shall not be used in advertising or otherwise to promote the sale, - use or other dealings in this Software without prior written - authorization. -*/ - -#include "PluginHostAdapter.h" - -namespace Vamp -{ - -PluginHostAdapter::PluginHostAdapter(const VampPluginDescriptor *descriptor, - float inputSampleRate) : - Plugin(inputSampleRate), - m_descriptor(descriptor) -{ - std::cerr << "PluginHostAdapter::PluginHostAdapter (plugin = " << descriptor->name << ")" << std::endl; - m_handle = m_descriptor->instantiate(m_descriptor, inputSampleRate); -} - -PluginHostAdapter::~PluginHostAdapter() -{ - if (m_handle) m_descriptor->cleanup(m_handle); -} - -bool -PluginHostAdapter::initialise(size_t channels, - size_t stepSize, - size_t blockSize) -{ - if (!m_handle) return false; - return m_descriptor->initialise(m_handle, channels, stepSize, blockSize) ? - true : false; -} - -void -PluginHostAdapter::reset() -{ - if (!m_handle) return; - m_descriptor->reset(m_handle); -} - -PluginHostAdapter::InputDomain -PluginHostAdapter::getInputDomain() const -{ - if (m_descriptor->inputDomain == vampFrequencyDomain) { - return FrequencyDomain; - } else { - return TimeDomain; - } -} - -std::string -PluginHostAdapter::getName() const -{ - return m_descriptor->name; -} - -std::string -PluginHostAdapter::getDescription() const -{ - return m_descriptor->description; -} - -std::string -PluginHostAdapter::getMaker() const -{ - return m_descriptor->maker; -} - -int -PluginHostAdapter::getPluginVersion() const -{ - return m_descriptor->pluginVersion; -} - -std::string -PluginHostAdapter::getCopyright() const -{ - return m_descriptor->copyright; -} - -PluginHostAdapter::ParameterList -PluginHostAdapter::getParameterDescriptors() const -{ - ParameterList list; - for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) { - const VampParameterDescriptor *spd = m_descriptor->parameters[i]; - ParameterDescriptor pd; - pd.name = spd->name; - pd.description = spd->description; - pd.unit = spd->unit; - pd.minValue = spd->minValue; - pd.maxValue = spd->maxValue; - pd.defaultValue = spd->defaultValue; - pd.isQuantized = spd->isQuantized; - pd.quantizeStep = spd->quantizeStep; - list.push_back(pd); - } - return list; -} - -float -PluginHostAdapter::getParameter(std::string param) const -{ - if (!m_handle) return 0.0; - - for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) { - if (param == m_descriptor->parameters[i]->name) { - return m_descriptor->getParameter(m_handle, i); - } - } - - return 0.0; -} - -void -PluginHostAdapter::setParameter(std::string param, - float value) -{ - if (!m_handle) return; - - for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) { - if (param == m_descriptor->parameters[i]->name) { - m_descriptor->setParameter(m_handle, i, value); - return; - } - } -} - -PluginHostAdapter::ProgramList -PluginHostAdapter::getPrograms() const -{ - ProgramList list; - - for (unsigned int i = 0; i < m_descriptor->programCount; ++i) { - list.push_back(m_descriptor->programs[i]); - } - - return list; -} - -std::string -PluginHostAdapter::getCurrentProgram() const -{ - if (!m_handle) return ""; - - int pn = m_descriptor->getCurrentProgram(m_handle); - return m_descriptor->programs[pn]; -} - -void -PluginHostAdapter::selectProgram(std::string program) -{ - if (!m_handle) return; - - for (unsigned int i = 0; i < m_descriptor->programCount; ++i) { - if (program == m_descriptor->programs[i]) { - m_descriptor->selectProgram(m_handle, i); - return; - } - } -} - -size_t -PluginHostAdapter::getPreferredStepSize() const -{ - if (!m_handle) return 0; - return m_descriptor->getPreferredStepSize(m_handle); -} - -size_t -PluginHostAdapter::getPreferredBlockSize() const -{ - if (!m_handle) return 0; - return m_descriptor->getPreferredBlockSize(m_handle); -} - -PluginHostAdapter::OutputList -PluginHostAdapter::getOutputDescriptors() const -{ - OutputList list; - if (!m_handle) return list; - - unsigned int count = m_descriptor->getOutputCount(m_handle); - - for (unsigned int i = 0; i < count; ++i) { - VampOutputDescriptor *sd = m_descriptor->getOutputDescriptor(m_handle, i); - OutputDescriptor d; - d.name = sd->name; - d.description = sd->description; - d.unit = sd->unit; - d.hasFixedValueCount = sd->hasFixedValueCount; - d.valueCount = sd->valueCount; - for (unsigned int j = 0; j < sd->valueCount; ++j) { - d.valueNames.push_back(sd->valueNames[i] ? sd->valueNames[i] : ""); - } - d.hasKnownExtents = sd->hasKnownExtents; - d.minValue = sd->minValue; - d.maxValue = sd->maxValue; - d.isQuantized = sd->isQuantized; - d.quantizeStep = sd->quantizeStep; - - switch (sd->sampleType) { - case vampOneSamplePerStep: - d.sampleType = OutputDescriptor::OneSamplePerStep; break; - case vampFixedSampleRate: - d.sampleType = OutputDescriptor::FixedSampleRate; break; - case vampVariableSampleRate: - d.sampleType = OutputDescriptor::VariableSampleRate; break; - } - - d.sampleRate = sd->sampleRate; - - list.push_back(d); - - m_descriptor->releaseOutputDescriptor(sd); - } - - return list; -} - -PluginHostAdapter::FeatureSet -PluginHostAdapter::process(float **inputBuffers, - RealTime timestamp) -{ - FeatureSet fs; - if (!m_handle) return fs; - - int sec = timestamp.sec; - int nsec = timestamp.nsec; - - VampFeatureList **features = m_descriptor->process(m_handle, - inputBuffers, - sec, nsec); - - convertFeatures(features, fs); - m_descriptor->releaseFeatureSet(features); - return fs; -} - -PluginHostAdapter::FeatureSet -PluginHostAdapter::getRemainingFeatures() -{ - FeatureSet fs; - if (!m_handle) return fs; - - VampFeatureList **features = m_descriptor->getRemainingFeatures(m_handle); - - convertFeatures(features, fs); - m_descriptor->releaseFeatureSet(features); - return fs; -} - -void -PluginHostAdapter::convertFeatures(VampFeatureList **features, - FeatureSet &fs) -{ - for (unsigned int i = 0; features[i]; ++i) { - - VampFeatureList &list = *features[i]; - - if (list.featureCount > 0) { - - for (unsigned int j = 0; j < list.featureCount; ++j) { - - Feature feature; - feature.hasTimestamp = list.features[j].hasTimestamp; - feature.timestamp = RealTime(list.features[j].sec, - list.features[j].nsec); - - for (unsigned int k = 0; k < list.features[j].valueCount; ++k) { - feature.values.push_back(list.features[j].values[k]); - } - - feature.label = list.features[j].label; - - fs[i].push_back(feature); - } - } - } -} - -} diff -r 274e883b5975 -r 0133b3513e2b sdk/PluginHostAdapter.h --- a/sdk/PluginHostAdapter.h Fri Mar 31 15:06:47 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,92 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - Vamp - - An API for audio analysis and feature extraction plugins. - - Centre for Digital Music, Queen Mary, University of London. - Copyright 2006 Chris Cannam. - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR - ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the names of the Centre for - Digital Music; Queen Mary, University of London; and Chris Cannam - shall not be used in advertising or otherwise to promote the sale, - use or other dealings in this Software without prior written - authorization. -*/ - -#ifndef _PLUGIN_HOST_ADAPTER_H_ -#define _PLUGIN_HOST_ADAPTER_H_ - -#include "vamp.h" - -#include "Plugin.h" - -namespace Vamp { - -class PluginHostAdapter : public Plugin -{ -public: - PluginHostAdapter(const VampPluginDescriptor *descriptor, - float inputSampleRate); - virtual ~PluginHostAdapter(); - - bool initialise(size_t channels, size_t stepSize, size_t blockSize); - void reset(); - - InputDomain getInputDomain() const; - - std::string getName() const; - std::string getDescription() const; - std::string getMaker() const; - int getPluginVersion() const; - std::string getCopyright() const; - - ParameterList getParameterDescriptors() const; - float getParameter(std::string) const; - void setParameter(std::string, float); - - ProgramList getPrograms() const; - std::string getCurrentProgram() const; - void selectProgram(std::string); - - size_t getPreferredStepSize() const; - size_t getPreferredBlockSize() const; - - OutputList getOutputDescriptors() const; - - FeatureSet process(float **inputBuffers, RealTime timestamp); - - FeatureSet getRemainingFeatures(); - -protected: - void convertFeatures(VampFeatureList **, FeatureSet &); - - const VampPluginDescriptor *m_descriptor; - VampPluginHandle m_handle; -}; - -} - -#endif - - diff -r 274e883b5975 -r 0133b3513e2b sdk/RealTime.cpp --- a/sdk/RealTime.cpp Fri Mar 31 15:06:47 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,248 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - Vamp - - An API for audio analysis and feature extraction plugins. - - Centre for Digital Music, Queen Mary, University of London. - Copyright 2006 Chris Cannam. - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR - ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the names of the Centre for - Digital Music; Queen Mary, University of London; and Chris Cannam - shall not be used in advertising or otherwise to promote the sale, - use or other dealings in this Software without prior written - authorization. -*/ - -/* - This is a modified version of a source file from the - Rosegarden MIDI and audio sequencer and notation editor. - This file copyright 2000-2006 Chris Cannam; relicensed as detailed above -*/ - -#include - -#if (__GNUC__ < 3) -#include -#define stringstream strstream -#else -#include -#endif - -using std::cerr; -using std::endl; - -#include "RealTime.h" -#include "sys/time.h" - -namespace Vamp { - -// A RealTime consists of two ints that must be at least 32 bits each. -// A signed 32-bit int can store values exceeding +/- 2 billion. This -// means we can safely use our lower int for nanoseconds, as there are -// 1 billion nanoseconds in a second and we need to handle double that -// because of the implementations of addition etc that we use. -// -// The maximum valid RealTime on a 32-bit system is somewhere around -// 68 years: 999999999 nanoseconds longer than the classic Unix epoch. - -#define ONE_BILLION 1000000000 - -RealTime::RealTime(int s, int n) : - sec(s), nsec(n) -{ - if (sec == 0) { - while (nsec <= -ONE_BILLION) { nsec += ONE_BILLION; --sec; } - while (nsec >= ONE_BILLION) { nsec -= ONE_BILLION; ++sec; } - } else if (sec < 0) { - while (nsec <= -ONE_BILLION) { nsec += ONE_BILLION; --sec; } - while (nsec > 0) { nsec -= ONE_BILLION; ++sec; } - } else { - while (nsec >= ONE_BILLION) { nsec -= ONE_BILLION; ++sec; } - while (nsec < 0) { nsec += ONE_BILLION; --sec; } - } -} - -RealTime -RealTime::fromSeconds(double sec) -{ - return RealTime(int(sec), int((sec - int(sec)) * ONE_BILLION)); -} - -RealTime -RealTime::fromMilliseconds(int msec) -{ - return RealTime(msec / 1000, (msec % 1000) * 1000000); -} - -RealTime -RealTime::fromTimeval(const struct timeval &tv) -{ - return RealTime(tv.tv_sec, tv.tv_usec * 1000); -} - -std::ostream &operator<<(std::ostream &out, const RealTime &rt) -{ - if (rt < RealTime::zeroTime) { - out << "-"; - } else { - out << " "; - } - - int s = (rt.sec < 0 ? -rt.sec : rt.sec); - int n = (rt.nsec < 0 ? -rt.nsec : rt.nsec); - - out << s << "."; - - int nn(n); - if (nn == 0) out << "00000000"; - else while (nn < (ONE_BILLION / 10)) { - out << "0"; - nn *= 10; - } - - out << n << "R"; - return out; -} - -std::string -RealTime::toString() const -{ - std::stringstream out; - out << *this; - -#if (__GNUC__ < 3) - out << std::ends; -#endif - - std::string s = out.str(); - - // remove trailing R - return s.substr(0, s.length() - 1); -} - -std::string -RealTime::toText(bool fixedDp) const -{ - if (*this < RealTime::zeroTime) return "-" + (-*this).toText(); - - std::stringstream out; - - if (sec >= 3600) { - out << (sec / 3600) << ":"; - } - - if (sec >= 60) { - out << (sec % 3600) / 60 << ":"; - } - - if (sec >= 10) { - out << ((sec % 60) / 10); - } - - out << (sec % 10); - - int ms = msec(); - - if (ms != 0) { - out << "."; - out << (ms / 100); - ms = ms % 100; - if (ms != 0) { - out << (ms / 10); - ms = ms % 10; - } else if (fixedDp) { - out << "0"; - } - if (ms != 0) { - out << ms; - } else if (fixedDp) { - out << "0"; - } - } else if (fixedDp) { - out << ".000"; - } - -#if (__GNUC__ < 3) - out << std::ends; -#endif - - std::string s = out.str(); - - return s; -} - - -RealTime -RealTime::operator/(int d) const -{ - int secdiv = sec / d; - int secrem = sec % d; - - double nsecdiv = (double(nsec) + ONE_BILLION * double(secrem)) / d; - - return RealTime(secdiv, int(nsecdiv + 0.5)); -} - -double -RealTime::operator/(const RealTime &r) const -{ - double lTotal = double(sec) * ONE_BILLION + double(nsec); - double rTotal = double(r.sec) * ONE_BILLION + double(r.nsec); - - if (rTotal == 0) return 0.0; - else return lTotal/rTotal; -} - -long -RealTime::realTime2Frame(const RealTime &time, unsigned int sampleRate) -{ - if (time < zeroTime) return -realTime2Frame(-time, sampleRate); - - // We like integers. The last term is always zero unless the - // sample rate is greater than 1MHz, but hell, you never know... - - long frame = - time.sec * sampleRate + - (time.msec() * sampleRate) / 1000 + - ((time.usec() - 1000 * time.msec()) * sampleRate) / 1000000 + - ((time.nsec - 1000 * time.usec()) * sampleRate) / 1000000000; - - return frame; -} - -RealTime -RealTime::frame2RealTime(long frame, unsigned int sampleRate) -{ - if (frame < 0) return -frame2RealTime(-frame, sampleRate); - - RealTime rt; - rt.sec = frame / long(sampleRate); - frame -= rt.sec * long(sampleRate); - rt.nsec = (int)(((float(frame) * 1000000) / long(sampleRate)) * 1000); - return rt; -} - -const RealTime RealTime::zeroTime(0,0); - -} diff -r 274e883b5975 -r 0133b3513e2b sdk/RealTime.h --- a/sdk/RealTime.h Fri Mar 31 15:06:47 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: */ - -/* - Vamp - - An API for audio analysis and feature extraction plugins. - - Centre for Digital Music, Queen Mary, University of London. - Copyright 2006 Chris Cannam. - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR - ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the names of the Centre for - Digital Music; Queen Mary, University of London; and Chris Cannam - shall not be used in advertising or otherwise to promote the sale, - use or other dealings in this Software without prior written - authorization. -*/ - -/* - This is a modified version of a source file from the - Rosegarden MIDI and audio sequencer and notation editor. - This file copyright 2000-2006 Chris Cannam; relicensed as detailed above -*/ - -#ifndef _REAL_TIME_H_ -#define _REAL_TIME_H_ - -#include -#include - -struct timeval; - -namespace Vamp { - -/** - * RealTime represents time values to nanosecond precision - * with accurate arithmetic and frame-rate conversion functions. - */ - -struct RealTime -{ - int sec; - int nsec; - - int usec() const { return nsec / 1000; } - int msec() const { return nsec / 1000000; } - - RealTime(): sec(0), nsec(0) {} - RealTime(int s, int n); - - RealTime(const RealTime &r) : - sec(r.sec), nsec(r.nsec) { } - - static RealTime fromSeconds(double sec); - static RealTime fromMilliseconds(int msec); - static RealTime fromTimeval(const struct timeval &); - - RealTime &operator=(const RealTime &r) { - sec = r.sec; nsec = r.nsec; return *this; - } - - RealTime operator+(const RealTime &r) const { - return RealTime(sec + r.sec, nsec + r.nsec); - } - RealTime operator-(const RealTime &r) const { - return RealTime(sec - r.sec, nsec - r.nsec); - } - RealTime operator-() const { - return RealTime(-sec, -nsec); - } - - bool operator <(const RealTime &r) const { - if (sec == r.sec) return nsec < r.nsec; - else return sec < r.sec; - } - - bool operator >(const RealTime &r) const { - if (sec == r.sec) return nsec > r.nsec; - else return sec > r.sec; - } - - bool operator==(const RealTime &r) const { - return (sec == r.sec && nsec == r.nsec); - } - - bool operator!=(const RealTime &r) const { - return !(r == *this); - } - - bool operator>=(const RealTime &r) const { - if (sec == r.sec) return nsec >= r.nsec; - else return sec >= r.sec; - } - - bool operator<=(const RealTime &r) const { - if (sec == r.sec) return nsec <= r.nsec; - else return sec <= r.sec; - } - - RealTime operator/(int d) const; - - // Find the fractional difference between times - // - double operator/(const RealTime &r) const; - - // Return a human-readable debug-type string to full precision - // (probably not a format to show to a user directly) - // - std::string toString() const; - - // Return a user-readable string to the nearest millisecond - // in a form like HH:MM:SS.mmm - // - std::string toText(bool fixedDp = false) const; - - // Convenience functions for handling sample frames - // - static long realTime2Frame(const RealTime &r, unsigned int sampleRate); - static RealTime frame2RealTime(long frame, unsigned int sampleRate); - - static const RealTime zeroTime; -}; - -std::ostream &operator<<(std::ostream &out, const RealTime &rt); - -} - -#endif diff -r 274e883b5975 -r 0133b3513e2b vamp-sdk/Plugin.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vamp-sdk/Plugin.h Fri Mar 31 15:08:27 2006 +0000 @@ -0,0 +1,369 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_PLUGIN_H_ +#define _VAMP_PLUGIN_H_ + +#include "PluginBase.h" +#include "RealTime.h" + +#include +#include +#include + +namespace Vamp { + +/** + * Vamp::Plugin 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 + * PluginBase, that must be implemented by the subclass. + */ + +/** + * Plugin Lifecycle + * ================ + * + * Feature extraction plugins are managed differently from real-time + * plugins (such as VST effects). 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. + * (Note however that you cannot make the number of distinct outputs + * dependent on parameter values; nor can you make any of these depend + * on the number of input channels.) + * + * 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 Plugin : public PluginBase +{ +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; + + enum InputDomain { TimeDomain, FrequencyDomain }; + + /** + * Get the plugin's required input domain. If this is TimeDomain, + * the samples provided to the process() function (below) will be + * in the time domain, as for a traditional audio processing + * plugin. If this is FrequencyDomain, the host will carry out a + * windowed FFT of size equal to the negotiated block size on the + * data before passing the frequency bin data in to process(). + * The plugin does not get to choose the window type -- the host + * will either let the user do so, or will use a Hanning window. + */ + virtual InputDomain getInputDomain() const = 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 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 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 values; + + /** + * Label for the sample of this feature. + */ + std::string label; + }; + + typedef std::vector FeatureList; + typedef std::map FeatureSet; // key is output no + + /** + * Process a single block of input data. + * + * If the plugin's inputDomain is TimeDomain, inputBuffers will + * point to one array of floats per input channel, and each of + * these arrays will contain blockSize consecutive audio samples + * (the host will zero-pad as necessary). + * + * If the plugin's inputDomain is FrequencyDomain, inputBuffers + * will point to one array of floats per input channel, and each + * of these arrays will contain blockSize/2 consecutive pairs of + * real and imaginary component floats corresponding to bins + * 0..(blockSize/2-1) of the FFT output. + * + * 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: + Plugin(float inputSampleRate) : + m_inputSampleRate(inputSampleRate) { } + + float m_inputSampleRate; +}; + +} + +#endif + + + diff -r 274e883b5975 -r 0133b3513e2b vamp-sdk/PluginAdapter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vamp-sdk/PluginAdapter.cpp Fri Mar 31 15:08:27 2006 +0000 @@ -0,0 +1,473 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#include "PluginAdapter.h" + +namespace Vamp { + +PluginAdapterBase::PluginAdapterBase() : + m_populated(false) +{ +} + +const VampPluginDescriptor * +PluginAdapterBase::getDescriptor() +{ + if (m_populated) return &m_descriptor; + + Plugin *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 VampParameterDescriptor **) + malloc(m_parameters.size() * sizeof(VampParameterDescriptor)); + + for (unsigned int i = 0; i < m_parameters.size(); ++i) { + VampParameterDescriptor *desc = (VampParameterDescriptor *) + malloc(sizeof(VampParameterDescriptor)); + 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()); + } + + if (plugin->getInputDomain() == Plugin::FrequencyDomain) { + m_descriptor.inputDomain = vampFrequencyDomain; + } else { + m_descriptor.inputDomain = vampTimeDomain; + } + + m_descriptor.instantiate = vampInstantiate; + m_descriptor.cleanup = vampCleanup; + m_descriptor.initialise = vampInitialise; + m_descriptor.reset = vampReset; + m_descriptor.getParameter = vampGetParameter; + m_descriptor.setParameter = vampSetParameter; + m_descriptor.getCurrentProgram = vampGetCurrentProgram; + m_descriptor.selectProgram = vampSelectProgram; + m_descriptor.getPreferredStepSize = vampGetPreferredStepSize; + m_descriptor.getPreferredBlockSize = vampGetPreferredBlockSize; + m_descriptor.getMinChannelCount = vampGetMinChannelCount; + m_descriptor.getMaxChannelCount = vampGetMaxChannelCount; + m_descriptor.getOutputCount = vampGetOutputCount; + m_descriptor.getOutputDescriptor = vampGetOutputDescriptor; + m_descriptor.releaseOutputDescriptor = vampReleaseOutputDescriptor; + m_descriptor.process = vampProcess; + m_descriptor.getRemainingFeatures = vampGetRemainingFeatures; + m_descriptor.releaseFeatureSet = vampReleaseFeatureSet; + + m_adapterMap[&m_descriptor] = this; + + delete plugin; + + m_populated = true; + return &m_descriptor; +} + +PluginAdapterBase::~PluginAdapterBase() +{ + 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 VampParameterDescriptor *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); +} + +PluginAdapterBase * +PluginAdapterBase::lookupAdapter(VampPluginHandle handle) +{ + AdapterMap::const_iterator i = m_adapterMap.find(handle); + if (i == m_adapterMap.end()) return 0; + return i->second; +} + +VampPluginHandle +PluginAdapterBase::vampInstantiate(const VampPluginDescriptor *desc, + float inputSampleRate) +{ + if (m_adapterMap.find(desc) == m_adapterMap.end()) return 0; + PluginAdapterBase *adapter = m_adapterMap[desc]; + if (desc != &adapter->m_descriptor) return 0; + + Plugin *plugin = adapter->createPlugin(inputSampleRate); + if (plugin) { + m_adapterMap[plugin] = adapter; + } + + return plugin; +} + +void +PluginAdapterBase::vampCleanup(VampPluginHandle handle) +{ + PluginAdapterBase *adapter = lookupAdapter(handle); + if (!adapter) { + delete ((Plugin *)handle); + return; + } + adapter->cleanup(((Plugin *)handle)); +} + +int +PluginAdapterBase::vampInitialise(VampPluginHandle handle, + unsigned int channels, + unsigned int stepSize, + unsigned int blockSize) +{ + bool result = ((Plugin *)handle)->initialise + (channels, stepSize, blockSize); + return result ? 1 : 0; +} + +void +PluginAdapterBase::vampReset(VampPluginHandle handle) +{ + ((Plugin *)handle)->reset(); +} + +float +PluginAdapterBase::vampGetParameter(VampPluginHandle handle, + int param) +{ + PluginAdapterBase *adapter = lookupAdapter(handle); + if (!adapter) return 0.0; + Plugin::ParameterList &list = adapter->m_parameters; + return ((Plugin *)handle)->getParameter(list[param].name); +} + +void +PluginAdapterBase::vampSetParameter(VampPluginHandle handle, + int param, float value) +{ + PluginAdapterBase *adapter = lookupAdapter(handle); + if (!adapter) return; + Plugin::ParameterList &list = adapter->m_parameters; + ((Plugin *)handle)->setParameter(list[param].name, value); +} + +unsigned int +PluginAdapterBase::vampGetCurrentProgram(VampPluginHandle handle) +{ + PluginAdapterBase *adapter = lookupAdapter(handle); + if (!adapter) return 0; + Plugin::ProgramList &list = adapter->m_programs; + std::string program = ((Plugin *)handle)->getCurrentProgram(); + for (unsigned int i = 0; i < list.size(); ++i) { + if (list[i] == program) return i; + } + return 0; +} + +void +PluginAdapterBase::vampSelectProgram(VampPluginHandle handle, + unsigned int program) +{ + PluginAdapterBase *adapter = lookupAdapter(handle); + if (!adapter) return; + Plugin::ProgramList &list = adapter->m_programs; + ((Plugin *)handle)->selectProgram(list[program]); +} + +unsigned int +PluginAdapterBase::vampGetPreferredStepSize(VampPluginHandle handle) +{ + return ((Plugin *)handle)->getPreferredStepSize(); +} + +unsigned int +PluginAdapterBase::vampGetPreferredBlockSize(VampPluginHandle handle) +{ + return ((Plugin *)handle)->getPreferredBlockSize(); +} + +unsigned int +PluginAdapterBase::vampGetMinChannelCount(VampPluginHandle handle) +{ + return ((Plugin *)handle)->getMinChannelCount(); +} + +unsigned int +PluginAdapterBase::vampGetMaxChannelCount(VampPluginHandle handle) +{ + return ((Plugin *)handle)->getMaxChannelCount(); +} + +unsigned int +PluginAdapterBase::vampGetOutputCount(VampPluginHandle handle) +{ + PluginAdapterBase *adapter = lookupAdapter(handle); + if (!adapter) return 0; + return adapter->getOutputCount((Plugin *)handle); +} + +VampOutputDescriptor * +PluginAdapterBase::vampGetOutputDescriptor(VampPluginHandle handle, + unsigned int i) +{ + PluginAdapterBase *adapter = lookupAdapter(handle); + if (!adapter) return 0; + return adapter->getOutputDescriptor((Plugin *)handle, i); +} + +void +PluginAdapterBase::vampReleaseOutputDescriptor(VampOutputDescriptor *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); +} + +VampFeatureList ** +PluginAdapterBase::vampProcess(VampPluginHandle handle, + float **inputBuffers, + int sec, + int nsec) +{ + PluginAdapterBase *adapter = lookupAdapter(handle); + if (!adapter) return 0; + return adapter->process((Plugin *)handle, + inputBuffers, sec, nsec); +} + +VampFeatureList ** +PluginAdapterBase::vampGetRemainingFeatures(VampPluginHandle handle) +{ + PluginAdapterBase *adapter = lookupAdapter(handle); + if (!adapter) return 0; + return adapter->getRemainingFeatures((Plugin *)handle); +} + +void +PluginAdapterBase::vampReleaseFeatureSet(VampFeatureList **fs) +{ + if (!fs) return; + for (unsigned int i = 0; fs[i]; ++i) { + for (unsigned int j = 0; j < fs[i]->featureCount; ++j) { + VampFeature *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 +PluginAdapterBase::cleanup(Plugin *plugin) +{ + if (m_pluginOutputs.find(plugin) != m_pluginOutputs.end()) { + delete m_pluginOutputs[plugin]; + m_pluginOutputs.erase(plugin); + } + m_adapterMap.erase(plugin); + delete ((Plugin *)plugin); +} + +void +PluginAdapterBase::checkOutputMap(Plugin *plugin) +{ + if (!m_pluginOutputs[plugin]) { + m_pluginOutputs[plugin] = new Plugin::OutputList + (plugin->getOutputDescriptors()); + } +} + +unsigned int +PluginAdapterBase::getOutputCount(Plugin *plugin) +{ + checkOutputMap(plugin); + return m_pluginOutputs[plugin]->size(); +} + +VampOutputDescriptor * +PluginAdapterBase::getOutputDescriptor(Plugin *plugin, + unsigned int i) +{ + checkOutputMap(plugin); + Plugin::OutputDescriptor &od = + (*m_pluginOutputs[plugin])[i]; + + VampOutputDescriptor *desc = (VampOutputDescriptor *) + malloc(sizeof(VampOutputDescriptor)); + + 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) { + if (i < od.valueNames.size()) { + desc->valueNames[i] = strdup(od.valueNames[i].c_str()); + } else { + desc->valueNames[i] = 0; + } + } + + desc->hasKnownExtents = od.hasKnownExtents; + desc->minValue = od.minValue; + desc->maxValue = od.maxValue; + desc->isQuantized = od.isQuantized; + desc->quantizeStep = od.quantizeStep; + + switch (od.sampleType) { + case Plugin::OutputDescriptor::OneSamplePerStep: + desc->sampleType = vampOneSamplePerStep; break; + case Plugin::OutputDescriptor::FixedSampleRate: + desc->sampleType = vampFixedSampleRate; break; + case Plugin::OutputDescriptor::VariableSampleRate: + desc->sampleType = vampVariableSampleRate; break; + } + + desc->sampleRate = od.sampleRate; + + return desc; +} + +VampFeatureList ** +PluginAdapterBase::process(Plugin *plugin, + float **inputBuffers, + int sec, int nsec) +{ + RealTime rt(sec, nsec); + return convertFeatures(plugin->process(inputBuffers, rt)); +} + +VampFeatureList ** +PluginAdapterBase::getRemainingFeatures(Plugin *plugin) +{ + return convertFeatures(plugin->getRemainingFeatures()); +} + +VampFeatureList ** +PluginAdapterBase::convertFeatures(const Plugin::FeatureSet &features) +{ + unsigned int n = 0; + if (features.begin() != features.end()) { + Plugin::FeatureSet::const_iterator i = features.end(); + --i; + n = i->first + 1; + } + + if (!n) return 0; + + VampFeatureList **fs = (VampFeatureList **) + malloc((n + 1) * sizeof(VampFeatureList *)); + + for (unsigned int i = 0; i < n; ++i) { + fs[i] = (VampFeatureList *)malloc(sizeof(VampFeatureList)); + if (features.find(i) == features.end()) { + fs[i]->featureCount = 0; + fs[i]->features = 0; + } else { + Plugin::FeatureSet::const_iterator fi = + features.find(i); + const Plugin::FeatureList &fl = fi->second; + fs[i]->featureCount = fl.size(); + fs[i]->features = (VampFeature *)malloc(fl.size() * + sizeof(VampFeature)); + 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; +} + +PluginAdapterBase::AdapterMap +PluginAdapterBase::m_adapterMap; + +} + diff -r 274e883b5975 -r 0133b3513e2b vamp-sdk/PluginAdapter.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vamp-sdk/PluginAdapter.h Fri Mar 31 15:08:27 2006 +0000 @@ -0,0 +1,147 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _PLUGIN_ADAPTER_H_ +#define _PLUGIN_ADAPTER_H_ + +#include "vamp.h" +#include "Plugin.h" + +#include + +namespace Vamp { + +class PluginAdapterBase +{ +public: + virtual ~PluginAdapterBase(); + const VampPluginDescriptor *getDescriptor(); + +protected: + PluginAdapterBase(); + + virtual Plugin *createPlugin(float inputSampleRate) = 0; + + static VampPluginHandle vampInstantiate(const VampPluginDescriptor *desc, + float inputSampleRate); + + static void vampCleanup(VampPluginHandle handle); + + static int vampInitialise(VampPluginHandle handle, unsigned int channels, + unsigned int stepSize, unsigned int blockSize); + + static void vampReset(VampPluginHandle handle); + + static float vampGetParameter(VampPluginHandle handle, int param); + static void vampSetParameter(VampPluginHandle handle, int param, float value); + + static unsigned int vampGetCurrentProgram(VampPluginHandle handle); + static void vampSelectProgram(VampPluginHandle handle, unsigned int program); + + static unsigned int vampGetPreferredStepSize(VampPluginHandle handle); + static unsigned int vampGetPreferredBlockSize(VampPluginHandle handle); + static unsigned int vampGetMinChannelCount(VampPluginHandle handle); + static unsigned int vampGetMaxChannelCount(VampPluginHandle handle); + + static unsigned int vampGetOutputCount(VampPluginHandle handle); + + static VampOutputDescriptor *vampGetOutputDescriptor(VampPluginHandle handle, + unsigned int i); + + static void vampReleaseOutputDescriptor(VampOutputDescriptor *desc); + + static VampFeatureList **vampProcess(VampPluginHandle handle, + float **inputBuffers, + int sec, + int nsec); + + static VampFeatureList **vampGetRemainingFeatures(VampPluginHandle handle); + + static void vampReleaseFeatureSet(VampFeatureList **fs); + + void cleanup(Plugin *plugin); + void checkOutputMap(Plugin *plugin); + unsigned int getOutputCount(Plugin *plugin); + VampOutputDescriptor *getOutputDescriptor(Plugin *plugin, + unsigned int i); + VampFeatureList **process(Plugin *plugin, + float **inputBuffers, + int sec, int nsec); + VampFeatureList **getRemainingFeatures(Plugin *plugin); + VampFeatureList **convertFeatures(const Plugin::FeatureSet &features); + + typedef std::map AdapterMap; + static AdapterMap m_adapterMap; + static PluginAdapterBase *lookupAdapter(VampPluginHandle); + + bool m_populated; + VampPluginDescriptor m_descriptor; + Plugin::ParameterList m_parameters; + Plugin::ProgramList m_programs; + + typedef std::map OutputMap; + OutputMap m_pluginOutputs; + + typedef std::map FeatureBufferMap; + FeatureBufferMap m_pluginFeatures; +}; + +template +class PluginAdapter : public PluginAdapterBase +{ +public: + PluginAdapter() : PluginAdapterBase() { } + ~PluginAdapter() { } + +protected: + Plugin *createPlugin(float inputSampleRate) { + P *p = new P(inputSampleRate); + Plugin *plugin = dynamic_cast(p); + if (!plugin) { + std::cerr << "ERROR: PluginAdapter::createPlugin: " + << "Template type is not a plugin!" + << std::endl; + delete p; + return 0; + } + return plugin; + } +}; + +} + +#endif + diff -r 274e883b5975 -r 0133b3513e2b vamp-sdk/PluginBase.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vamp-sdk/PluginBase.h Fri Mar 31 15:08:27 2006 +0000 @@ -0,0 +1,190 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_PLUGIN_BASE_H_ +#define _VAMP_PLUGIN_BASE_H_ + +#include +#include + +namespace Vamp { + +/** + * 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 PluginBase +{ +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 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 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) { } +}; + +} + +#endif diff -r 274e883b5975 -r 0133b3513e2b vamp-sdk/PluginHostAdapter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vamp-sdk/PluginHostAdapter.cpp Fri Mar 31 15:08:27 2006 +0000 @@ -0,0 +1,314 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#include "PluginHostAdapter.h" + +namespace Vamp +{ + +PluginHostAdapter::PluginHostAdapter(const VampPluginDescriptor *descriptor, + float inputSampleRate) : + Plugin(inputSampleRate), + m_descriptor(descriptor) +{ + std::cerr << "PluginHostAdapter::PluginHostAdapter (plugin = " << descriptor->name << ")" << std::endl; + m_handle = m_descriptor->instantiate(m_descriptor, inputSampleRate); +} + +PluginHostAdapter::~PluginHostAdapter() +{ + if (m_handle) m_descriptor->cleanup(m_handle); +} + +bool +PluginHostAdapter::initialise(size_t channels, + size_t stepSize, + size_t blockSize) +{ + if (!m_handle) return false; + return m_descriptor->initialise(m_handle, channels, stepSize, blockSize) ? + true : false; +} + +void +PluginHostAdapter::reset() +{ + if (!m_handle) return; + m_descriptor->reset(m_handle); +} + +PluginHostAdapter::InputDomain +PluginHostAdapter::getInputDomain() const +{ + if (m_descriptor->inputDomain == vampFrequencyDomain) { + return FrequencyDomain; + } else { + return TimeDomain; + } +} + +std::string +PluginHostAdapter::getName() const +{ + return m_descriptor->name; +} + +std::string +PluginHostAdapter::getDescription() const +{ + return m_descriptor->description; +} + +std::string +PluginHostAdapter::getMaker() const +{ + return m_descriptor->maker; +} + +int +PluginHostAdapter::getPluginVersion() const +{ + return m_descriptor->pluginVersion; +} + +std::string +PluginHostAdapter::getCopyright() const +{ + return m_descriptor->copyright; +} + +PluginHostAdapter::ParameterList +PluginHostAdapter::getParameterDescriptors() const +{ + ParameterList list; + for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) { + const VampParameterDescriptor *spd = m_descriptor->parameters[i]; + ParameterDescriptor pd; + pd.name = spd->name; + pd.description = spd->description; + pd.unit = spd->unit; + pd.minValue = spd->minValue; + pd.maxValue = spd->maxValue; + pd.defaultValue = spd->defaultValue; + pd.isQuantized = spd->isQuantized; + pd.quantizeStep = spd->quantizeStep; + list.push_back(pd); + } + return list; +} + +float +PluginHostAdapter::getParameter(std::string param) const +{ + if (!m_handle) return 0.0; + + for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) { + if (param == m_descriptor->parameters[i]->name) { + return m_descriptor->getParameter(m_handle, i); + } + } + + return 0.0; +} + +void +PluginHostAdapter::setParameter(std::string param, + float value) +{ + if (!m_handle) return; + + for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) { + if (param == m_descriptor->parameters[i]->name) { + m_descriptor->setParameter(m_handle, i, value); + return; + } + } +} + +PluginHostAdapter::ProgramList +PluginHostAdapter::getPrograms() const +{ + ProgramList list; + + for (unsigned int i = 0; i < m_descriptor->programCount; ++i) { + list.push_back(m_descriptor->programs[i]); + } + + return list; +} + +std::string +PluginHostAdapter::getCurrentProgram() const +{ + if (!m_handle) return ""; + + int pn = m_descriptor->getCurrentProgram(m_handle); + return m_descriptor->programs[pn]; +} + +void +PluginHostAdapter::selectProgram(std::string program) +{ + if (!m_handle) return; + + for (unsigned int i = 0; i < m_descriptor->programCount; ++i) { + if (program == m_descriptor->programs[i]) { + m_descriptor->selectProgram(m_handle, i); + return; + } + } +} + +size_t +PluginHostAdapter::getPreferredStepSize() const +{ + if (!m_handle) return 0; + return m_descriptor->getPreferredStepSize(m_handle); +} + +size_t +PluginHostAdapter::getPreferredBlockSize() const +{ + if (!m_handle) return 0; + return m_descriptor->getPreferredBlockSize(m_handle); +} + +PluginHostAdapter::OutputList +PluginHostAdapter::getOutputDescriptors() const +{ + OutputList list; + if (!m_handle) return list; + + unsigned int count = m_descriptor->getOutputCount(m_handle); + + for (unsigned int i = 0; i < count; ++i) { + VampOutputDescriptor *sd = m_descriptor->getOutputDescriptor(m_handle, i); + OutputDescriptor d; + d.name = sd->name; + d.description = sd->description; + d.unit = sd->unit; + d.hasFixedValueCount = sd->hasFixedValueCount; + d.valueCount = sd->valueCount; + for (unsigned int j = 0; j < sd->valueCount; ++j) { + d.valueNames.push_back(sd->valueNames[i] ? sd->valueNames[i] : ""); + } + d.hasKnownExtents = sd->hasKnownExtents; + d.minValue = sd->minValue; + d.maxValue = sd->maxValue; + d.isQuantized = sd->isQuantized; + d.quantizeStep = sd->quantizeStep; + + switch (sd->sampleType) { + case vampOneSamplePerStep: + d.sampleType = OutputDescriptor::OneSamplePerStep; break; + case vampFixedSampleRate: + d.sampleType = OutputDescriptor::FixedSampleRate; break; + case vampVariableSampleRate: + d.sampleType = OutputDescriptor::VariableSampleRate; break; + } + + d.sampleRate = sd->sampleRate; + + list.push_back(d); + + m_descriptor->releaseOutputDescriptor(sd); + } + + return list; +} + +PluginHostAdapter::FeatureSet +PluginHostAdapter::process(float **inputBuffers, + RealTime timestamp) +{ + FeatureSet fs; + if (!m_handle) return fs; + + int sec = timestamp.sec; + int nsec = timestamp.nsec; + + VampFeatureList **features = m_descriptor->process(m_handle, + inputBuffers, + sec, nsec); + + convertFeatures(features, fs); + m_descriptor->releaseFeatureSet(features); + return fs; +} + +PluginHostAdapter::FeatureSet +PluginHostAdapter::getRemainingFeatures() +{ + FeatureSet fs; + if (!m_handle) return fs; + + VampFeatureList **features = m_descriptor->getRemainingFeatures(m_handle); + + convertFeatures(features, fs); + m_descriptor->releaseFeatureSet(features); + return fs; +} + +void +PluginHostAdapter::convertFeatures(VampFeatureList **features, + FeatureSet &fs) +{ + for (unsigned int i = 0; features[i]; ++i) { + + VampFeatureList &list = *features[i]; + + if (list.featureCount > 0) { + + for (unsigned int j = 0; j < list.featureCount; ++j) { + + Feature feature; + feature.hasTimestamp = list.features[j].hasTimestamp; + feature.timestamp = RealTime(list.features[j].sec, + list.features[j].nsec); + + for (unsigned int k = 0; k < list.features[j].valueCount; ++k) { + feature.values.push_back(list.features[j].values[k]); + } + + feature.label = list.features[j].label; + + fs[i].push_back(feature); + } + } + } +} + +} diff -r 274e883b5975 -r 0133b3513e2b vamp-sdk/PluginHostAdapter.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vamp-sdk/PluginHostAdapter.h Fri Mar 31 15:08:27 2006 +0000 @@ -0,0 +1,92 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _PLUGIN_HOST_ADAPTER_H_ +#define _PLUGIN_HOST_ADAPTER_H_ + +#include "vamp.h" + +#include "Plugin.h" + +namespace Vamp { + +class PluginHostAdapter : public Plugin +{ +public: + PluginHostAdapter(const VampPluginDescriptor *descriptor, + float inputSampleRate); + virtual ~PluginHostAdapter(); + + bool initialise(size_t channels, size_t stepSize, size_t blockSize); + void reset(); + + InputDomain getInputDomain() const; + + std::string getName() const; + std::string getDescription() const; + std::string getMaker() const; + int getPluginVersion() const; + std::string getCopyright() const; + + ParameterList getParameterDescriptors() const; + float getParameter(std::string) const; + void setParameter(std::string, float); + + ProgramList getPrograms() const; + std::string getCurrentProgram() const; + void selectProgram(std::string); + + size_t getPreferredStepSize() const; + size_t getPreferredBlockSize() const; + + OutputList getOutputDescriptors() const; + + FeatureSet process(float **inputBuffers, RealTime timestamp); + + FeatureSet getRemainingFeatures(); + +protected: + void convertFeatures(VampFeatureList **, FeatureSet &); + + const VampPluginDescriptor *m_descriptor; + VampPluginHandle m_handle; +}; + +} + +#endif + + diff -r 274e883b5975 -r 0133b3513e2b vamp-sdk/RealTime.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vamp-sdk/RealTime.cpp Fri Mar 31 15:08:27 2006 +0000 @@ -0,0 +1,248 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +/* + This is a modified version of a source file from the + Rosegarden MIDI and audio sequencer and notation editor. + This file copyright 2000-2006 Chris Cannam; relicensed as detailed above +*/ + +#include + +#if (__GNUC__ < 3) +#include +#define stringstream strstream +#else +#include +#endif + +using std::cerr; +using std::endl; + +#include "RealTime.h" +#include "sys/time.h" + +namespace Vamp { + +// A RealTime consists of two ints that must be at least 32 bits each. +// A signed 32-bit int can store values exceeding +/- 2 billion. This +// means we can safely use our lower int for nanoseconds, as there are +// 1 billion nanoseconds in a second and we need to handle double that +// because of the implementations of addition etc that we use. +// +// The maximum valid RealTime on a 32-bit system is somewhere around +// 68 years: 999999999 nanoseconds longer than the classic Unix epoch. + +#define ONE_BILLION 1000000000 + +RealTime::RealTime(int s, int n) : + sec(s), nsec(n) +{ + if (sec == 0) { + while (nsec <= -ONE_BILLION) { nsec += ONE_BILLION; --sec; } + while (nsec >= ONE_BILLION) { nsec -= ONE_BILLION; ++sec; } + } else if (sec < 0) { + while (nsec <= -ONE_BILLION) { nsec += ONE_BILLION; --sec; } + while (nsec > 0) { nsec -= ONE_BILLION; ++sec; } + } else { + while (nsec >= ONE_BILLION) { nsec -= ONE_BILLION; ++sec; } + while (nsec < 0) { nsec += ONE_BILLION; --sec; } + } +} + +RealTime +RealTime::fromSeconds(double sec) +{ + return RealTime(int(sec), int((sec - int(sec)) * ONE_BILLION)); +} + +RealTime +RealTime::fromMilliseconds(int msec) +{ + return RealTime(msec / 1000, (msec % 1000) * 1000000); +} + +RealTime +RealTime::fromTimeval(const struct timeval &tv) +{ + return RealTime(tv.tv_sec, tv.tv_usec * 1000); +} + +std::ostream &operator<<(std::ostream &out, const RealTime &rt) +{ + if (rt < RealTime::zeroTime) { + out << "-"; + } else { + out << " "; + } + + int s = (rt.sec < 0 ? -rt.sec : rt.sec); + int n = (rt.nsec < 0 ? -rt.nsec : rt.nsec); + + out << s << "."; + + int nn(n); + if (nn == 0) out << "00000000"; + else while (nn < (ONE_BILLION / 10)) { + out << "0"; + nn *= 10; + } + + out << n << "R"; + return out; +} + +std::string +RealTime::toString() const +{ + std::stringstream out; + out << *this; + +#if (__GNUC__ < 3) + out << std::ends; +#endif + + std::string s = out.str(); + + // remove trailing R + return s.substr(0, s.length() - 1); +} + +std::string +RealTime::toText(bool fixedDp) const +{ + if (*this < RealTime::zeroTime) return "-" + (-*this).toText(); + + std::stringstream out; + + if (sec >= 3600) { + out << (sec / 3600) << ":"; + } + + if (sec >= 60) { + out << (sec % 3600) / 60 << ":"; + } + + if (sec >= 10) { + out << ((sec % 60) / 10); + } + + out << (sec % 10); + + int ms = msec(); + + if (ms != 0) { + out << "."; + out << (ms / 100); + ms = ms % 100; + if (ms != 0) { + out << (ms / 10); + ms = ms % 10; + } else if (fixedDp) { + out << "0"; + } + if (ms != 0) { + out << ms; + } else if (fixedDp) { + out << "0"; + } + } else if (fixedDp) { + out << ".000"; + } + +#if (__GNUC__ < 3) + out << std::ends; +#endif + + std::string s = out.str(); + + return s; +} + + +RealTime +RealTime::operator/(int d) const +{ + int secdiv = sec / d; + int secrem = sec % d; + + double nsecdiv = (double(nsec) + ONE_BILLION * double(secrem)) / d; + + return RealTime(secdiv, int(nsecdiv + 0.5)); +} + +double +RealTime::operator/(const RealTime &r) const +{ + double lTotal = double(sec) * ONE_BILLION + double(nsec); + double rTotal = double(r.sec) * ONE_BILLION + double(r.nsec); + + if (rTotal == 0) return 0.0; + else return lTotal/rTotal; +} + +long +RealTime::realTime2Frame(const RealTime &time, unsigned int sampleRate) +{ + if (time < zeroTime) return -realTime2Frame(-time, sampleRate); + + // We like integers. The last term is always zero unless the + // sample rate is greater than 1MHz, but hell, you never know... + + long frame = + time.sec * sampleRate + + (time.msec() * sampleRate) / 1000 + + ((time.usec() - 1000 * time.msec()) * sampleRate) / 1000000 + + ((time.nsec - 1000 * time.usec()) * sampleRate) / 1000000000; + + return frame; +} + +RealTime +RealTime::frame2RealTime(long frame, unsigned int sampleRate) +{ + if (frame < 0) return -frame2RealTime(-frame, sampleRate); + + RealTime rt; + rt.sec = frame / long(sampleRate); + frame -= rt.sec * long(sampleRate); + rt.nsec = (int)(((float(frame) * 1000000) / long(sampleRate)) * 1000); + return rt; +} + +const RealTime RealTime::zeroTime(0,0); + +} diff -r 274e883b5975 -r 0133b3513e2b vamp-sdk/RealTime.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vamp-sdk/RealTime.h Fri Mar 31 15:08:27 2006 +0000 @@ -0,0 +1,146 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +/* + This is a modified version of a source file from the + Rosegarden MIDI and audio sequencer and notation editor. + This file copyright 2000-2006 Chris Cannam; relicensed as detailed above +*/ + +#ifndef _REAL_TIME_H_ +#define _REAL_TIME_H_ + +#include +#include + +struct timeval; + +namespace Vamp { + +/** + * RealTime represents time values to nanosecond precision + * with accurate arithmetic and frame-rate conversion functions. + */ + +struct RealTime +{ + int sec; + int nsec; + + int usec() const { return nsec / 1000; } + int msec() const { return nsec / 1000000; } + + RealTime(): sec(0), nsec(0) {} + RealTime(int s, int n); + + RealTime(const RealTime &r) : + sec(r.sec), nsec(r.nsec) { } + + static RealTime fromSeconds(double sec); + static RealTime fromMilliseconds(int msec); + static RealTime fromTimeval(const struct timeval &); + + RealTime &operator=(const RealTime &r) { + sec = r.sec; nsec = r.nsec; return *this; + } + + RealTime operator+(const RealTime &r) const { + return RealTime(sec + r.sec, nsec + r.nsec); + } + RealTime operator-(const RealTime &r) const { + return RealTime(sec - r.sec, nsec - r.nsec); + } + RealTime operator-() const { + return RealTime(-sec, -nsec); + } + + bool operator <(const RealTime &r) const { + if (sec == r.sec) return nsec < r.nsec; + else return sec < r.sec; + } + + bool operator >(const RealTime &r) const { + if (sec == r.sec) return nsec > r.nsec; + else return sec > r.sec; + } + + bool operator==(const RealTime &r) const { + return (sec == r.sec && nsec == r.nsec); + } + + bool operator!=(const RealTime &r) const { + return !(r == *this); + } + + bool operator>=(const RealTime &r) const { + if (sec == r.sec) return nsec >= r.nsec; + else return sec >= r.sec; + } + + bool operator<=(const RealTime &r) const { + if (sec == r.sec) return nsec <= r.nsec; + else return sec <= r.sec; + } + + RealTime operator/(int d) const; + + // Find the fractional difference between times + // + double operator/(const RealTime &r) const; + + // Return a human-readable debug-type string to full precision + // (probably not a format to show to a user directly) + // + std::string toString() const; + + // Return a user-readable string to the nearest millisecond + // in a form like HH:MM:SS.mmm + // + std::string toText(bool fixedDp = false) const; + + // Convenience functions for handling sample frames + // + static long realTime2Frame(const RealTime &r, unsigned int sampleRate); + static RealTime frame2RealTime(long frame, unsigned int sampleRate); + + static const RealTime zeroTime; +}; + +std::ostream &operator<<(std::ostream &out, const RealTime &rt); + +} + +#endif