Mercurial > hg > vamp-plugin-sdk
diff sdk/Plugin.h @ 0:6479539d1b32
* Importing first cut of Sonic Visualiser's Vamp plugin format SDK
author | cannam |
---|---|
date | Fri, 31 Mar 2006 14:21:51 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdk/Plugin.h Fri Mar 31 14:21:51 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 <string> +#include <vector> +#include <map> + +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<std::string> valueNames; + + /** + * True if the results in the output have a fixed numeric + * range (minimum and maximum values). Undefined if + * valueCount is zero. + */ + bool hasKnownExtents; + + /** + * Minimum value of the results in the output. Undefined if + * hasKnownExtents is false or valueCount is zero. + */ + float minValue; + + /** + * Maximum value of the results in the output. Undefined if + * hasKnownExtents is false or valueCount is zero. + */ + float maxValue; + + /** + * True if the output values are quantized to a particular + * resolution. Undefined if valueCount is zero. + */ + bool isQuantized; + + /** + * Quantization resolution of the output values (e.g. 1.0 if + * they are all integers). Undefined if isQuantized is false + * or valueCount is zero. + */ + float quantizeStep; + + enum SampleType { + + /// Results from each process() align with that call's block start + OneSamplePerStep, + + /// Results are evenly spaced in time (sampleRate specified below) + FixedSampleRate, + + /// Results are unevenly spaced and have individual timestamps + VariableSampleRate + }; + + /** + * Positioning in time of the output results. + */ + SampleType sampleType; + + /** + * Sample rate of the output results. Undefined if sampleType + * is OneSamplePerStep. + * + * If sampleType is VariableSampleRate and this value is + * non-zero, then it may be used to calculate a resolution for + * the output (i.e. the "duration" of each value, in time). + * It's recommended to set this to zero if that behaviour is + * not desired. + */ + float sampleRate; + }; + + typedef std::vector<OutputDescriptor> OutputList; + + /** + * Get the outputs of this plugin. An output's index in this list + * is used as its numeric index when looking it up in the + * FeatureSet returned from the process() call. + */ + virtual OutputList getOutputDescriptors() const = 0; + + struct Feature + { + /** + * True if an output feature has its own timestamp. This is + * mandatory if the output has VariableSampleRate, and is + * likely to be disregarded otherwise. + */ + bool hasTimestamp; + + /** + * Timestamp of the output feature. This is mandatory if the + * output has VariableSampleRate, and is likely to be + * disregarded otherwise. Undefined if hasTimestamp is false. + */ + RealTime timestamp; + + /** + * Results for a single sample of this feature. If the output + * hasFixedValueCount, there must be the same number of values + * as the output's valueCount count. + */ + std::vector<float> values; + + /** + * Label for the sample of this feature. + */ + std::string label; + }; + + typedef std::vector<Feature> FeatureList; + typedef std::map<int, FeatureList> FeatureSet; // key is output no + + /** + * Process a single block of input data. + * + * 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 + + +