annotate plugin/FeatureExtractionPlugin.h @ 24:bb9291d84810

* Add ffwd/rewind * Abstract out MultiSelection
author Chris Cannam
date Wed, 08 Feb 2006 17:59:16 +0000
parents a7ed14263fe4
children 39ae3dee27b9
rev   line source
Chris@0 1 /* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@0 4 A waveform viewer and audio annotation editor.
Chris@2 5 Chris Cannam, Queen Mary University of London, 2005-2006
Chris@0 6
Chris@0 7 This is experimental software. Not for distribution.
Chris@0 8 */
Chris@0 9
Chris@0 10 #ifndef _FEATURE_EXTRACTION_PLUGIN_H_
Chris@0 11 #define _FEATURE_EXTRACTION_PLUGIN_H_
Chris@0 12
Chris@0 13 /**
Chris@0 14 * A base class for feature extraction plugins.
Chris@0 15 */
Chris@0 16
Chris@0 17 #include <string>
Chris@0 18 #include <vector>
Chris@0 19 #include <map>
Chris@0 20
Chris@0 21 #include "base/RealTime.h"
Chris@0 22
Chris@0 23 /**
Chris@0 24 * FeatureExtractionPlugin is a base class for plugin instance classes
Chris@0 25 * that provide feature extraction from audio or related data.
Chris@0 26 *
Chris@0 27 * In most cases, the input will be audio and the output will be a
Chris@0 28 * stream of derived data at a lower sampling resolution than the
Chris@0 29 * input.
Chris@0 30 */
Chris@0 31
Chris@0 32 class FeatureExtractionPlugin
Chris@0 33 {
Chris@0 34 public:
Chris@0 35 /**
Chris@0 36 * Initialise a plugin to prepare it for use with the given number
Chris@0 37 * of input channels, step size (window increment, in sample
Chris@0 38 * frames) and block size (window size, in sample frames).
Chris@0 39 *
Chris@0 40 * The input sample rate should have been already specified at
Chris@0 41 * construction time.
Chris@0 42 *
Chris@0 43 * Return true for successful initialisation, false if the number
Chris@0 44 * of input channels, step size and/or block size cannot be
Chris@0 45 * supported.
Chris@0 46 */
Chris@0 47 virtual bool initialise(size_t inputChannels,
Chris@0 48 size_t stepSize,
Chris@0 49 size_t blockSize) = 0;
Chris@0 50
Chris@0 51 /**
Chris@0 52 * Reset the plugin after use, to prepare it for another clean
Chris@0 53 * run. Not called for the first initialisation (i.e. initialise
Chris@0 54 * must also do a reset).
Chris@0 55 */
Chris@0 56 virtual void reset() = 0;
Chris@0 57
Chris@0 58 /**
Chris@0 59 * Get the computer-usable name of the plugin. This should be
Chris@0 60 * reasonably short and contain no whitespace or punctuation
Chris@0 61 * characters.
Chris@0 62 */
Chris@0 63 virtual std::string getName() const = 0;
Chris@0 64
Chris@0 65 /**
Chris@0 66 * Get a human-readable description of the plugin. This should be
Chris@0 67 * self-contained, as it may be shown to the user in isolation
Chris@0 68 * without also showing the plugin's "name".
Chris@0 69 */
Chris@0 70 virtual std::string getDescription() const = 0;
Chris@0 71
Chris@0 72 /**
Chris@0 73 * Get the name of the author or vendor of the plugin in
Chris@0 74 * human-readable form.
Chris@0 75 */
Chris@0 76 virtual std::string getMaker() const = 0;
Chris@0 77
Chris@0 78 /**
Chris@0 79 * Get the version number of the plugin.
Chris@0 80 */
Chris@0 81 virtual int getPluginVersion() const = 0;
Chris@0 82
Chris@0 83 /**
Chris@0 84 * Get the copyright statement or licensing summary of the plugin.
Chris@0 85 */
Chris@0 86 virtual std::string getCopyright() const = 0;
Chris@0 87
Chris@0 88 /**
Chris@0 89 * Get the preferred step size (window increment -- the distance
Chris@0 90 * in sample frames between the start frames of consecutive blocks
Chris@0 91 * passed to the process() function) for the plugin. This should
Chris@0 92 * be called before initialise().
Chris@0 93 */
Chris@0 94 virtual size_t getPreferredStepSize() const = 0;
Chris@0 95
Chris@0 96 /**
Chris@0 97 * Get the preferred block size (window size -- the number of
Chris@0 98 * sample frames passed in each block to the process() function).
Chris@0 99 * This should be called before initialise().
Chris@0 100 */
Chris@0 101 virtual size_t getPreferredBlockSize() const { return getPreferredStepSize(); }
Chris@0 102
Chris@0 103 /**
Chris@0 104 * Get the minimum supported number of input channels.
Chris@0 105 */
Chris@0 106 virtual size_t getMinChannelCount() const { return 1; }
Chris@0 107
Chris@0 108 /**
Chris@0 109 * Get the maximum supported number of input channels.
Chris@0 110 */
Chris@0 111 virtual size_t getMaxChannelCount() const { return 1; }
Chris@0 112
Chris@0 113
Chris@0 114 struct OutputDescriptor
Chris@0 115 {
Chris@0 116 /**
Chris@0 117 * The name of the output, in computer-usable form. Should be
Chris@0 118 * reasonably short and without whitespace or punctuation.
Chris@0 119 */
Chris@0 120 std::string name;
Chris@0 121
Chris@0 122 /**
Chris@0 123 * The human-readable name of the output.
Chris@0 124 */
Chris@0 125 std::string description;
Chris@0 126
Chris@0 127 /**
Chris@0 128 * The unit of the output, in human-readable form.
Chris@0 129 */
Chris@0 130 std::string unit;
Chris@0 131
Chris@0 132 /**
Chris@0 133 * True if the output has the same number of values per result
Chris@0 134 * for every output result. Outputs for which this is false
Chris@0 135 * are unlikely to be very useful in a general-purpose host.
Chris@0 136 */
Chris@0 137 bool hasFixedValueCount;
Chris@0 138
Chris@0 139 /**
Chris@0 140 * The number of values per result of the output. Undefined
Chris@0 141 * if hasFixedValueCount is false. If this is zero, the output
Chris@0 142 * is point data (i.e. only the time of each output is of
Chris@0 143 * interest, the value list will be empty).
Chris@0 144 *
Chris@0 145 * Note that this gives the number of values of a single
Chris@0 146 * output result, not of the output stream (which has one more
Chris@0 147 * dimension: time).
Chris@0 148 */
Chris@0 149 size_t valueCount;
Chris@0 150
Chris@0 151 /**
Chris@19 152 * The names of each of the values, if appropriate. This is
Chris@19 153 * always optional.
Chris@19 154 */
Chris@19 155 std::vector<std::string> valueNames;
Chris@19 156
Chris@19 157 /**
Chris@0 158 * True if the results in the output have a fixed numeric
Chris@0 159 * range (minimum and maximum values). Undefined if
Chris@0 160 * valueCount is zero.
Chris@0 161 */
Chris@0 162 bool hasKnownExtents;
Chris@0 163
Chris@0 164 /**
Chris@0 165 * Minimum value of the results in the output. Undefined if
Chris@0 166 * hasKnownExtents is false or valueCount is zero.
Chris@0 167 */
Chris@0 168 float minValue;
Chris@0 169
Chris@0 170 /**
Chris@0 171 * Maximum value of the results in the output. Undefined if
Chris@0 172 * hasKnownExtents is false or valueCount is zero.
Chris@0 173 */
Chris@0 174 float maxValue;
Chris@0 175
Chris@0 176 /**
Chris@0 177 * True if the output values are quantized to a particular
Chris@0 178 * resolution. Undefined if valueCount is zero.
Chris@0 179 */
Chris@0 180 bool isQuantized;
Chris@0 181
Chris@0 182 /**
Chris@0 183 * Quantization resolution of the output values (e.g. 1.0 if
Chris@0 184 * they are all integers). Undefined if isQuantized is false
Chris@0 185 * or valueCount is zero.
Chris@0 186 */
Chris@0 187 float quantizeStep;
Chris@0 188
Chris@0 189 enum SampleType {
Chris@0 190
Chris@0 191 /// Results from each process() align with that call's block start
Chris@0 192 OneSamplePerStep,
Chris@0 193
Chris@0 194 /// Results are evenly spaced in time (sampleRate specified below)
Chris@0 195 FixedSampleRate,
Chris@0 196
Chris@0 197 /// Results are unevenly spaced and have individual timestamps
Chris@0 198 VariableSampleRate
Chris@0 199 };
Chris@0 200
Chris@0 201 /**
Chris@0 202 * Positioning in time of the output results.
Chris@0 203 */
Chris@0 204 SampleType sampleType;
Chris@0 205
Chris@0 206 /**
Chris@0 207 * Sample rate of the output results. Undefined if sampleType
Chris@0 208 * is OneSamplePerStep.
Chris@0 209 *
Chris@0 210 * If sampleType is VariableSampleRate and this value is
Chris@0 211 * non-zero, then it may be used to calculate a resolution for
Chris@0 212 * the output (i.e. the "duration" of each value, in time).
Chris@0 213 * It's recommended to set this to zero if that behaviour is
Chris@0 214 * not desired.
Chris@0 215 */
Chris@0 216 float sampleRate;
Chris@0 217 };
Chris@0 218
Chris@0 219 typedef std::vector<OutputDescriptor> OutputList;
Chris@0 220
Chris@0 221 /**
Chris@0 222 * Get the outputs of this plugin. An output's index in this list
Chris@0 223 * is used as its numeric index when looking it up in the
Chris@0 224 * FeatureSet returned from the process() call.
Chris@0 225 */
Chris@0 226 virtual OutputList getOutputDescriptors() const = 0;
Chris@0 227
Chris@0 228
Chris@0 229 struct ParameterDescriptor
Chris@0 230 {
Chris@0 231 /**
Chris@0 232 * The name of the parameter, in computer-usable form. Should
Chris@0 233 * be reasonably short and without whitespace or punctuation.
Chris@0 234 */
Chris@0 235 std::string name;
Chris@0 236
Chris@0 237 /**
Chris@0 238 * The human-readable name of the parameter.
Chris@0 239 */
Chris@0 240 std::string description;
Chris@0 241
Chris@0 242 /**
Chris@0 243 * The unit of the parameter, in human-readable form.
Chris@0 244 */
Chris@0 245 std::string unit;
Chris@0 246
Chris@0 247 /**
Chris@0 248 * The minimum value of the parameter.
Chris@0 249 */
Chris@0 250 float minValue;
Chris@0 251
Chris@0 252 /**
Chris@0 253 * The maximum value of the parameter.
Chris@0 254 */
Chris@0 255 float maxValue;
Chris@0 256
Chris@0 257 /**
Chris@0 258 * The default value of the parameter.
Chris@0 259 */
Chris@0 260 float defaultValue;
Chris@0 261
Chris@0 262 /**
Chris@0 263 * True if the parameter values are quantized to a particular
Chris@0 264 * resolution.
Chris@0 265 */
Chris@0 266 bool isQuantized;
Chris@0 267
Chris@0 268 /**
Chris@0 269 * Quantization resolution of the parameter values (e.g. 1.0
Chris@0 270 * if they are all integers). Undefined if isQuantized is
Chris@0 271 * false.
Chris@0 272 */
Chris@0 273 float quantizeStep;
Chris@0 274 };
Chris@0 275
Chris@0 276 typedef std::vector<ParameterDescriptor> ParameterList;
Chris@0 277
Chris@0 278 /**
Chris@0 279 * Get the controllable parameters of this plugin.
Chris@0 280 */
Chris@0 281 virtual ParameterList getParameterDescriptors() const {
Chris@0 282 return ParameterList();
Chris@0 283 }
Chris@0 284
Chris@0 285 /**
Chris@0 286 * Get the value of a named parameter. The argument is the name
Chris@0 287 * field from that parameter's descriptor.
Chris@0 288 */
Chris@0 289 virtual float getParameter(std::string) const { return 0.0; }
Chris@0 290
Chris@0 291 /**
Chris@0 292 * Set a named parameter. The first argument is the name field
Chris@0 293 * from that parameter's descriptor.
Chris@0 294 */
Chris@0 295 virtual void setParameter(std::string, float) { }
Chris@0 296
Chris@0 297 struct Feature
Chris@0 298 {
Chris@0 299 /**
Chris@0 300 * True if an output feature has its own timestamp. This is
Chris@0 301 * mandatory if the output has VariableSampleRate, and is
Chris@0 302 * likely to be disregarded otherwise.
Chris@0 303 */
Chris@0 304 bool hasTimestamp;
Chris@0 305
Chris@0 306 /**
Chris@0 307 * Timestamp of the output feature. This is mandatory if the
Chris@0 308 * output has VariableSampleRate, and is likely to be
Chris@0 309 * disregarded otherwise. Undefined if hasTimestamp is false.
Chris@0 310 */
Chris@0 311 RealTime timestamp;
Chris@0 312
Chris@0 313 /**
Chris@0 314 * Results for a single sample of this feature. If the output
Chris@0 315 * hasFixedValueCount, there must be the same number of values
Chris@0 316 * as the output's valueCount count.
Chris@0 317 */
Chris@0 318 std::vector<float> values;
Chris@0 319
Chris@0 320 /**
Chris@0 321 * Label for the sample of this feature.
Chris@0 322 */
Chris@0 323 std::string label;
Chris@0 324 };
Chris@0 325
Chris@0 326 typedef std::vector<Feature> FeatureList;
Chris@0 327 typedef std::map<int, FeatureList> FeatureSet; // key is output no
Chris@0 328
Chris@0 329 /**
Chris@0 330 * Process a single block of input data. inputBuffers points to
Chris@0 331 * one array of floats per input channel, and each of those arrays
Chris@0 332 * contains the blockSize number of samples (the host will
Chris@0 333 * zero-pad as necessary). The timestamp is the real time in
Chris@0 334 * seconds of the start of the supplied block of samples.
Chris@0 335 *
Chris@0 336 * Return any features that have become available after this
Chris@0 337 * process call. (These do not necessarily have to fall within
Chris@0 338 * the process block, except for OneSamplePerStep outputs.)
Chris@0 339 */
Chris@0 340 virtual FeatureSet process(float **inputBuffers,
Chris@0 341 RealTime timestamp) = 0;
Chris@0 342
Chris@0 343 /**
Chris@0 344 * After all blocks have been processed, calculate and return any
Chris@0 345 * remaining features derived from the complete input.
Chris@0 346 */
Chris@0 347 virtual FeatureSet getRemainingFeatures() = 0;
Chris@0 348
Chris@0 349 protected:
Chris@0 350 FeatureExtractionPlugin(float inputSampleRate) :
Chris@0 351 m_inputSampleRate(inputSampleRate) { }
Chris@0 352
Chris@0 353 float m_inputSampleRate;
Chris@0 354 };
Chris@0 355
Chris@0 356 #endif
Chris@0 357
Chris@0 358
Chris@0 359