annotate vamp-sdk/PluginHostAdapter.cpp @ 9:44113b1e296b

* Add valueNames to parameter descriptor * Change valueCount and valueNames to binCount and binNames in output descriptor, to avoid confusion with other uses of value * Some explanatory notes about FFT alignment
author cannam
date Wed, 05 Apr 2006 16:50:07 +0000
parents c66551966b5f
children a3d35e11c3fe
rev   line source
cannam@1 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
cannam@1 2
cannam@1 3 /*
cannam@1 4 Vamp
cannam@1 5
cannam@1 6 An API for audio analysis and feature extraction plugins.
cannam@1 7
cannam@1 8 Centre for Digital Music, Queen Mary, University of London.
cannam@1 9 Copyright 2006 Chris Cannam.
cannam@1 10
cannam@1 11 Permission is hereby granted, free of charge, to any person
cannam@1 12 obtaining a copy of this software and associated documentation
cannam@1 13 files (the "Software"), to deal in the Software without
cannam@1 14 restriction, including without limitation the rights to use, copy,
cannam@1 15 modify, merge, publish, distribute, sublicense, and/or sell copies
cannam@1 16 of the Software, and to permit persons to whom the Software is
cannam@1 17 furnished to do so, subject to the following conditions:
cannam@1 18
cannam@1 19 The above copyright notice and this permission notice shall be
cannam@1 20 included in all copies or substantial portions of the Software.
cannam@1 21
cannam@1 22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
cannam@1 23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
cannam@1 24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
cannam@6 25 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
cannam@1 26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
cannam@1 27 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
cannam@1 28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
cannam@1 29
cannam@1 30 Except as contained in this notice, the names of the Centre for
cannam@1 31 Digital Music; Queen Mary, University of London; and Chris Cannam
cannam@1 32 shall not be used in advertising or otherwise to promote the sale,
cannam@1 33 use or other dealings in this Software without prior written
cannam@1 34 authorization.
cannam@1 35 */
cannam@1 36
cannam@1 37 #include "PluginHostAdapter.h"
cannam@1 38
cannam@1 39 namespace Vamp
cannam@1 40 {
cannam@1 41
cannam@1 42 PluginHostAdapter::PluginHostAdapter(const VampPluginDescriptor *descriptor,
cannam@1 43 float inputSampleRate) :
cannam@1 44 Plugin(inputSampleRate),
cannam@1 45 m_descriptor(descriptor)
cannam@1 46 {
cannam@1 47 std::cerr << "PluginHostAdapter::PluginHostAdapter (plugin = " << descriptor->name << ")" << std::endl;
cannam@1 48 m_handle = m_descriptor->instantiate(m_descriptor, inputSampleRate);
cannam@1 49 }
cannam@1 50
cannam@1 51 PluginHostAdapter::~PluginHostAdapter()
cannam@1 52 {
cannam@1 53 if (m_handle) m_descriptor->cleanup(m_handle);
cannam@1 54 }
cannam@1 55
cannam@1 56 bool
cannam@1 57 PluginHostAdapter::initialise(size_t channels,
cannam@1 58 size_t stepSize,
cannam@1 59 size_t blockSize)
cannam@1 60 {
cannam@1 61 if (!m_handle) return false;
cannam@1 62 return m_descriptor->initialise(m_handle, channels, stepSize, blockSize) ?
cannam@1 63 true : false;
cannam@1 64 }
cannam@1 65
cannam@1 66 void
cannam@1 67 PluginHostAdapter::reset()
cannam@1 68 {
cannam@1 69 if (!m_handle) return;
cannam@1 70 m_descriptor->reset(m_handle);
cannam@1 71 }
cannam@1 72
cannam@1 73 PluginHostAdapter::InputDomain
cannam@1 74 PluginHostAdapter::getInputDomain() const
cannam@1 75 {
cannam@1 76 if (m_descriptor->inputDomain == vampFrequencyDomain) {
cannam@1 77 return FrequencyDomain;
cannam@1 78 } else {
cannam@1 79 return TimeDomain;
cannam@1 80 }
cannam@1 81 }
cannam@1 82
cannam@1 83 std::string
cannam@1 84 PluginHostAdapter::getName() const
cannam@1 85 {
cannam@1 86 return m_descriptor->name;
cannam@1 87 }
cannam@1 88
cannam@1 89 std::string
cannam@1 90 PluginHostAdapter::getDescription() const
cannam@1 91 {
cannam@1 92 return m_descriptor->description;
cannam@1 93 }
cannam@1 94
cannam@1 95 std::string
cannam@1 96 PluginHostAdapter::getMaker() const
cannam@1 97 {
cannam@1 98 return m_descriptor->maker;
cannam@1 99 }
cannam@1 100
cannam@1 101 int
cannam@1 102 PluginHostAdapter::getPluginVersion() const
cannam@1 103 {
cannam@1 104 return m_descriptor->pluginVersion;
cannam@1 105 }
cannam@1 106
cannam@1 107 std::string
cannam@1 108 PluginHostAdapter::getCopyright() const
cannam@1 109 {
cannam@1 110 return m_descriptor->copyright;
cannam@1 111 }
cannam@1 112
cannam@1 113 PluginHostAdapter::ParameterList
cannam@1 114 PluginHostAdapter::getParameterDescriptors() const
cannam@1 115 {
cannam@1 116 ParameterList list;
cannam@1 117 for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
cannam@1 118 const VampParameterDescriptor *spd = m_descriptor->parameters[i];
cannam@1 119 ParameterDescriptor pd;
cannam@1 120 pd.name = spd->name;
cannam@1 121 pd.description = spd->description;
cannam@1 122 pd.unit = spd->unit;
cannam@1 123 pd.minValue = spd->minValue;
cannam@1 124 pd.maxValue = spd->maxValue;
cannam@1 125 pd.defaultValue = spd->defaultValue;
cannam@1 126 pd.isQuantized = spd->isQuantized;
cannam@1 127 pd.quantizeStep = spd->quantizeStep;
cannam@9 128 if (pd.isQuantized && spd->valueNames) {
cannam@9 129 for (unsigned int j = 0; spd->valueNames[j]; ++j) {
cannam@9 130 pd.valueNames.push_back(spd->valueNames[j]);
cannam@9 131 }
cannam@9 132 }
cannam@1 133 list.push_back(pd);
cannam@1 134 }
cannam@1 135 return list;
cannam@1 136 }
cannam@1 137
cannam@1 138 float
cannam@1 139 PluginHostAdapter::getParameter(std::string param) const
cannam@1 140 {
cannam@1 141 if (!m_handle) return 0.0;
cannam@1 142
cannam@1 143 for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
cannam@1 144 if (param == m_descriptor->parameters[i]->name) {
cannam@1 145 return m_descriptor->getParameter(m_handle, i);
cannam@1 146 }
cannam@1 147 }
cannam@1 148
cannam@1 149 return 0.0;
cannam@1 150 }
cannam@1 151
cannam@1 152 void
cannam@1 153 PluginHostAdapter::setParameter(std::string param,
cannam@1 154 float value)
cannam@1 155 {
cannam@1 156 if (!m_handle) return;
cannam@1 157
cannam@1 158 for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
cannam@1 159 if (param == m_descriptor->parameters[i]->name) {
cannam@1 160 m_descriptor->setParameter(m_handle, i, value);
cannam@1 161 return;
cannam@1 162 }
cannam@1 163 }
cannam@1 164 }
cannam@1 165
cannam@1 166 PluginHostAdapter::ProgramList
cannam@1 167 PluginHostAdapter::getPrograms() const
cannam@1 168 {
cannam@1 169 ProgramList list;
cannam@1 170
cannam@1 171 for (unsigned int i = 0; i < m_descriptor->programCount; ++i) {
cannam@1 172 list.push_back(m_descriptor->programs[i]);
cannam@1 173 }
cannam@1 174
cannam@1 175 return list;
cannam@1 176 }
cannam@1 177
cannam@1 178 std::string
cannam@1 179 PluginHostAdapter::getCurrentProgram() const
cannam@1 180 {
cannam@1 181 if (!m_handle) return "";
cannam@1 182
cannam@1 183 int pn = m_descriptor->getCurrentProgram(m_handle);
cannam@1 184 return m_descriptor->programs[pn];
cannam@1 185 }
cannam@1 186
cannam@1 187 void
cannam@1 188 PluginHostAdapter::selectProgram(std::string program)
cannam@1 189 {
cannam@1 190 if (!m_handle) return;
cannam@1 191
cannam@1 192 for (unsigned int i = 0; i < m_descriptor->programCount; ++i) {
cannam@1 193 if (program == m_descriptor->programs[i]) {
cannam@1 194 m_descriptor->selectProgram(m_handle, i);
cannam@1 195 return;
cannam@1 196 }
cannam@1 197 }
cannam@1 198 }
cannam@1 199
cannam@1 200 size_t
cannam@1 201 PluginHostAdapter::getPreferredStepSize() const
cannam@1 202 {
cannam@1 203 if (!m_handle) return 0;
cannam@1 204 return m_descriptor->getPreferredStepSize(m_handle);
cannam@1 205 }
cannam@1 206
cannam@1 207 size_t
cannam@1 208 PluginHostAdapter::getPreferredBlockSize() const
cannam@1 209 {
cannam@1 210 if (!m_handle) return 0;
cannam@1 211 return m_descriptor->getPreferredBlockSize(m_handle);
cannam@1 212 }
cannam@1 213
cannam@1 214 PluginHostAdapter::OutputList
cannam@1 215 PluginHostAdapter::getOutputDescriptors() const
cannam@1 216 {
cannam@1 217 OutputList list;
cannam@1 218 if (!m_handle) return list;
cannam@1 219
cannam@1 220 unsigned int count = m_descriptor->getOutputCount(m_handle);
cannam@1 221
cannam@1 222 for (unsigned int i = 0; i < count; ++i) {
cannam@1 223 VampOutputDescriptor *sd = m_descriptor->getOutputDescriptor(m_handle, i);
cannam@1 224 OutputDescriptor d;
cannam@1 225 d.name = sd->name;
cannam@1 226 d.description = sd->description;
cannam@1 227 d.unit = sd->unit;
cannam@9 228 d.hasFixedBinCount = sd->hasFixedBinCount;
cannam@9 229 d.binCount = sd->binCount;
cannam@9 230 if (d.hasFixedBinCount) {
cannam@9 231 for (unsigned int j = 0; j < sd->binCount; ++j) {
cannam@9 232 d.binNames.push_back(sd->binNames[j] ? sd->binNames[j] : "");
cannam@9 233 }
cannam@1 234 }
cannam@1 235 d.hasKnownExtents = sd->hasKnownExtents;
cannam@1 236 d.minValue = sd->minValue;
cannam@1 237 d.maxValue = sd->maxValue;
cannam@1 238 d.isQuantized = sd->isQuantized;
cannam@1 239 d.quantizeStep = sd->quantizeStep;
cannam@1 240
cannam@1 241 switch (sd->sampleType) {
cannam@1 242 case vampOneSamplePerStep:
cannam@1 243 d.sampleType = OutputDescriptor::OneSamplePerStep; break;
cannam@1 244 case vampFixedSampleRate:
cannam@1 245 d.sampleType = OutputDescriptor::FixedSampleRate; break;
cannam@1 246 case vampVariableSampleRate:
cannam@1 247 d.sampleType = OutputDescriptor::VariableSampleRate; break;
cannam@1 248 }
cannam@1 249
cannam@1 250 d.sampleRate = sd->sampleRate;
cannam@1 251
cannam@1 252 list.push_back(d);
cannam@1 253
cannam@1 254 m_descriptor->releaseOutputDescriptor(sd);
cannam@1 255 }
cannam@1 256
cannam@1 257 return list;
cannam@1 258 }
cannam@1 259
cannam@1 260 PluginHostAdapter::FeatureSet
cannam@1 261 PluginHostAdapter::process(float **inputBuffers,
cannam@1 262 RealTime timestamp)
cannam@1 263 {
cannam@1 264 FeatureSet fs;
cannam@1 265 if (!m_handle) return fs;
cannam@1 266
cannam@1 267 int sec = timestamp.sec;
cannam@1 268 int nsec = timestamp.nsec;
cannam@1 269
cannam@1 270 VampFeatureList **features = m_descriptor->process(m_handle,
cannam@1 271 inputBuffers,
cannam@1 272 sec, nsec);
cannam@1 273
cannam@1 274 convertFeatures(features, fs);
cannam@1 275 m_descriptor->releaseFeatureSet(features);
cannam@1 276 return fs;
cannam@1 277 }
cannam@1 278
cannam@1 279 PluginHostAdapter::FeatureSet
cannam@1 280 PluginHostAdapter::getRemainingFeatures()
cannam@1 281 {
cannam@1 282 FeatureSet fs;
cannam@1 283 if (!m_handle) return fs;
cannam@1 284
cannam@1 285 VampFeatureList **features = m_descriptor->getRemainingFeatures(m_handle);
cannam@1 286
cannam@1 287 convertFeatures(features, fs);
cannam@1 288 m_descriptor->releaseFeatureSet(features);
cannam@1 289 return fs;
cannam@1 290 }
cannam@1 291
cannam@1 292 void
cannam@1 293 PluginHostAdapter::convertFeatures(VampFeatureList **features,
cannam@1 294 FeatureSet &fs)
cannam@1 295 {
cannam@7 296 if (!features) return;
cannam@7 297
cannam@1 298 for (unsigned int i = 0; features[i]; ++i) {
cannam@1 299
cannam@1 300 VampFeatureList &list = *features[i];
cannam@1 301
cannam@1 302 if (list.featureCount > 0) {
cannam@1 303
cannam@1 304 for (unsigned int j = 0; j < list.featureCount; ++j) {
cannam@1 305
cannam@1 306 Feature feature;
cannam@1 307 feature.hasTimestamp = list.features[j].hasTimestamp;
cannam@1 308 feature.timestamp = RealTime(list.features[j].sec,
cannam@1 309 list.features[j].nsec);
cannam@1 310
cannam@1 311 for (unsigned int k = 0; k < list.features[j].valueCount; ++k) {
cannam@1 312 feature.values.push_back(list.features[j].values[k]);
cannam@1 313 }
cannam@7 314
cannam@7 315 if (list.features[j].label) {
cannam@7 316 feature.label = list.features[j].label;
cannam@7 317 }
cannam@1 318
cannam@1 319 fs[i].push_back(feature);
cannam@1 320 }
cannam@1 321 }
cannam@1 322 }
cannam@1 323 }
cannam@1 324
cannam@1 325 }