annotate src/vamp-hostsdk/PluginHostAdapter.cpp @ 512:54277cb679ff

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