annotate src/vamp-plugin-sdk-2.4/vamp-sdk/Plugin.h @ 23:619f715526df sv_v2.1

Update Vamp plugin SDK to 2.5
author Chris Cannam
date Thu, 09 May 2013 10:52:46 +0100
parents b7bda433d832
children
rev   line source
Chris@12 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@12 2
Chris@12 3 /*
Chris@12 4 Vamp
Chris@12 5
Chris@12 6 An API for audio analysis and feature extraction plugins.
Chris@12 7
Chris@12 8 Centre for Digital Music, Queen Mary, University of London.
Chris@12 9 Copyright 2006 Chris Cannam.
Chris@12 10
Chris@12 11 Permission is hereby granted, free of charge, to any person
Chris@12 12 obtaining a copy of this software and associated documentation
Chris@12 13 files (the "Software"), to deal in the Software without
Chris@12 14 restriction, including without limitation the rights to use, copy,
Chris@12 15 modify, merge, publish, distribute, sublicense, and/or sell copies
Chris@12 16 of the Software, and to permit persons to whom the Software is
Chris@12 17 furnished to do so, subject to the following conditions:
Chris@12 18
Chris@12 19 The above copyright notice and this permission notice shall be
Chris@12 20 included in all copies or substantial portions of the Software.
Chris@12 21
Chris@12 22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Chris@12 23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Chris@12 24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Chris@12 25 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
Chris@12 26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
Chris@12 27 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
Chris@12 28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Chris@12 29
Chris@12 30 Except as contained in this notice, the names of the Centre for
Chris@12 31 Digital Music; Queen Mary, University of London; and Chris Cannam
Chris@12 32 shall not be used in advertising or otherwise to promote the sale,
Chris@12 33 use or other dealings in this Software without prior written
Chris@12 34 authorization.
Chris@12 35 */
Chris@12 36
Chris@12 37 #ifndef _VAMP_SDK_PLUGIN_H_
Chris@12 38 #define _VAMP_SDK_PLUGIN_H_
Chris@12 39
Chris@12 40 #include <string>
Chris@12 41 #include <vector>
Chris@12 42 #include <map>
Chris@12 43
Chris@12 44 #include "PluginBase.h"
Chris@12 45 #include "RealTime.h"
Chris@12 46
Chris@12 47 #include "plugguard.h"
Chris@12 48 _VAMP_SDK_PLUGSPACE_BEGIN(Plugin.h)
Chris@12 49
Chris@12 50 namespace Vamp {
Chris@12 51
Chris@12 52 /**
Chris@12 53 * \class Plugin Plugin.h <vamp-sdk/Plugin.h>
Chris@12 54 *
Chris@12 55 * Vamp::Plugin is a base class for plugin instance classes
Chris@12 56 * that provide feature extraction from audio or related data.
Chris@12 57 *
Chris@12 58 * In most cases, the input will be audio and the output will be a
Chris@12 59 * stream of derived data at a lower sampling resolution than the
Chris@12 60 * input.
Chris@12 61 *
Chris@12 62 * Note that this class inherits several abstract methods from
Chris@12 63 * PluginBase. These must be implemented by the subclass.
Chris@12 64 *
Chris@12 65 *
Chris@12 66 * PLUGIN LIFECYCLE
Chris@12 67 *
Chris@12 68 * Feature extraction plugins are managed differently from real-time
Chris@12 69 * plugins (such as VST effects). The main difference is that the
Chris@12 70 * parameters for a feature extraction plugin are configured before
Chris@12 71 * the plugin is used, and do not change during use.
Chris@12 72 *
Chris@12 73 * 1. Host constructs the plugin, passing it the input sample rate.
Chris@12 74 * The plugin may do basic initialisation, but should not do anything
Chris@12 75 * computationally expensive at this point. You must make sure your
Chris@12 76 * plugin is cheap to construct, otherwise you'll seriously affect the
Chris@12 77 * startup performance of almost all hosts. If you have serious
Chris@12 78 * initialisation to do, the proper place is in initialise() (step 5).
Chris@12 79 *
Chris@12 80 * 2. Host may query the plugin's available outputs.
Chris@12 81 *
Chris@12 82 * 3. Host queries programs and parameter descriptors, and may set
Chris@12 83 * some or all of them. Parameters that are not explicitly set should
Chris@12 84 * take their default values as specified in the parameter descriptor.
Chris@12 85 * When a program is set, the parameter values may change and the host
Chris@12 86 * will re-query them to check.
Chris@12 87 *
Chris@12 88 * 4. Host queries the preferred step size, block size and number of
Chris@12 89 * channels. These may all vary depending on the parameter values.
Chris@12 90 * (Note however that you cannot make the number of distinct outputs
Chris@12 91 * dependent on parameter values.)
Chris@12 92 *
Chris@12 93 * 5. Plugin is properly initialised with a call to initialise. This
Chris@12 94 * fixes the step size, block size, and number of channels, as well as
Chris@12 95 * all of the parameter and program settings. If the values passed in
Chris@12 96 * to initialise do not match the plugin's advertised preferred values
Chris@12 97 * from step 4, the plugin may refuse to initialise and return false
Chris@12 98 * (although if possible it should accept the new values). Any
Chris@12 99 * computationally expensive setup code should take place here.
Chris@12 100 *
Chris@12 101 * 6. Host finally checks the number of values, resolution, extents
Chris@12 102 * etc per output (which may vary depending on the number of channels,
Chris@12 103 * step size and block size as well as the parameter values).
Chris@12 104 *
Chris@12 105 * 7. Host will repeatedly call the process method to pass in blocks
Chris@12 106 * of input data. This method may return features extracted from that
Chris@12 107 * data (if the plugin is causal).
Chris@12 108 *
Chris@12 109 * 8. Host will call getRemainingFeatures exactly once, after all the
Chris@12 110 * input data has been processed. This may return any non-causal or
Chris@12 111 * leftover features.
Chris@12 112 *
Chris@12 113 * 9. At any point after initialise was called, the host may
Chris@12 114 * optionally call the reset method and restart processing. (This
Chris@12 115 * does not mean it can change the parameters, which are fixed from
Chris@12 116 * initialise until destruction.)
Chris@12 117 *
Chris@12 118 * A plugin does not need to handle the case where setParameter or
Chris@12 119 * selectProgram is called after initialise has been called. It's the
Chris@12 120 * host's responsibility not to do that. Similarly, the plugin may
Chris@12 121 * safely assume that initialise is called no more than once.
Chris@12 122 */
Chris@12 123
Chris@12 124 class Plugin : public PluginBase
Chris@12 125 {
Chris@12 126 public:
Chris@12 127 virtual ~Plugin() { }
Chris@12 128
Chris@12 129 /**
Chris@12 130 * Initialise a plugin to prepare it for use with the given number
Chris@12 131 * of input channels, step size (window increment, in sample
Chris@12 132 * frames) and block size (window size, in sample frames).
Chris@12 133 *
Chris@12 134 * The input sample rate should have been already specified at
Chris@12 135 * construction time.
Chris@12 136 *
Chris@12 137 * Return true for successful initialisation, false if the number
Chris@12 138 * of input channels, step size and/or block size cannot be
Chris@12 139 * supported.
Chris@12 140 */
Chris@12 141 virtual bool initialise(size_t inputChannels,
Chris@12 142 size_t stepSize,
Chris@12 143 size_t blockSize) = 0;
Chris@12 144
Chris@12 145 /**
Chris@12 146 * Reset the plugin after use, to prepare it for another clean
Chris@12 147 * run. Not called for the first initialisation (i.e. initialise
Chris@12 148 * must also do a reset).
Chris@12 149 */
Chris@12 150 virtual void reset() = 0;
Chris@12 151
Chris@12 152 enum InputDomain { TimeDomain, FrequencyDomain };
Chris@12 153
Chris@12 154 /**
Chris@12 155 * Get the plugin's required input domain.
Chris@12 156 *
Chris@12 157 * If this is TimeDomain, the samples provided to the process()
Chris@12 158 * function (below) will be in the time domain, as for a
Chris@12 159 * traditional audio processing plugin.
Chris@12 160 *
Chris@12 161 * If this is FrequencyDomain, the host will carry out a windowed
Chris@12 162 * FFT of size equal to the negotiated block size on the data
Chris@12 163 * before passing the frequency bin data in to process(). The
Chris@12 164 * input data for the FFT will be rotated so as to place the
Chris@12 165 * origin in the centre of the block.
Chris@12 166 * The plugin does not get to choose the window type -- the host
Chris@12 167 * will either let the user do so, or will use a Hanning window.
Chris@12 168 */
Chris@12 169 virtual InputDomain getInputDomain() const = 0;
Chris@12 170
Chris@12 171 /**
Chris@12 172 * Get the preferred block size (window size -- the number of
Chris@12 173 * sample frames passed in each block to the process() function).
Chris@12 174 * This should be called before initialise().
Chris@12 175 *
Chris@12 176 * A plugin that can handle any block size may return 0. The
Chris@12 177 * final block size will be set in the initialise() call.
Chris@12 178 */
Chris@12 179 virtual size_t getPreferredBlockSize() const { return 0; }
Chris@12 180
Chris@12 181 /**
Chris@12 182 * Get the preferred step size (window increment -- the distance
Chris@12 183 * in sample frames between the start frames of consecutive blocks
Chris@12 184 * passed to the process() function) for the plugin. This should
Chris@12 185 * be called before initialise().
Chris@12 186 *
Chris@12 187 * A plugin may return 0 if it has no particular interest in the
Chris@12 188 * step size. In this case, the host should make the step size
Chris@12 189 * equal to the block size if the plugin is accepting input in the
Chris@12 190 * time domain. If the plugin is accepting input in the frequency
Chris@12 191 * domain, the host may use any step size. The final step size
Chris@12 192 * will be set in the initialise() call.
Chris@12 193 */
Chris@12 194 virtual size_t getPreferredStepSize() const { return 0; }
Chris@12 195
Chris@12 196 /**
Chris@12 197 * Get the minimum supported number of input channels.
Chris@12 198 */
Chris@12 199 virtual size_t getMinChannelCount() const { return 1; }
Chris@12 200
Chris@12 201 /**
Chris@12 202 * Get the maximum supported number of input channels.
Chris@12 203 */
Chris@12 204 virtual size_t getMaxChannelCount() const { return 1; }
Chris@12 205
Chris@12 206 struct OutputDescriptor
Chris@12 207 {
Chris@12 208 /**
Chris@12 209 * The name of the output, in computer-usable form. Should be
Chris@12 210 * reasonably short and without whitespace or punctuation, using
Chris@12 211 * the characters [a-zA-Z0-9_-] only.
Chris@12 212 * Example: "zero_crossing_count"
Chris@12 213 */
Chris@12 214 std::string identifier;
Chris@12 215
Chris@12 216 /**
Chris@12 217 * The human-readable name of the output.
Chris@12 218 * Example: "Zero Crossing Counts"
Chris@12 219 */
Chris@12 220 std::string name;
Chris@12 221
Chris@12 222 /**
Chris@12 223 * A human-readable short text describing the output. May be
Chris@12 224 * empty if the name has said it all already.
Chris@12 225 * Example: "The number of zero crossing points per processing block"
Chris@12 226 */
Chris@12 227 std::string description;
Chris@12 228
Chris@12 229 /**
Chris@12 230 * The unit of the output, in human-readable form.
Chris@12 231 */
Chris@12 232 std::string unit;
Chris@12 233
Chris@12 234 /**
Chris@12 235 * True if the output has the same number of values per sample
Chris@12 236 * for every output sample. Outputs for which this is false
Chris@12 237 * are unlikely to be very useful in a general-purpose host.
Chris@12 238 */
Chris@12 239 bool hasFixedBinCount;
Chris@12 240
Chris@12 241 /**
Chris@12 242 * The number of values per result of the output. Undefined
Chris@12 243 * if hasFixedBinCount is false. If this is zero, the output
Chris@12 244 * is point data (i.e. only the time of each output is of
Chris@12 245 * interest, the value list will be empty).
Chris@12 246 */
Chris@12 247 size_t binCount;
Chris@12 248
Chris@12 249 /**
Chris@12 250 * The (human-readable) names of each of the bins, if
Chris@12 251 * appropriate. This is always optional.
Chris@12 252 */
Chris@12 253 std::vector<std::string> binNames;
Chris@12 254
Chris@12 255 /**
Chris@12 256 * True if the results in each output bin fall within a fixed
Chris@12 257 * numeric range (minimum and maximum values). Undefined if
Chris@12 258 * binCount is zero.
Chris@12 259 */
Chris@12 260 bool hasKnownExtents;
Chris@12 261
Chris@12 262 /**
Chris@12 263 * Minimum value of the results in the output. Undefined if
Chris@12 264 * hasKnownExtents is false or binCount is zero.
Chris@12 265 */
Chris@12 266 float minValue;
Chris@12 267
Chris@12 268 /**
Chris@12 269 * Maximum value of the results in the output. Undefined if
Chris@12 270 * hasKnownExtents is false or binCount is zero.
Chris@12 271 */
Chris@12 272 float maxValue;
Chris@12 273
Chris@12 274 /**
Chris@12 275 * True if the output values are quantized to a particular
Chris@12 276 * resolution. Undefined if binCount is zero.
Chris@12 277 */
Chris@12 278 bool isQuantized;
Chris@12 279
Chris@12 280 /**
Chris@12 281 * Quantization resolution of the output values (e.g. 1.0 if
Chris@12 282 * they are all integers). Undefined if isQuantized is false
Chris@12 283 * or binCount is zero.
Chris@12 284 */
Chris@12 285 float quantizeStep;
Chris@12 286
Chris@12 287 enum SampleType {
Chris@12 288
Chris@12 289 /// Results from each process() align with that call's block start
Chris@12 290 OneSamplePerStep,
Chris@12 291
Chris@12 292 /// Results are evenly spaced in time (sampleRate specified below)
Chris@12 293 FixedSampleRate,
Chris@12 294
Chris@12 295 /// Results are unevenly spaced and have individual timestamps
Chris@12 296 VariableSampleRate
Chris@12 297 };
Chris@12 298
Chris@12 299 /**
Chris@12 300 * Positioning in time of the output results.
Chris@12 301 */
Chris@12 302 SampleType sampleType;
Chris@12 303
Chris@12 304 /**
Chris@12 305 * Sample rate of the output results, as samples per second.
Chris@12 306 * Undefined if sampleType is OneSamplePerStep.
Chris@12 307 *
Chris@12 308 * If sampleType is VariableSampleRate and this value is
Chris@12 309 * non-zero, then it may be used to calculate a resolution for
Chris@12 310 * the output (i.e. the "duration" of each sample, in time,
Chris@12 311 * will be 1/sampleRate seconds). It's recommended to set
Chris@12 312 * this to zero if that behaviour is not desired.
Chris@12 313 */
Chris@12 314 float sampleRate;
Chris@12 315
Chris@12 316 /**
Chris@12 317 * True if the returned results for this output are known to
Chris@12 318 * have a duration field.
Chris@12 319 */
Chris@12 320 bool hasDuration;
Chris@12 321
Chris@12 322 OutputDescriptor() : // defaults for mandatory non-class-type members
Chris@12 323 hasFixedBinCount(false), hasKnownExtents(false), isQuantized(false),
Chris@12 324 sampleType(OneSamplePerStep), hasDuration(false) { }
Chris@12 325 };
Chris@12 326
Chris@12 327 typedef std::vector<OutputDescriptor> OutputList;
Chris@12 328
Chris@12 329 /**
Chris@12 330 * Get the outputs of this plugin. An output's index in this list
Chris@12 331 * is used as its numeric index when looking it up in the
Chris@12 332 * FeatureSet returned from the process() call.
Chris@12 333 */
Chris@12 334 virtual OutputList getOutputDescriptors() const = 0;
Chris@12 335
Chris@12 336 struct Feature
Chris@12 337 {
Chris@12 338 /**
Chris@12 339 * True if an output feature has its own timestamp. This is
Chris@12 340 * mandatory if the output has VariableSampleRate, optional if
Chris@12 341 * the output has FixedSampleRate, and unused if the output
Chris@12 342 * has OneSamplePerStep.
Chris@12 343 */
Chris@12 344 bool hasTimestamp;
Chris@12 345
Chris@12 346 /**
Chris@12 347 * Timestamp of the output feature. This is mandatory if the
Chris@12 348 * output has VariableSampleRate or if the output has
Chris@12 349 * FixedSampleRate and hasTimestamp is true, and unused
Chris@12 350 * otherwise.
Chris@12 351 */
Chris@12 352 RealTime timestamp;
Chris@12 353
Chris@12 354 /**
Chris@12 355 * True if an output feature has a specified duration. This
Chris@12 356 * is optional if the output has VariableSampleRate or
Chris@12 357 * FixedSampleRate, and and unused if the output has
Chris@12 358 * OneSamplePerStep.
Chris@12 359 */
Chris@12 360 bool hasDuration;
Chris@12 361
Chris@12 362 /**
Chris@12 363 * Duration of the output feature. This is mandatory if the
Chris@12 364 * output has VariableSampleRate or FixedSampleRate and
Chris@12 365 * hasDuration is true, and unused otherwise.
Chris@12 366 */
Chris@12 367 RealTime duration;
Chris@12 368
Chris@12 369 /**
Chris@12 370 * Results for a single sample of this feature. If the output
Chris@12 371 * hasFixedBinCount, there must be the same number of values
Chris@12 372 * as the output's binCount count.
Chris@12 373 */
Chris@12 374 std::vector<float> values;
Chris@12 375
Chris@12 376 /**
Chris@12 377 * Label for the sample of this feature.
Chris@12 378 */
Chris@12 379 std::string label;
Chris@12 380
Chris@12 381 Feature() : // defaults for mandatory non-class-type members
Chris@12 382 hasTimestamp(false), hasDuration(false) { }
Chris@12 383 };
Chris@12 384
Chris@12 385 typedef std::vector<Feature> FeatureList;
Chris@12 386
Chris@12 387 typedef std::map<int, FeatureList> FeatureSet; // key is output no
Chris@12 388
Chris@12 389 /**
Chris@12 390 * Process a single block of input data.
Chris@12 391 *
Chris@12 392 * If the plugin's inputDomain is TimeDomain, inputBuffers will
Chris@12 393 * point to one array of floats per input channel, and each of
Chris@12 394 * these arrays will contain blockSize consecutive audio samples
Chris@12 395 * (the host will zero-pad as necessary). The timestamp in this
Chris@12 396 * case will be the real time in seconds of the start of the
Chris@12 397 * supplied block of samples.
Chris@12 398 *
Chris@12 399 * If the plugin's inputDomain is FrequencyDomain, inputBuffers
Chris@12 400 * will point to one array of floats per input channel, and each
Chris@12 401 * of these arrays will contain blockSize/2+1 consecutive pairs of
Chris@12 402 * real and imaginary component floats corresponding to bins
Chris@12 403 * 0..(blockSize/2) of the FFT output. That is, bin 0 (the first
Chris@12 404 * pair of floats) contains the DC output, up to bin blockSize/2
Chris@12 405 * which contains the Nyquist-frequency output. There will
Chris@12 406 * therefore be blockSize+2 floats per channel in total. The
Chris@12 407 * timestamp will be the real time in seconds of the centre of the
Chris@12 408 * FFT input window (i.e. the very first block passed to process
Chris@12 409 * might contain the FFT of half a block of zero samples and the
Chris@12 410 * first half-block of the actual data, with a timestamp of zero).
Chris@12 411 *
Chris@12 412 * Return any features that have become available after this
Chris@12 413 * process call. (These do not necessarily have to fall within
Chris@12 414 * the process block, except for OneSamplePerStep outputs.)
Chris@12 415 */
Chris@12 416 virtual FeatureSet process(const float *const *inputBuffers,
Chris@12 417 RealTime timestamp) = 0;
Chris@12 418
Chris@12 419 /**
Chris@12 420 * After all blocks have been processed, calculate and return any
Chris@12 421 * remaining features derived from the complete input.
Chris@12 422 */
Chris@12 423 virtual FeatureSet getRemainingFeatures() = 0;
Chris@12 424
Chris@12 425 /**
Chris@12 426 * Used to distinguish between Vamp::Plugin and other potential
Chris@12 427 * sibling subclasses of PluginBase. Do not reimplement this
Chris@12 428 * function in your subclass.
Chris@12 429 */
Chris@12 430 virtual std::string getType() const { return "Feature Extraction Plugin"; }
Chris@12 431
Chris@12 432 protected:
Chris@12 433 Plugin(float inputSampleRate) :
Chris@12 434 m_inputSampleRate(inputSampleRate) { }
Chris@12 435
Chris@12 436 float m_inputSampleRate;
Chris@12 437 };
Chris@12 438
Chris@12 439 }
Chris@12 440
Chris@12 441 _VAMP_SDK_PLUGSPACE_END(Plugin.h)
Chris@12 442
Chris@12 443 #endif
Chris@12 444
Chris@12 445
Chris@12 446