annotate vamp-sdk/PluginHostAdapter.cpp @ 211:caa9d07bb9bd

* Update VC project file to handle proper export of plugin lookup function, and use the right dll name to match the other platforms and the .cat file
author cannam
date Sat, 18 Oct 2008 16:51:51 +0000
parents fe30a25ee4f8
children
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@130 38 #include <cstdlib>
cannam@1 39
cannam@1 40 namespace Vamp
cannam@1 41 {
cannam@1 42
cannam@1 43 PluginHostAdapter::PluginHostAdapter(const VampPluginDescriptor *descriptor,
cannam@1 44 float inputSampleRate) :
cannam@1 45 Plugin(inputSampleRate),
cannam@1 46 m_descriptor(descriptor)
cannam@1 47 {
cannam@15 48 // std::cerr << "PluginHostAdapter::PluginHostAdapter (plugin = " << descriptor->name << ")" << std::endl;
cannam@1 49 m_handle = m_descriptor->instantiate(m_descriptor, inputSampleRate);
cannam@15 50 if (!m_handle) {
cannam@15 51 // std::cerr << "WARNING: PluginHostAdapter: Plugin instantiation failed for plugin " << m_descriptor->name << std::endl;
cannam@15 52 }
cannam@1 53 }
cannam@1 54
cannam@1 55 PluginHostAdapter::~PluginHostAdapter()
cannam@1 56 {
cannam@15 57 // std::cerr << "PluginHostAdapter::~PluginHostAdapter (plugin = " << m_descriptor->name << ")" << std::endl;
cannam@1 58 if (m_handle) m_descriptor->cleanup(m_handle);
cannam@1 59 }
cannam@1 60
cannam@32 61 std::vector<std::string>
cannam@32 62 PluginHostAdapter::getPluginPath()
cannam@32 63 {
cannam@32 64 std::vector<std::string> path;
cannam@32 65 std::string envPath;
cannam@32 66
cannam@32 67 char *cpath = getenv("VAMP_PATH");
cannam@32 68 if (cpath) envPath = cpath;
cannam@32 69
cannam@32 70 #ifdef _WIN32
cannam@32 71 #define PATH_SEPARATOR ';'
cannam@32 72 #define DEFAULT_VAMP_PATH "%ProgramFiles%\\Vamp Plugins"
cannam@32 73 #else
cannam@32 74 #define PATH_SEPARATOR ':'
cannam@32 75 #ifdef __APPLE__
cannam@35 76 #define DEFAULT_VAMP_PATH "$HOME/Library/Audio/Plug-Ins/Vamp:/Library/Audio/Plug-Ins/Vamp"
cannam@32 77 #else
cannam@35 78 #define DEFAULT_VAMP_PATH "$HOME/vamp:$HOME/.vamp:/usr/local/lib/vamp:/usr/lib/vamp"
cannam@32 79 #endif
cannam@32 80 #endif
cannam@32 81
cannam@32 82 if (envPath == "") {
cannam@32 83 envPath = DEFAULT_VAMP_PATH;
cannam@32 84 char *chome = getenv("HOME");
cannam@32 85 if (chome) {
cannam@32 86 std::string home(chome);
cannam@32 87 std::string::size_type f;
cannam@32 88 while ((f = envPath.find("$HOME")) != std::string::npos &&
cannam@32 89 f < envPath.length()) {
cannam@32 90 envPath.replace(f, 5, home);
cannam@32 91 }
cannam@32 92 }
cannam@32 93 #ifdef _WIN32
cannam@32 94 char *cpfiles = getenv("ProgramFiles");
cannam@32 95 if (!cpfiles) cpfiles = "C:\\Program Files";
cannam@32 96 std::string pfiles(cpfiles);
cannam@32 97 std::string::size_type f;
cannam@32 98 while ((f = envPath.find("%ProgramFiles%")) != std::string::npos &&
cannam@32 99 f < envPath.length()) {
cannam@32 100 envPath.replace(f, 14, pfiles);
cannam@32 101 }
cannam@32 102 #endif
cannam@32 103 }
cannam@32 104
cannam@32 105 std::string::size_type index = 0, newindex = 0;
cannam@32 106
cannam@32 107 while ((newindex = envPath.find(PATH_SEPARATOR, index)) < envPath.size()) {
cannam@32 108 path.push_back(envPath.substr(index, newindex - index));
cannam@32 109 index = newindex + 1;
cannam@32 110 }
cannam@32 111
cannam@32 112 path.push_back(envPath.substr(index));
cannam@32 113
cannam@32 114 return path;
cannam@32 115 }
cannam@32 116
cannam@1 117 bool
cannam@1 118 PluginHostAdapter::initialise(size_t channels,
cannam@1 119 size_t stepSize,
cannam@1 120 size_t blockSize)
cannam@1 121 {
cannam@1 122 if (!m_handle) return false;
cannam@1 123 return m_descriptor->initialise(m_handle, channels, stepSize, blockSize) ?
cannam@1 124 true : false;
cannam@1 125 }
cannam@1 126
cannam@1 127 void
cannam@1 128 PluginHostAdapter::reset()
cannam@1 129 {
cannam@197 130 if (!m_handle) {
cannam@197 131 // std::cerr << "PluginHostAdapter::reset: no handle" << std::endl;
cannam@197 132 return;
cannam@197 133 }
cannam@197 134 // std::cerr << "PluginHostAdapter::reset(" << m_handle << ")" << std::endl;
cannam@1 135 m_descriptor->reset(m_handle);
cannam@1 136 }
cannam@1 137
cannam@1 138 PluginHostAdapter::InputDomain
cannam@1 139 PluginHostAdapter::getInputDomain() const
cannam@1 140 {
cannam@1 141 if (m_descriptor->inputDomain == vampFrequencyDomain) {
cannam@1 142 return FrequencyDomain;
cannam@1 143 } else {
cannam@1 144 return TimeDomain;
cannam@1 145 }
cannam@1 146 }
cannam@1 147
cannam@50 148 unsigned int
cannam@50 149 PluginHostAdapter::getVampApiVersion() const
cannam@50 150 {
cannam@50 151 return m_descriptor->vampApiVersion;
cannam@50 152 }
cannam@50 153
cannam@1 154 std::string
cannam@49 155 PluginHostAdapter::getIdentifier() const
cannam@49 156 {
cannam@49 157 return m_descriptor->identifier;
cannam@49 158 }
cannam@49 159
cannam@49 160 std::string
cannam@1 161 PluginHostAdapter::getName() const
cannam@1 162 {
cannam@1 163 return m_descriptor->name;
cannam@1 164 }
cannam@1 165
cannam@1 166 std::string
cannam@1 167 PluginHostAdapter::getDescription() const
cannam@1 168 {
cannam@1 169 return m_descriptor->description;
cannam@1 170 }
cannam@1 171
cannam@1 172 std::string
cannam@1 173 PluginHostAdapter::getMaker() const
cannam@1 174 {
cannam@1 175 return m_descriptor->maker;
cannam@1 176 }
cannam@1 177
cannam@1 178 int
cannam@1 179 PluginHostAdapter::getPluginVersion() const
cannam@1 180 {
cannam@1 181 return m_descriptor->pluginVersion;
cannam@1 182 }
cannam@1 183
cannam@1 184 std::string
cannam@1 185 PluginHostAdapter::getCopyright() const
cannam@1 186 {
cannam@1 187 return m_descriptor->copyright;
cannam@1 188 }
cannam@1 189
cannam@1 190 PluginHostAdapter::ParameterList
cannam@1 191 PluginHostAdapter::getParameterDescriptors() const
cannam@1 192 {
cannam@1 193 ParameterList list;
cannam@1 194 for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
cannam@1 195 const VampParameterDescriptor *spd = m_descriptor->parameters[i];
cannam@1 196 ParameterDescriptor pd;
cannam@49 197 pd.identifier = spd->identifier;
cannam@1 198 pd.name = spd->name;
cannam@1 199 pd.description = spd->description;
cannam@1 200 pd.unit = spd->unit;
cannam@1 201 pd.minValue = spd->minValue;
cannam@1 202 pd.maxValue = spd->maxValue;
cannam@1 203 pd.defaultValue = spd->defaultValue;
cannam@1 204 pd.isQuantized = spd->isQuantized;
cannam@1 205 pd.quantizeStep = spd->quantizeStep;
cannam@9 206 if (pd.isQuantized && spd->valueNames) {
cannam@9 207 for (unsigned int j = 0; spd->valueNames[j]; ++j) {
cannam@9 208 pd.valueNames.push_back(spd->valueNames[j]);
cannam@9 209 }
cannam@9 210 }
cannam@1 211 list.push_back(pd);
cannam@1 212 }
cannam@1 213 return list;
cannam@1 214 }
cannam@1 215
cannam@1 216 float
cannam@1 217 PluginHostAdapter::getParameter(std::string param) const
cannam@1 218 {
cannam@1 219 if (!m_handle) return 0.0;
cannam@1 220
cannam@1 221 for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
cannam@49 222 if (param == m_descriptor->parameters[i]->identifier) {
cannam@1 223 return m_descriptor->getParameter(m_handle, i);
cannam@1 224 }
cannam@1 225 }
cannam@1 226
cannam@1 227 return 0.0;
cannam@1 228 }
cannam@1 229
cannam@1 230 void
cannam@1 231 PluginHostAdapter::setParameter(std::string param,
cannam@1 232 float value)
cannam@1 233 {
cannam@1 234 if (!m_handle) return;
cannam@1 235
cannam@1 236 for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
cannam@49 237 if (param == m_descriptor->parameters[i]->identifier) {
cannam@1 238 m_descriptor->setParameter(m_handle, i, value);
cannam@1 239 return;
cannam@1 240 }
cannam@1 241 }
cannam@1 242 }
cannam@1 243
cannam@1 244 PluginHostAdapter::ProgramList
cannam@1 245 PluginHostAdapter::getPrograms() const
cannam@1 246 {
cannam@1 247 ProgramList list;
cannam@1 248
cannam@1 249 for (unsigned int i = 0; i < m_descriptor->programCount; ++i) {
cannam@1 250 list.push_back(m_descriptor->programs[i]);
cannam@1 251 }
cannam@1 252
cannam@1 253 return list;
cannam@1 254 }
cannam@1 255
cannam@1 256 std::string
cannam@1 257 PluginHostAdapter::getCurrentProgram() const
cannam@1 258 {
cannam@1 259 if (!m_handle) return "";
cannam@1 260
cannam@1 261 int pn = m_descriptor->getCurrentProgram(m_handle);
cannam@1 262 return m_descriptor->programs[pn];
cannam@1 263 }
cannam@1 264
cannam@1 265 void
cannam@1 266 PluginHostAdapter::selectProgram(std::string program)
cannam@1 267 {
cannam@1 268 if (!m_handle) return;
cannam@1 269
cannam@1 270 for (unsigned int i = 0; i < m_descriptor->programCount; ++i) {
cannam@1 271 if (program == m_descriptor->programs[i]) {
cannam@1 272 m_descriptor->selectProgram(m_handle, i);
cannam@1 273 return;
cannam@1 274 }
cannam@1 275 }
cannam@1 276 }
cannam@1 277
cannam@1 278 size_t
cannam@1 279 PluginHostAdapter::getPreferredStepSize() const
cannam@1 280 {
cannam@1 281 if (!m_handle) return 0;
cannam@1 282 return m_descriptor->getPreferredStepSize(m_handle);
cannam@1 283 }
cannam@1 284
cannam@1 285 size_t
cannam@1 286 PluginHostAdapter::getPreferredBlockSize() const
cannam@1 287 {
cannam@1 288 if (!m_handle) return 0;
cannam@1 289 return m_descriptor->getPreferredBlockSize(m_handle);
cannam@1 290 }
cannam@1 291
cannam@26 292 size_t
cannam@26 293 PluginHostAdapter::getMinChannelCount() const
cannam@26 294 {
cannam@26 295 if (!m_handle) return 0;
cannam@26 296 return m_descriptor->getMinChannelCount(m_handle);
cannam@26 297 }
cannam@26 298
cannam@26 299 size_t
cannam@26 300 PluginHostAdapter::getMaxChannelCount() const
cannam@26 301 {
cannam@26 302 if (!m_handle) return 0;
cannam@26 303 return m_descriptor->getMaxChannelCount(m_handle);
cannam@26 304 }
cannam@26 305
cannam@1 306 PluginHostAdapter::OutputList
cannam@1 307 PluginHostAdapter::getOutputDescriptors() const
cannam@1 308 {
cannam@1 309 OutputList list;
cannam@15 310 if (!m_handle) {
cannam@15 311 // std::cerr << "PluginHostAdapter::getOutputDescriptors: no handle " << std::endl;
cannam@15 312 return list;
cannam@15 313 }
cannam@1 314
cannam@1 315 unsigned int count = m_descriptor->getOutputCount(m_handle);
cannam@1 316
cannam@1 317 for (unsigned int i = 0; i < count; ++i) {
cannam@1 318 VampOutputDescriptor *sd = m_descriptor->getOutputDescriptor(m_handle, i);
cannam@1 319 OutputDescriptor d;
cannam@49 320 d.identifier = sd->identifier;
cannam@1 321 d.name = sd->name;
cannam@1 322 d.description = sd->description;
cannam@1 323 d.unit = sd->unit;
cannam@9 324 d.hasFixedBinCount = sd->hasFixedBinCount;
cannam@9 325 d.binCount = sd->binCount;
cannam@9 326 if (d.hasFixedBinCount) {
cannam@9 327 for (unsigned int j = 0; j < sd->binCount; ++j) {
cannam@9 328 d.binNames.push_back(sd->binNames[j] ? sd->binNames[j] : "");
cannam@9 329 }
cannam@1 330 }
cannam@1 331 d.hasKnownExtents = sd->hasKnownExtents;
cannam@1 332 d.minValue = sd->minValue;
cannam@1 333 d.maxValue = sd->maxValue;
cannam@1 334 d.isQuantized = sd->isQuantized;
cannam@1 335 d.quantizeStep = sd->quantizeStep;
cannam@1 336
cannam@1 337 switch (sd->sampleType) {
cannam@1 338 case vampOneSamplePerStep:
cannam@1 339 d.sampleType = OutputDescriptor::OneSamplePerStep; break;
cannam@1 340 case vampFixedSampleRate:
cannam@1 341 d.sampleType = OutputDescriptor::FixedSampleRate; break;
cannam@1 342 case vampVariableSampleRate:
cannam@1 343 d.sampleType = OutputDescriptor::VariableSampleRate; break;
cannam@1 344 }
cannam@1 345
cannam@1 346 d.sampleRate = sd->sampleRate;
cannam@1 347
cannam@192 348 if (m_descriptor->vampApiVersion >= 2) {
cannam@192 349 d.hasDuration = sd->hasDuration;
cannam@192 350 } else {
cannam@192 351 d.hasDuration = false;
cannam@192 352 }
cannam@192 353
cannam@1 354 list.push_back(d);
cannam@1 355
cannam@1 356 m_descriptor->releaseOutputDescriptor(sd);
cannam@1 357 }
cannam@1 358
cannam@1 359 return list;
cannam@1 360 }
cannam@1 361
cannam@1 362 PluginHostAdapter::FeatureSet
cannam@47 363 PluginHostAdapter::process(const float *const *inputBuffers,
cannam@47 364 RealTime timestamp)
cannam@1 365 {
cannam@1 366 FeatureSet fs;
cannam@1 367 if (!m_handle) return fs;
cannam@1 368
cannam@1 369 int sec = timestamp.sec;
cannam@1 370 int nsec = timestamp.nsec;
cannam@1 371
cannam@12 372 VampFeatureList *features = m_descriptor->process(m_handle,
cannam@1 373 inputBuffers,
cannam@1 374 sec, nsec);
cannam@1 375
cannam@1 376 convertFeatures(features, fs);
cannam@1 377 m_descriptor->releaseFeatureSet(features);
cannam@1 378 return fs;
cannam@1 379 }
cannam@1 380
cannam@1 381 PluginHostAdapter::FeatureSet
cannam@1 382 PluginHostAdapter::getRemainingFeatures()
cannam@1 383 {
cannam@1 384 FeatureSet fs;
cannam@1 385 if (!m_handle) return fs;
cannam@1 386
cannam@12 387 VampFeatureList *features = m_descriptor->getRemainingFeatures(m_handle);
cannam@1 388
cannam@1 389 convertFeatures(features, fs);
cannam@1 390 m_descriptor->releaseFeatureSet(features);
cannam@1 391 return fs;
cannam@1 392 }
cannam@1 393
cannam@1 394 void
cannam@12 395 PluginHostAdapter::convertFeatures(VampFeatureList *features,
cannam@1 396 FeatureSet &fs)
cannam@1 397 {
cannam@7 398 if (!features) return;
cannam@7 399
cannam@12 400 unsigned int outputs = m_descriptor->getOutputCount(m_handle);
cannam@12 401
cannam@12 402 for (unsigned int i = 0; i < outputs; ++i) {
cannam@1 403
cannam@12 404 VampFeatureList &list = features[i];
cannam@1 405
cannam@1 406 if (list.featureCount > 0) {
cannam@1 407
cannam@108 408 Feature feature;
cannam@168 409 feature.values.reserve(list.features[0].v1.valueCount);
cannam@108 410
cannam@1 411 for (unsigned int j = 0; j < list.featureCount; ++j) {
cannam@108 412
cannam@168 413 feature.hasTimestamp = list.features[j].v1.hasTimestamp;
cannam@168 414 feature.timestamp = RealTime(list.features[j].v1.sec,
cannam@168 415 list.features[j].v1.nsec);
cannam@168 416 feature.hasDuration = false;
cannam@1 417
cannam@167 418 if (m_descriptor->vampApiVersion >= 2) {
cannam@168 419 unsigned int j2 = j + list.featureCount;
cannam@168 420 feature.hasDuration = list.features[j2].v2.hasDuration;
cannam@168 421 feature.duration = RealTime(list.features[j2].v2.durationSec,
cannam@168 422 list.features[j2].v2.durationNsec);
cannam@167 423 }
cannam@167 424
cannam@168 425 for (unsigned int k = 0; k < list.features[j].v1.valueCount; ++k) {
cannam@168 426 feature.values.push_back(list.features[j].v1.values[k]);
cannam@1 427 }
cannam@7 428
cannam@168 429 if (list.features[j].v1.label) {
cannam@168 430 feature.label = list.features[j].v1.label;
cannam@7 431 }
cannam@1 432
cannam@1 433 fs[i].push_back(feature);
cannam@108 434
cannam@168 435 if (list.features[j].v1.valueCount > 0) {
cannam@108 436 feature.values.clear();
cannam@108 437 }
cannam@108 438
cannam@168 439 if (list.features[j].v1.label) {
cannam@108 440 feature.label = "";
cannam@108 441 }
cannam@1 442 }
cannam@1 443 }
cannam@1 444 }
cannam@1 445 }
cannam@1 446
cannam@1 447 }