annotate vamp-hostsdk/PluginInputDomainAdapter.h @ 525:8c18bdaad04f c++11-mutex

Avoid simple static allocation of mutex, as it could lead to mutex being destroyed before last adapter that needs to use it (since adapters are usually also static)
author Chris Cannam
date Mon, 09 Sep 2019 10:24:13 +0100
parents 5cb298435765
children 8ffb8985ae8f
rev   line source
cannam@233 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
cannam@233 2
cannam@233 3 /*
cannam@233 4 Vamp
cannam@233 5
cannam@233 6 An API for audio analysis and feature extraction plugins.
cannam@233 7
cannam@233 8 Centre for Digital Music, Queen Mary, University of London.
cannam@290 9 Copyright 2006-2009 Chris Cannam and QMUL.
cannam@233 10
cannam@233 11 Permission is hereby granted, free of charge, to any person
cannam@233 12 obtaining a copy of this software and associated documentation
cannam@233 13 files (the "Software"), to deal in the Software without
cannam@233 14 restriction, including without limitation the rights to use, copy,
cannam@233 15 modify, merge, publish, distribute, sublicense, and/or sell copies
cannam@233 16 of the Software, and to permit persons to whom the Software is
cannam@233 17 furnished to do so, subject to the following conditions:
cannam@233 18
cannam@233 19 The above copyright notice and this permission notice shall be
cannam@233 20 included in all copies or substantial portions of the Software.
cannam@233 21
cannam@233 22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
cannam@233 23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
cannam@233 24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
cannam@233 25 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
cannam@233 26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
cannam@233 27 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
cannam@233 28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
cannam@233 29
cannam@233 30 Except as contained in this notice, the names of the Centre for
cannam@233 31 Digital Music; Queen Mary, University of London; and Chris Cannam
cannam@233 32 shall not be used in advertising or otherwise to promote the sale,
cannam@233 33 use or other dealings in this Software without prior written
cannam@233 34 authorization.
cannam@233 35 */
cannam@233 36
cannam@233 37 #ifndef _VAMP_PLUGIN_INPUT_DOMAIN_ADAPTER_H_
cannam@233 38 #define _VAMP_PLUGIN_INPUT_DOMAIN_ADAPTER_H_
cannam@233 39
cannam@243 40 #include "hostguard.h"
cannam@233 41 #include "PluginWrapper.h"
cannam@233 42
cannam@263 43 _VAMP_SDK_HOSTSPACE_BEGIN(PluginInputDomainAdapter.h)
cannam@263 44
cannam@233 45 namespace Vamp {
cannam@233 46
cannam@233 47 namespace HostExt {
cannam@233 48
cannam@233 49 /**
cannam@233 50 * \class PluginInputDomainAdapter PluginInputDomainAdapter.h <vamp-hostsdk/PluginInputDomainAdapter.h>
cannam@233 51 *
cannam@233 52 * PluginInputDomainAdapter is a Vamp plugin adapter that converts
cannam@233 53 * time-domain input into frequency-domain input for plugins that need
cannam@233 54 * it. This permits a host to use time- and frequency-domain plugins
cannam@233 55 * interchangeably without needing to handle the conversion itself.
cannam@233 56 *
Chris@317 57 * This adapter uses a basic windowed FFT (using Hann window by
Chris@317 58 * default) that supports power-of-two block sizes only. If a
Chris@317 59 * frequency domain plugin requests a non-power-of-two blocksize, the
Chris@317 60 * adapter will adjust it to a nearby power of two instead. Thus,
Chris@317 61 * getPreferredBlockSize() will always return a power of two if the
Chris@317 62 * wrapped plugin is a frequency domain one. If the plugin doesn't
Chris@317 63 * accept the adjusted power of two block size, initialise() will
Chris@317 64 * fail.
cannam@233 65 *
cannam@233 66 * The adapter provides no way for the host to discover whether the
cannam@233 67 * underlying plugin is actually a time or frequency domain plugin
cannam@233 68 * (except that if the preferred block size is not a power of two, it
cannam@233 69 * must be a time domain plugin).
cannam@233 70 *
cannam@233 71 * The FFT implementation is simple and self-contained, but unlikely
cannam@233 72 * to be the fastest available: a host can usually do better if it
cannam@233 73 * cares enough.
cannam@233 74 *
Chris@317 75 * The window shape for the FFT frame can be set using setWindowType
Chris@317 76 * and the current shape retrieved using getWindowType. (This was
Chris@317 77 * added in v2.3 of the SDK.)
Chris@317 78 *
cannam@233 79 * In every respect other than its input domain handling, the
cannam@233 80 * PluginInputDomainAdapter behaves identically to the plugin that it
cannam@233 81 * wraps. The wrapped plugin will be deleted when the wrapper is
cannam@233 82 * deleted.
cannam@233 83 *
cannam@233 84 * \note This class was introduced in version 1.1 of the Vamp plugin SDK.
cannam@233 85 */
cannam@233 86
cannam@233 87 class PluginInputDomainAdapter : public PluginWrapper
cannam@233 88 {
cannam@233 89 public:
cannam@248 90 /**
cannam@248 91 * Construct a PluginInputDomainAdapter wrapping the given plugin.
cannam@248 92 * The adapter takes ownership of the plugin, which will be
cannam@248 93 * deleted when the adapter is deleted.
cannam@248 94 */
cannam@248 95 PluginInputDomainAdapter(Plugin *plugin);
cannam@233 96 virtual ~PluginInputDomainAdapter();
cannam@233 97
cannam@233 98 bool initialise(size_t channels, size_t stepSize, size_t blockSize);
cannam@288 99 void reset();
cannam@233 100
cannam@233 101 InputDomain getInputDomain() const;
cannam@233 102
cannam@233 103 size_t getPreferredStepSize() const;
cannam@233 104 size_t getPreferredBlockSize() const;
cannam@233 105
cannam@233 106 FeatureSet process(const float *const *inputBuffers, RealTime timestamp);
cannam@233 107
cannam@233 108 /**
cannam@288 109 * ProcessTimestampMethod determines how the
cannam@288 110 * PluginInputDomainAdapter handles timestamps for the data passed
cannam@288 111 * to the process() function of the plugin it wraps, in the case
cannam@288 112 * where the plugin is expecting frequency-domain data.
cannam@288 113 *
cannam@298 114 * The Vamp specification requires that the timestamp passed to
cannam@298 115 * the plugin for frequency-domain input should be that of the
cannam@298 116 * centre of the processing block, rather than the start as is the
cannam@298 117 * case for time-domain input.
cannam@288 118 *
cannam@298 119 * Since PluginInputDomainAdapter aims to be transparent in use,
cannam@298 120 * it needs to handle this timestamp adjustment itself. However,
cannam@298 121 * some control is available over the method used for adjustment,
cannam@298 122 * by means of the ProcessTimestampMethod setting.
cannam@288 123 *
cannam@298 124 * If ProcessTimestampMethod is set to ShiftTimestamp (the
cannam@298 125 * default), then the data passed to the wrapped plugin will be
cannam@298 126 * calculated from the same input data block as passed to the
cannam@298 127 * wrapper, but the timestamp passed to the plugin will be
cannam@298 128 * advanced by half of the window size.
cannam@288 129 *
cannam@298 130 * If ProcessTimestampMethod is set to ShiftData, then the
cannam@298 131 * timestamp passed to the wrapped plugin will be the same as that
cannam@298 132 * passed to the process call of the wrapper, but the data block
cannam@298 133 * used to calculate the input will be shifted back (earlier) by
cannam@298 134 * half of the window size, with half a block of zero padding at
cannam@298 135 * the start of the first process call. This has the advantage of
cannam@298 136 * preserving the first half block of audio without any
cannam@298 137 * deterioration from window shaping.
cannam@298 138 *
cannam@298 139 * If ProcessTimestampMethod is set to NoShift, then no adjustment
cannam@298 140 * will be made and the timestamps will be incorrect.
cannam@298 141 */
cannam@298 142 enum ProcessTimestampMethod {
cannam@298 143 ShiftTimestamp,
cannam@298 144 ShiftData,
cannam@298 145 NoShift
cannam@298 146 };
cannam@298 147
cannam@298 148 /**
cannam@298 149 * Set the method used for timestamp adjustment in plugins taking
cannam@298 150 * frequency-domain input. See the ProcessTimestampMethod
cannam@298 151 * documentation for details.
cannam@288 152 *
cannam@288 153 * This function must be called before the first call to
cannam@288 154 * process().
cannam@288 155 */
cannam@298 156 void setProcessTimestampMethod(ProcessTimestampMethod);
cannam@288 157
cannam@298 158 /**
cannam@298 159 * Retrieve the method used for timestamp adjustment in plugins
cannam@298 160 * taking frequency-domain input. See the ProcessTimestampMethod
cannam@298 161 * documentation for details.
cannam@298 162 */
cannam@288 163 ProcessTimestampMethod getProcessTimestampMethod() const;
cannam@288 164
cannam@288 165 /**
cannam@233 166 * Return the amount by which the timestamps supplied to process()
cannam@233 167 * are being incremented when they are passed to the plugin's own
cannam@233 168 * process() implementation.
cannam@233 169 *
cannam@233 170 * The Vamp API mandates that the timestamp passed to the plugin
cannam@233 171 * for time-domain input should be the time of the first sample in
cannam@233 172 * the block, but the timestamp passed for frequency-domain input
cannam@233 173 * should be the timestamp of the centre of the block.
cannam@233 174 *
cannam@233 175 * The PluginInputDomainAdapter adjusts its timestamps properly so
cannam@233 176 * that the plugin receives correct times, but in some
cannam@233 177 * circumstances (such as for establishing the correct timing of
cannam@233 178 * implicitly-timed features, i.e. features without their own
cannam@233 179 * timestamps) the host may need to be aware that this adjustment
cannam@233 180 * is taking place.
cannam@233 181 *
cannam@288 182 * If the plugin requires time-domain input or the
cannam@288 183 * PluginInputDomainAdapter is configured with its
cannam@288 184 * ProcessTimestampMethod set to ShiftData instead of
cannam@288 185 * ShiftTimestamp, then this function will return zero.
cannam@288 186 *
cannam@288 187 * The result of calling this function before initialise() has
cannam@288 188 * been called is undefined.
cannam@233 189 */
cannam@233 190 RealTime getTimestampAdjustment() const;
cannam@233 191
Chris@317 192 /**
Chris@317 193 * The set of supported window shapes.
Chris@317 194 */
Chris@317 195 enum WindowType {
Chris@317 196
Chris@317 197 RectangularWindow = 0,
Chris@317 198
Chris@317 199 BartlettWindow = 1, /// synonym for RectangularWindow
Chris@317 200 TriangularWindow = 1, /// synonym for BartlettWindow
Chris@317 201
Chris@317 202 HammingWindow = 2,
Chris@317 203
Chris@317 204 HanningWindow = 3, /// synonym for HannWindow
Chris@317 205 HannWindow = 3, /// synonym for HanningWindow
Chris@317 206
Chris@317 207 BlackmanWindow = 4,
Chris@317 208
Chris@317 209 NuttallWindow = 7,
Chris@317 210
Chris@317 211 BlackmanHarrisWindow = 8
Chris@317 212 };
Chris@317 213
Chris@317 214 /**
Chris@317 215 * Return the current window shape. The default is HanningWindow.
Chris@317 216 */
Chris@317 217 WindowType getWindowType() const;
Chris@317 218
Chris@317 219 /**
Chris@317 220 * Set the current window shape.
Chris@317 221 */
Chris@317 222 void setWindowType(WindowType type);
Chris@317 223
Chris@317 224
cannam@233 225 protected:
cannam@233 226 class Impl;
cannam@233 227 Impl *m_impl;
cannam@233 228 };
cannam@233 229
cannam@233 230 }
cannam@233 231
cannam@233 232 }
cannam@233 233
cannam@263 234 _VAMP_SDK_HOSTSPACE_END(PluginInputDomainAdapter.h)
cannam@263 235
cannam@233 236 #endif