annotate src/vamp-sdk/PluginAdapter.cpp @ 263:4454843ff384

* OK, we're going to have to place the host stuff in its own namespace too. Otherwise our new SV build on OSX fails to load old plugins because they pull in the host namespace PluginBase and thus report the wrong Vamp version... *sigh*
author cannam
date Thu, 20 Nov 2008 15:01:30 +0000
parents 7b90fe049d04
children 6579e441f2fe
rev   line source
cannam@3 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
cannam@3 2
cannam@3 3 /*
cannam@3 4 Vamp
cannam@3 5
cannam@3 6 An API for audio analysis and feature extraction plugins.
cannam@3 7
cannam@3 8 Centre for Digital Music, Queen Mary, University of London.
cannam@3 9 Copyright 2006 Chris Cannam.
cannam@3 10
cannam@3 11 Permission is hereby granted, free of charge, to any person
cannam@3 12 obtaining a copy of this software and associated documentation
cannam@3 13 files (the "Software"), to deal in the Software without
cannam@3 14 restriction, including without limitation the rights to use, copy,
cannam@3 15 modify, merge, publish, distribute, sublicense, and/or sell copies
cannam@3 16 of the Software, and to permit persons to whom the Software is
cannam@3 17 furnished to do so, subject to the following conditions:
cannam@3 18
cannam@3 19 The above copyright notice and this permission notice shall be
cannam@3 20 included in all copies or substantial portions of the Software.
cannam@3 21
cannam@3 22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
cannam@3 23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
cannam@3 24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
cannam@6 25 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
cannam@3 26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
cannam@3 27 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
cannam@3 28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
cannam@3 29
cannam@3 30 Except as contained in this notice, the names of the Centre for
cannam@3 31 Digital Music; Queen Mary, University of London; and Chris Cannam
cannam@3 32 shall not be used in advertising or otherwise to promote the sale,
cannam@3 33 use or other dealings in this Software without prior written
cannam@3 34 authorization.
cannam@3 35 */
cannam@3 36
cannam@230 37 #include <vamp-sdk/PluginAdapter.h>
cannam@3 38
cannam@130 39 #include <cstring>
cannam@130 40 #include <cstdlib>
cannam@130 41
cannam@234 42 #if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 0 )
cannam@234 43 #error Incorrect Vamp SDK header included (not the expected 2.0 SDK)
cannam@234 44 #endif
cannam@234 45
cannam@234 46
cannam@23 47 //#define DEBUG_PLUGIN_ADAPTER 1
cannam@22 48
cannam@233 49 _VAMP_SDK_PLUGSPACE_BEGIN(PluginAdapter.cpp)
cannam@230 50
cannam@3 51 namespace Vamp {
cannam@3 52
cannam@76 53 class PluginAdapterBase::Impl
cannam@3 54 {
cannam@76 55 public:
cannam@76 56 Impl(PluginAdapterBase *);
cannam@76 57 ~Impl();
cannam@76 58
cannam@76 59 const VampPluginDescriptor *getDescriptor();
cannam@76 60
cannam@76 61 protected:
cannam@76 62 PluginAdapterBase *m_base;
cannam@76 63
cannam@76 64 static VampPluginHandle vampInstantiate(const VampPluginDescriptor *desc,
cannam@167 65 float inputSampleRate);
cannam@76 66
cannam@76 67 static void vampCleanup(VampPluginHandle handle);
cannam@76 68
cannam@76 69 static int vampInitialise(VampPluginHandle handle, unsigned int channels,
cannam@76 70 unsigned int stepSize, unsigned int blockSize);
cannam@76 71
cannam@76 72 static void vampReset(VampPluginHandle handle);
cannam@76 73
cannam@76 74 static float vampGetParameter(VampPluginHandle handle, int param);
cannam@76 75 static void vampSetParameter(VampPluginHandle handle, int param, float value);
cannam@76 76
cannam@76 77 static unsigned int vampGetCurrentProgram(VampPluginHandle handle);
cannam@76 78 static void vampSelectProgram(VampPluginHandle handle, unsigned int program);
cannam@76 79
cannam@76 80 static unsigned int vampGetPreferredStepSize(VampPluginHandle handle);
cannam@76 81 static unsigned int vampGetPreferredBlockSize(VampPluginHandle handle);
cannam@76 82 static unsigned int vampGetMinChannelCount(VampPluginHandle handle);
cannam@76 83 static unsigned int vampGetMaxChannelCount(VampPluginHandle handle);
cannam@76 84
cannam@76 85 static unsigned int vampGetOutputCount(VampPluginHandle handle);
cannam@76 86
cannam@76 87 static VampOutputDescriptor *vampGetOutputDescriptor(VampPluginHandle handle,
cannam@76 88 unsigned int i);
cannam@76 89
cannam@76 90 static void vampReleaseOutputDescriptor(VampOutputDescriptor *desc);
cannam@76 91
cannam@76 92 static VampFeatureList *vampProcess(VampPluginHandle handle,
cannam@76 93 const float *const *inputBuffers,
cannam@76 94 int sec,
cannam@76 95 int nsec);
cannam@76 96
cannam@76 97 static VampFeatureList *vampGetRemainingFeatures(VampPluginHandle handle);
cannam@76 98
cannam@76 99 static void vampReleaseFeatureSet(VampFeatureList *fs);
cannam@76 100
cannam@76 101 void cleanup(Plugin *plugin);
cannam@76 102 void checkOutputMap(Plugin *plugin);
cannam@76 103 unsigned int getOutputCount(Plugin *plugin);
cannam@76 104 VampOutputDescriptor *getOutputDescriptor(Plugin *plugin,
cannam@76 105 unsigned int i);
cannam@76 106 VampFeatureList *process(Plugin *plugin,
cannam@76 107 const float *const *inputBuffers,
cannam@76 108 int sec, int nsec);
cannam@76 109 VampFeatureList *getRemainingFeatures(Plugin *plugin);
cannam@76 110 VampFeatureList *convertFeatures(Plugin *plugin,
cannam@76 111 const Plugin::FeatureSet &features);
cannam@76 112
cannam@76 113 // maps both plugins and descriptors to adapters
cannam@76 114 typedef std::map<const void *, Impl *> AdapterMap;
cannam@76 115 static AdapterMap *m_adapterMap;
cannam@76 116 static Impl *lookupAdapter(VampPluginHandle);
cannam@76 117
cannam@76 118 bool m_populated;
cannam@76 119 VampPluginDescriptor m_descriptor;
cannam@76 120 Plugin::ParameterList m_parameters;
cannam@76 121 Plugin::ProgramList m_programs;
cannam@76 122
cannam@76 123 typedef std::map<Plugin *, Plugin::OutputList *> OutputMap;
cannam@76 124 OutputMap m_pluginOutputs;
cannam@76 125
cannam@76 126 std::map<Plugin *, VampFeatureList *> m_fs;
cannam@76 127 std::map<Plugin *, std::vector<size_t> > m_fsizes;
cannam@76 128 std::map<Plugin *, std::vector<std::vector<size_t> > > m_fvsizes;
cannam@76 129 void resizeFS(Plugin *plugin, int n);
cannam@76 130 void resizeFL(Plugin *plugin, int n, size_t sz);
cannam@76 131 void resizeFV(Plugin *plugin, int n, int j, size_t sz);
cannam@76 132 };
cannam@76 133
cannam@76 134 PluginAdapterBase::PluginAdapterBase()
cannam@76 135 {
cannam@76 136 m_impl = new Impl(this);
cannam@76 137 }
cannam@76 138
cannam@76 139 PluginAdapterBase::~PluginAdapterBase()
cannam@76 140 {
cannam@76 141 delete m_impl;
cannam@3 142 }
cannam@3 143
cannam@3 144 const VampPluginDescriptor *
cannam@3 145 PluginAdapterBase::getDescriptor()
cannam@3 146 {
cannam@76 147 return m_impl->getDescriptor();
cannam@76 148 }
cannam@76 149
cannam@76 150 PluginAdapterBase::Impl::Impl(PluginAdapterBase *base) :
cannam@76 151 m_base(base),
cannam@76 152 m_populated(false)
cannam@76 153 {
cannam@22 154 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 155 std::cerr << "PluginAdapterBase::Impl[" << this << "]::Impl" << std::endl;
cannam@76 156 #endif
cannam@76 157 }
cannam@76 158
cannam@76 159 const VampPluginDescriptor *
cannam@76 160 PluginAdapterBase::Impl::getDescriptor()
cannam@76 161 {
cannam@76 162 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 163 std::cerr << "PluginAdapterBase::Impl[" << this << "]::getDescriptor" << std::endl;
cannam@22 164 #endif
cannam@22 165
cannam@3 166 if (m_populated) return &m_descriptor;
cannam@3 167
cannam@76 168 Plugin *plugin = m_base->createPlugin(48000);
cannam@3 169
cannam@50 170 if (plugin->getVampApiVersion() != VAMP_API_VERSION) {
cannam@76 171 std::cerr << "Vamp::PluginAdapterBase::Impl::getDescriptor: ERROR: "
cannam@194 172 << "API version " << plugin->getVampApiVersion()
cannam@194 173 << " for\nplugin \"" << plugin->getIdentifier() << "\" "
cannam@194 174 << "differs from version "
cannam@194 175 << VAMP_API_VERSION << " for adapter.\n"
cannam@194 176 << "This plugin is probably linked against a different version of the Vamp SDK\n"
cannam@194 177 << "from the version it was compiled with. It will need to be re-linked correctly\n"
cannam@194 178 << "before it can be used." << std::endl;
cannam@50 179 delete plugin;
cannam@50 180 return 0;
cannam@50 181 }
cannam@50 182
cannam@3 183 m_parameters = plugin->getParameterDescriptors();
cannam@3 184 m_programs = plugin->getPrograms();
cannam@50 185
cannam@50 186 m_descriptor.vampApiVersion = plugin->getVampApiVersion();
cannam@49 187 m_descriptor.identifier = strdup(plugin->getIdentifier().c_str());
cannam@3 188 m_descriptor.name = strdup(plugin->getName().c_str());
cannam@3 189 m_descriptor.description = strdup(plugin->getDescription().c_str());
cannam@3 190 m_descriptor.maker = strdup(plugin->getMaker().c_str());
cannam@3 191 m_descriptor.pluginVersion = plugin->getPluginVersion();
cannam@3 192 m_descriptor.copyright = strdup(plugin->getCopyright().c_str());
cannam@3 193
cannam@3 194 m_descriptor.parameterCount = m_parameters.size();
cannam@3 195 m_descriptor.parameters = (const VampParameterDescriptor **)
cannam@3 196 malloc(m_parameters.size() * sizeof(VampParameterDescriptor));
cannam@7 197
cannam@7 198 unsigned int i;
cannam@3 199
cannam@7 200 for (i = 0; i < m_parameters.size(); ++i) {
cannam@3 201 VampParameterDescriptor *desc = (VampParameterDescriptor *)
cannam@3 202 malloc(sizeof(VampParameterDescriptor));
cannam@49 203 desc->identifier = strdup(m_parameters[i].identifier.c_str());
cannam@3 204 desc->name = strdup(m_parameters[i].name.c_str());
cannam@3 205 desc->description = strdup(m_parameters[i].description.c_str());
cannam@3 206 desc->unit = strdup(m_parameters[i].unit.c_str());
cannam@3 207 desc->minValue = m_parameters[i].minValue;
cannam@3 208 desc->maxValue = m_parameters[i].maxValue;
cannam@3 209 desc->defaultValue = m_parameters[i].defaultValue;
cannam@3 210 desc->isQuantized = m_parameters[i].isQuantized;
cannam@3 211 desc->quantizeStep = m_parameters[i].quantizeStep;
cannam@9 212 desc->valueNames = 0;
cannam@9 213 if (desc->isQuantized && !m_parameters[i].valueNames.empty()) {
cannam@9 214 desc->valueNames = (const char **)
cannam@9 215 malloc((m_parameters[i].valueNames.size()+1) * sizeof(char *));
cannam@9 216 for (unsigned int j = 0; j < m_parameters[i].valueNames.size(); ++j) {
cannam@9 217 desc->valueNames[j] = strdup(m_parameters[i].valueNames[j].c_str());
cannam@9 218 }
cannam@9 219 desc->valueNames[m_parameters[i].valueNames.size()] = 0;
cannam@9 220 }
cannam@3 221 m_descriptor.parameters[i] = desc;
cannam@3 222 }
cannam@3 223
cannam@3 224 m_descriptor.programCount = m_programs.size();
cannam@3 225 m_descriptor.programs = (const char **)
cannam@3 226 malloc(m_programs.size() * sizeof(const char *));
cannam@3 227
cannam@7 228 for (i = 0; i < m_programs.size(); ++i) {
cannam@3 229 m_descriptor.programs[i] = strdup(m_programs[i].c_str());
cannam@3 230 }
cannam@3 231
cannam@3 232 if (plugin->getInputDomain() == Plugin::FrequencyDomain) {
cannam@3 233 m_descriptor.inputDomain = vampFrequencyDomain;
cannam@3 234 } else {
cannam@3 235 m_descriptor.inputDomain = vampTimeDomain;
cannam@3 236 }
cannam@3 237
cannam@3 238 m_descriptor.instantiate = vampInstantiate;
cannam@3 239 m_descriptor.cleanup = vampCleanup;
cannam@3 240 m_descriptor.initialise = vampInitialise;
cannam@3 241 m_descriptor.reset = vampReset;
cannam@3 242 m_descriptor.getParameter = vampGetParameter;
cannam@3 243 m_descriptor.setParameter = vampSetParameter;
cannam@3 244 m_descriptor.getCurrentProgram = vampGetCurrentProgram;
cannam@3 245 m_descriptor.selectProgram = vampSelectProgram;
cannam@3 246 m_descriptor.getPreferredStepSize = vampGetPreferredStepSize;
cannam@3 247 m_descriptor.getPreferredBlockSize = vampGetPreferredBlockSize;
cannam@3 248 m_descriptor.getMinChannelCount = vampGetMinChannelCount;
cannam@3 249 m_descriptor.getMaxChannelCount = vampGetMaxChannelCount;
cannam@3 250 m_descriptor.getOutputCount = vampGetOutputCount;
cannam@3 251 m_descriptor.getOutputDescriptor = vampGetOutputDescriptor;
cannam@3 252 m_descriptor.releaseOutputDescriptor = vampReleaseOutputDescriptor;
cannam@3 253 m_descriptor.process = vampProcess;
cannam@3 254 m_descriptor.getRemainingFeatures = vampGetRemainingFeatures;
cannam@3 255 m_descriptor.releaseFeatureSet = vampReleaseFeatureSet;
cannam@3 256
cannam@13 257 if (!m_adapterMap) {
cannam@13 258 m_adapterMap = new AdapterMap;
cannam@13 259 }
cannam@15 260 (*m_adapterMap)[&m_descriptor] = this;
cannam@3 261
cannam@3 262 delete plugin;
cannam@3 263
cannam@3 264 m_populated = true;
cannam@3 265 return &m_descriptor;
cannam@3 266 }
cannam@3 267
cannam@76 268 PluginAdapterBase::Impl::~Impl()
cannam@3 269 {
cannam@22 270 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 271 std::cerr << "PluginAdapterBase::Impl[" << this << "]::~Impl" << std::endl;
cannam@22 272 #endif
cannam@22 273
cannam@3 274 if (!m_populated) return;
cannam@3 275
cannam@49 276 free((void *)m_descriptor.identifier);
cannam@3 277 free((void *)m_descriptor.name);
cannam@3 278 free((void *)m_descriptor.description);
cannam@3 279 free((void *)m_descriptor.maker);
cannam@3 280 free((void *)m_descriptor.copyright);
cannam@3 281
cannam@3 282 for (unsigned int i = 0; i < m_descriptor.parameterCount; ++i) {
cannam@3 283 const VampParameterDescriptor *desc = m_descriptor.parameters[i];
cannam@49 284 free((void *)desc->identifier);
cannam@3 285 free((void *)desc->name);
cannam@3 286 free((void *)desc->description);
cannam@3 287 free((void *)desc->unit);
cannam@9 288 if (desc->valueNames) {
cannam@9 289 for (unsigned int j = 0; desc->valueNames[j]; ++j) {
cannam@9 290 free((void *)desc->valueNames[j]);
cannam@9 291 }
cannam@9 292 free((void *)desc->valueNames);
cannam@9 293 }
cannam@3 294 }
cannam@3 295 free((void *)m_descriptor.parameters);
cannam@3 296
cannam@3 297 for (unsigned int i = 0; i < m_descriptor.programCount; ++i) {
cannam@3 298 free((void *)m_descriptor.programs[i]);
cannam@3 299 }
cannam@3 300 free((void *)m_descriptor.programs);
cannam@3 301
cannam@13 302 if (m_adapterMap) {
cannam@13 303
cannam@13 304 m_adapterMap->erase(&m_descriptor);
cannam@13 305
cannam@13 306 if (m_adapterMap->empty()) {
cannam@13 307 delete m_adapterMap;
cannam@13 308 m_adapterMap = 0;
cannam@13 309 }
cannam@13 310 }
cannam@3 311 }
cannam@3 312
cannam@76 313 PluginAdapterBase::Impl *
cannam@76 314 PluginAdapterBase::Impl::lookupAdapter(VampPluginHandle handle)
cannam@3 315 {
cannam@22 316 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 317 std::cerr << "PluginAdapterBase::Impl::lookupAdapter(" << handle << ")" << std::endl;
cannam@22 318 #endif
cannam@22 319
cannam@13 320 if (!m_adapterMap) return 0;
cannam@13 321 AdapterMap::const_iterator i = m_adapterMap->find(handle);
cannam@13 322 if (i == m_adapterMap->end()) return 0;
cannam@3 323 return i->second;
cannam@3 324 }
cannam@3 325
cannam@3 326 VampPluginHandle
cannam@76 327 PluginAdapterBase::Impl::vampInstantiate(const VampPluginDescriptor *desc,
cannam@3 328 float inputSampleRate)
cannam@3 329 {
cannam@22 330 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 331 std::cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << ")" << std::endl;
cannam@22 332 #endif
cannam@22 333
cannam@15 334 if (!m_adapterMap) {
cannam@15 335 m_adapterMap = new AdapterMap();
cannam@15 336 }
cannam@15 337
cannam@15 338 if (m_adapterMap->find(desc) == m_adapterMap->end()) {
cannam@76 339 std::cerr << "WARNING: PluginAdapterBase::Impl::vampInstantiate: Descriptor " << desc << " not in adapter map" << std::endl;
cannam@15 340 return 0;
cannam@15 341 }
cannam@15 342
cannam@76 343 Impl *adapter = (*m_adapterMap)[desc];
cannam@3 344 if (desc != &adapter->m_descriptor) return 0;
cannam@3 345
cannam@76 346 Plugin *plugin = adapter->m_base->createPlugin(inputSampleRate);
cannam@3 347 if (plugin) {
cannam@13 348 (*m_adapterMap)[plugin] = adapter;
cannam@3 349 }
cannam@3 350
cannam@22 351 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 352 std::cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << "): returning handle " << plugin << std::endl;
cannam@22 353 #endif
cannam@22 354
cannam@3 355 return plugin;
cannam@3 356 }
cannam@3 357
cannam@3 358 void
cannam@76 359 PluginAdapterBase::Impl::vampCleanup(VampPluginHandle handle)
cannam@3 360 {
cannam@22 361 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 362 std::cerr << "PluginAdapterBase::Impl::vampCleanup(" << handle << ")" << std::endl;
cannam@22 363 #endif
cannam@22 364
cannam@76 365 Impl *adapter = lookupAdapter(handle);
cannam@3 366 if (!adapter) {
cannam@3 367 delete ((Plugin *)handle);
cannam@3 368 return;
cannam@3 369 }
cannam@3 370 adapter->cleanup(((Plugin *)handle));
cannam@3 371 }
cannam@3 372
cannam@3 373 int
cannam@76 374 PluginAdapterBase::Impl::vampInitialise(VampPluginHandle handle,
cannam@3 375 unsigned int channels,
cannam@3 376 unsigned int stepSize,
cannam@3 377 unsigned int blockSize)
cannam@3 378 {
cannam@22 379 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 380 std::cerr << "PluginAdapterBase::Impl::vampInitialise(" << handle << ", " << channels << ", " << stepSize << ", " << blockSize << ")" << std::endl;
cannam@22 381 #endif
cannam@22 382
cannam@3 383 bool result = ((Plugin *)handle)->initialise
cannam@3 384 (channels, stepSize, blockSize);
cannam@3 385 return result ? 1 : 0;
cannam@3 386 }
cannam@3 387
cannam@3 388 void
cannam@76 389 PluginAdapterBase::Impl::vampReset(VampPluginHandle handle)
cannam@3 390 {
cannam@22 391 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 392 std::cerr << "PluginAdapterBase::Impl::vampReset(" << handle << ")" << std::endl;
cannam@22 393 #endif
cannam@22 394
cannam@3 395 ((Plugin *)handle)->reset();
cannam@3 396 }
cannam@3 397
cannam@3 398 float
cannam@76 399 PluginAdapterBase::Impl::vampGetParameter(VampPluginHandle handle,
cannam@3 400 int param)
cannam@3 401 {
cannam@22 402 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 403 std::cerr << "PluginAdapterBase::Impl::vampGetParameter(" << handle << ", " << param << ")" << std::endl;
cannam@22 404 #endif
cannam@22 405
cannam@76 406 Impl *adapter = lookupAdapter(handle);
cannam@3 407 if (!adapter) return 0.0;
cannam@3 408 Plugin::ParameterList &list = adapter->m_parameters;
cannam@49 409 return ((Plugin *)handle)->getParameter(list[param].identifier);
cannam@3 410 }
cannam@3 411
cannam@3 412 void
cannam@76 413 PluginAdapterBase::Impl::vampSetParameter(VampPluginHandle handle,
cannam@3 414 int param, float value)
cannam@3 415 {
cannam@22 416 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 417 std::cerr << "PluginAdapterBase::Impl::vampSetParameter(" << handle << ", " << param << ", " << value << ")" << std::endl;
cannam@22 418 #endif
cannam@22 419
cannam@76 420 Impl *adapter = lookupAdapter(handle);
cannam@3 421 if (!adapter) return;
cannam@3 422 Plugin::ParameterList &list = adapter->m_parameters;
cannam@49 423 ((Plugin *)handle)->setParameter(list[param].identifier, value);
cannam@3 424 }
cannam@3 425
cannam@3 426 unsigned int
cannam@76 427 PluginAdapterBase::Impl::vampGetCurrentProgram(VampPluginHandle handle)
cannam@3 428 {
cannam@22 429 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 430 std::cerr << "PluginAdapterBase::Impl::vampGetCurrentProgram(" << handle << ")" << std::endl;
cannam@22 431 #endif
cannam@22 432
cannam@76 433 Impl *adapter = lookupAdapter(handle);
cannam@3 434 if (!adapter) return 0;
cannam@3 435 Plugin::ProgramList &list = adapter->m_programs;
cannam@3 436 std::string program = ((Plugin *)handle)->getCurrentProgram();
cannam@3 437 for (unsigned int i = 0; i < list.size(); ++i) {
cannam@3 438 if (list[i] == program) return i;
cannam@3 439 }
cannam@3 440 return 0;
cannam@3 441 }
cannam@3 442
cannam@3 443 void
cannam@76 444 PluginAdapterBase::Impl::vampSelectProgram(VampPluginHandle handle,
cannam@3 445 unsigned int program)
cannam@3 446 {
cannam@22 447 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 448 std::cerr << "PluginAdapterBase::Impl::vampSelectProgram(" << handle << ", " << program << ")" << std::endl;
cannam@22 449 #endif
cannam@22 450
cannam@76 451 Impl *adapter = lookupAdapter(handle);
cannam@3 452 if (!adapter) return;
cannam@3 453 Plugin::ProgramList &list = adapter->m_programs;
cannam@3 454 ((Plugin *)handle)->selectProgram(list[program]);
cannam@3 455 }
cannam@3 456
cannam@3 457 unsigned int
cannam@76 458 PluginAdapterBase::Impl::vampGetPreferredStepSize(VampPluginHandle handle)
cannam@3 459 {
cannam@22 460 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 461 std::cerr << "PluginAdapterBase::Impl::vampGetPreferredStepSize(" << handle << ")" << std::endl;
cannam@22 462 #endif
cannam@22 463
cannam@3 464 return ((Plugin *)handle)->getPreferredStepSize();
cannam@3 465 }
cannam@3 466
cannam@3 467 unsigned int
cannam@76 468 PluginAdapterBase::Impl::vampGetPreferredBlockSize(VampPluginHandle handle)
cannam@3 469 {
cannam@22 470 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 471 std::cerr << "PluginAdapterBase::Impl::vampGetPreferredBlockSize(" << handle << ")" << std::endl;
cannam@22 472 #endif
cannam@22 473
cannam@3 474 return ((Plugin *)handle)->getPreferredBlockSize();
cannam@3 475 }
cannam@3 476
cannam@3 477 unsigned int
cannam@76 478 PluginAdapterBase::Impl::vampGetMinChannelCount(VampPluginHandle handle)
cannam@3 479 {
cannam@22 480 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 481 std::cerr << "PluginAdapterBase::Impl::vampGetMinChannelCount(" << handle << ")" << std::endl;
cannam@22 482 #endif
cannam@22 483
cannam@3 484 return ((Plugin *)handle)->getMinChannelCount();
cannam@3 485 }
cannam@3 486
cannam@3 487 unsigned int
cannam@76 488 PluginAdapterBase::Impl::vampGetMaxChannelCount(VampPluginHandle handle)
cannam@3 489 {
cannam@22 490 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 491 std::cerr << "PluginAdapterBase::Impl::vampGetMaxChannelCount(" << handle << ")" << std::endl;
cannam@22 492 #endif
cannam@22 493
cannam@3 494 return ((Plugin *)handle)->getMaxChannelCount();
cannam@3 495 }
cannam@3 496
cannam@3 497 unsigned int
cannam@76 498 PluginAdapterBase::Impl::vampGetOutputCount(VampPluginHandle handle)
cannam@3 499 {
cannam@22 500 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 501 std::cerr << "PluginAdapterBase::Impl::vampGetOutputCount(" << handle << ")" << std::endl;
cannam@22 502 #endif
cannam@22 503
cannam@76 504 Impl *adapter = lookupAdapter(handle);
cannam@15 505
cannam@15 506 // std::cerr << "vampGetOutputCount: handle " << handle << " -> adapter "<< adapter << std::endl;
cannam@15 507
cannam@3 508 if (!adapter) return 0;
cannam@3 509 return adapter->getOutputCount((Plugin *)handle);
cannam@3 510 }
cannam@3 511
cannam@3 512 VampOutputDescriptor *
cannam@76 513 PluginAdapterBase::Impl::vampGetOutputDescriptor(VampPluginHandle handle,
cannam@3 514 unsigned int i)
cannam@3 515 {
cannam@22 516 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 517 std::cerr << "PluginAdapterBase::Impl::vampGetOutputDescriptor(" << handle << ", " << i << ")" << std::endl;
cannam@22 518 #endif
cannam@22 519
cannam@76 520 Impl *adapter = lookupAdapter(handle);
cannam@15 521
cannam@15 522 // std::cerr << "vampGetOutputDescriptor: handle " << handle << " -> adapter "<< adapter << std::endl;
cannam@15 523
cannam@3 524 if (!adapter) return 0;
cannam@3 525 return adapter->getOutputDescriptor((Plugin *)handle, i);
cannam@3 526 }
cannam@3 527
cannam@3 528 void
cannam@76 529 PluginAdapterBase::Impl::vampReleaseOutputDescriptor(VampOutputDescriptor *desc)
cannam@3 530 {
cannam@22 531 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 532 std::cerr << "PluginAdapterBase::Impl::vampReleaseOutputDescriptor(" << desc << ")" << std::endl;
cannam@22 533 #endif
cannam@22 534
cannam@49 535 if (desc->identifier) free((void *)desc->identifier);
cannam@3 536 if (desc->name) free((void *)desc->name);
cannam@3 537 if (desc->description) free((void *)desc->description);
cannam@3 538 if (desc->unit) free((void *)desc->unit);
cannam@40 539 if (desc->hasFixedBinCount && desc->binNames) {
cannam@40 540 for (unsigned int i = 0; i < desc->binCount; ++i) {
cannam@40 541 if (desc->binNames[i]) {
cannam@40 542 free((void *)desc->binNames[i]);
cannam@40 543 }
cannam@40 544 }
cannam@3 545 }
cannam@9 546 if (desc->binNames) free((void *)desc->binNames);
cannam@3 547 free((void *)desc);
cannam@3 548 }
cannam@3 549
cannam@12 550 VampFeatureList *
cannam@76 551 PluginAdapterBase::Impl::vampProcess(VampPluginHandle handle,
cannam@108 552 const float *const *inputBuffers,
cannam@108 553 int sec,
cannam@108 554 int nsec)
cannam@3 555 {
cannam@22 556 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 557 std::cerr << "PluginAdapterBase::Impl::vampProcess(" << handle << ", " << sec << ", " << nsec << ")" << std::endl;
cannam@22 558 #endif
cannam@22 559
cannam@76 560 Impl *adapter = lookupAdapter(handle);
cannam@3 561 if (!adapter) return 0;
cannam@3 562 return adapter->process((Plugin *)handle,
cannam@3 563 inputBuffers, sec, nsec);
cannam@3 564 }
cannam@3 565
cannam@12 566 VampFeatureList *
cannam@76 567 PluginAdapterBase::Impl::vampGetRemainingFeatures(VampPluginHandle handle)
cannam@3 568 {
cannam@22 569 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 570 std::cerr << "PluginAdapterBase::Impl::vampGetRemainingFeatures(" << handle << ")" << std::endl;
cannam@22 571 #endif
cannam@22 572
cannam@76 573 Impl *adapter = lookupAdapter(handle);
cannam@3 574 if (!adapter) return 0;
cannam@3 575 return adapter->getRemainingFeatures((Plugin *)handle);
cannam@3 576 }
cannam@3 577
cannam@3 578 void
cannam@76 579 PluginAdapterBase::Impl::vampReleaseFeatureSet(VampFeatureList *fs)
cannam@3 580 {
cannam@22 581 #ifdef DEBUG_PLUGIN_ADAPTER
cannam@76 582 std::cerr << "PluginAdapterBase::Impl::vampReleaseFeatureSet" << std::endl;
cannam@22 583 #endif
cannam@3 584 }
cannam@3 585
cannam@3 586 void
cannam@76 587 PluginAdapterBase::Impl::cleanup(Plugin *plugin)
cannam@3 588 {
cannam@12 589 if (m_fs.find(plugin) != m_fs.end()) {
cannam@12 590 size_t outputCount = 0;
cannam@12 591 if (m_pluginOutputs[plugin]) {
cannam@12 592 outputCount = m_pluginOutputs[plugin]->size();
cannam@12 593 }
cannam@12 594 VampFeatureList *list = m_fs[plugin];
cannam@12 595 for (unsigned int i = 0; i < outputCount; ++i) {
cannam@12 596 for (unsigned int j = 0; j < m_fsizes[plugin][i]; ++j) {
cannam@168 597 if (list[i].features[j].v1.label) {
cannam@168 598 free(list[i].features[j].v1.label);
cannam@12 599 }
cannam@168 600 if (list[i].features[j].v1.values) {
cannam@168 601 free(list[i].features[j].v1.values);
cannam@12 602 }
cannam@12 603 }
cannam@12 604 if (list[i].features) free(list[i].features);
cannam@12 605 }
cannam@12 606 m_fs.erase(plugin);
cannam@12 607 m_fsizes.erase(plugin);
cannam@12 608 m_fvsizes.erase(plugin);
cannam@12 609 }
cannam@12 610
cannam@3 611 if (m_pluginOutputs.find(plugin) != m_pluginOutputs.end()) {
cannam@3 612 delete m_pluginOutputs[plugin];
cannam@3 613 m_pluginOutputs.erase(plugin);
cannam@3 614 }
cannam@13 615
cannam@13 616 if (m_adapterMap) {
cannam@13 617 m_adapterMap->erase(plugin);
cannam@13 618
cannam@13 619 if (m_adapterMap->empty()) {
cannam@13 620 delete m_adapterMap;
cannam@13 621 m_adapterMap = 0;
cannam@13 622 }
cannam@13 623 }
cannam@13 624
cannam@3 625 delete ((Plugin *)plugin);
cannam@3 626 }
cannam@3 627
cannam@3 628 void
cannam@76 629 PluginAdapterBase::Impl::checkOutputMap(Plugin *plugin)
cannam@3 630 {
cannam@15 631 if (m_pluginOutputs.find(plugin) == m_pluginOutputs.end() ||
cannam@15 632 !m_pluginOutputs[plugin]) {
cannam@3 633 m_pluginOutputs[plugin] = new Plugin::OutputList
cannam@3 634 (plugin->getOutputDescriptors());
cannam@76 635 // std::cerr << "PluginAdapterBase::Impl::checkOutputMap: Have " << m_pluginOutputs[plugin]->size() << " outputs for plugin " << plugin->getIdentifier() << std::endl;
cannam@3 636 }
cannam@3 637 }
cannam@3 638
cannam@3 639 unsigned int
cannam@76 640 PluginAdapterBase::Impl::getOutputCount(Plugin *plugin)
cannam@3 641 {
cannam@3 642 checkOutputMap(plugin);
cannam@3 643 return m_pluginOutputs[plugin]->size();
cannam@3 644 }
cannam@3 645
cannam@3 646 VampOutputDescriptor *
cannam@76 647 PluginAdapterBase::Impl::getOutputDescriptor(Plugin *plugin,
cannam@3 648 unsigned int i)
cannam@3 649 {
cannam@3 650 checkOutputMap(plugin);
cannam@3 651 Plugin::OutputDescriptor &od =
cannam@3 652 (*m_pluginOutputs[plugin])[i];
cannam@3 653
cannam@3 654 VampOutputDescriptor *desc = (VampOutputDescriptor *)
cannam@3 655 malloc(sizeof(VampOutputDescriptor));
cannam@3 656
cannam@49 657 desc->identifier = strdup(od.identifier.c_str());
cannam@3 658 desc->name = strdup(od.name.c_str());
cannam@3 659 desc->description = strdup(od.description.c_str());
cannam@3 660 desc->unit = strdup(od.unit.c_str());
cannam@9 661 desc->hasFixedBinCount = od.hasFixedBinCount;
cannam@9 662 desc->binCount = od.binCount;
cannam@3 663
cannam@240 664 if (od.hasFixedBinCount && od.binCount > 0
cannam@240 665 // We would like to do "&& !od.binNames.empty()" here -- but we
cannam@240 666 // can't, because it will crash older versions of the host adapter
cannam@240 667 // which try to copy the names across whenever the bin count is
cannam@240 668 // non-zero, regardless of whether they exist or not
cannam@240 669 ) {
cannam@9 670 desc->binNames = (const char **)
cannam@9 671 malloc(od.binCount * sizeof(const char *));
cannam@3 672
cannam@9 673 for (unsigned int i = 0; i < od.binCount; ++i) {
cannam@9 674 if (i < od.binNames.size()) {
cannam@9 675 desc->binNames[i] = strdup(od.binNames[i].c_str());
cannam@7 676 } else {
cannam@9 677 desc->binNames[i] = 0;
cannam@7 678 }
cannam@3 679 }
cannam@7 680 } else {
cannam@9 681 desc->binNames = 0;
cannam@3 682 }
cannam@3 683
cannam@3 684 desc->hasKnownExtents = od.hasKnownExtents;
cannam@3 685 desc->minValue = od.minValue;
cannam@3 686 desc->maxValue = od.maxValue;
cannam@3 687 desc->isQuantized = od.isQuantized;
cannam@3 688 desc->quantizeStep = od.quantizeStep;
cannam@3 689
cannam@3 690 switch (od.sampleType) {
cannam@3 691 case Plugin::OutputDescriptor::OneSamplePerStep:
cannam@3 692 desc->sampleType = vampOneSamplePerStep; break;
cannam@3 693 case Plugin::OutputDescriptor::FixedSampleRate:
cannam@3 694 desc->sampleType = vampFixedSampleRate; break;
cannam@3 695 case Plugin::OutputDescriptor::VariableSampleRate:
cannam@3 696 desc->sampleType = vampVariableSampleRate; break;
cannam@3 697 }
cannam@3 698
cannam@3 699 desc->sampleRate = od.sampleRate;
cannam@192 700 desc->hasDuration = od.hasDuration;
cannam@3 701
cannam@3 702 return desc;
cannam@3 703 }
cannam@3 704
cannam@12 705 VampFeatureList *
cannam@76 706 PluginAdapterBase::Impl::process(Plugin *plugin,
cannam@108 707 const float *const *inputBuffers,
cannam@108 708 int sec, int nsec)
cannam@3 709 {
cannam@76 710 // std::cerr << "PluginAdapterBase::Impl::process" << std::endl;
cannam@3 711 RealTime rt(sec, nsec);
cannam@12 712 checkOutputMap(plugin);
cannam@12 713 return convertFeatures(plugin, plugin->process(inputBuffers, rt));
cannam@3 714 }
cannam@3 715
cannam@12 716 VampFeatureList *
cannam@76 717 PluginAdapterBase::Impl::getRemainingFeatures(Plugin *plugin)
cannam@3 718 {
cannam@76 719 // std::cerr << "PluginAdapterBase::Impl::getRemainingFeatures" << std::endl;
cannam@12 720 checkOutputMap(plugin);
cannam@12 721 return convertFeatures(plugin, plugin->getRemainingFeatures());
cannam@3 722 }
cannam@3 723
cannam@12 724 VampFeatureList *
cannam@76 725 PluginAdapterBase::Impl::convertFeatures(Plugin *plugin,
cannam@167 726 const Plugin::FeatureSet &features)
cannam@3 727 {
cannam@12 728 int lastN = -1;
cannam@3 729
cannam@12 730 int outputCount = 0;
cannam@12 731 if (m_pluginOutputs[plugin]) outputCount = m_pluginOutputs[plugin]->size();
cannam@12 732
cannam@12 733 resizeFS(plugin, outputCount);
cannam@12 734 VampFeatureList *fs = m_fs[plugin];
cannam@3 735
cannam@168 736 // std::cerr << "PluginAdapter(v2)::convertFeatures: NOTE: sizeof(Feature) == " << sizeof(Plugin::Feature) << ", sizeof(VampFeature) == " << sizeof(VampFeature) << ", sizeof(VampFeatureList) == " << sizeof(VampFeatureList) << std::endl;
cannam@168 737
cannam@12 738 for (Plugin::FeatureSet::const_iterator fi = features.begin();
cannam@12 739 fi != features.end(); ++fi) {
cannam@3 740
cannam@12 741 int n = fi->first;
cannam@12 742
cannam@76 743 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: n = " << n << std::endl;
cannam@7 744
cannam@12 745 if (n >= int(outputCount)) {
cannam@76 746 std::cerr << "WARNING: PluginAdapterBase::Impl::convertFeatures: Too many outputs from plugin (" << n+1 << ", only should be " << outputCount << ")" << std::endl;
cannam@7 747 continue;
cannam@7 748 }
cannam@7 749
cannam@12 750 if (n > lastN + 1) {
cannam@12 751 for (int i = lastN + 1; i < n; ++i) {
cannam@12 752 fs[i].featureCount = 0;
cannam@12 753 }
cannam@12 754 }
cannam@7 755
cannam@7 756 const Plugin::FeatureList &fl = fi->second;
cannam@7 757
cannam@12 758 size_t sz = fl.size();
cannam@12 759 if (sz > m_fsizes[plugin][n]) resizeFL(plugin, n, sz);
cannam@12 760 fs[n].featureCount = sz;
cannam@12 761
cannam@12 762 for (size_t j = 0; j < sz; ++j) {
cannam@7 763
cannam@76 764 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: j = " << j << std::endl;
cannam@7 765
cannam@168 766 VampFeature *feature = &fs[n].features[j].v1;
cannam@7 767
cannam@7 768 feature->hasTimestamp = fl[j].hasTimestamp;
cannam@7 769 feature->sec = fl[j].timestamp.sec;
cannam@7 770 feature->nsec = fl[j].timestamp.nsec;
cannam@7 771 feature->valueCount = fl[j].values.size();
cannam@7 772
cannam@168 773 VampFeatureV2 *v2 = &fs[n].features[j + sz].v2;
cannam@167 774
cannam@167 775 v2->hasDuration = fl[j].hasDuration;
cannam@167 776 v2->durationSec = fl[j].duration.sec;
cannam@167 777 v2->durationNsec = fl[j].duration.nsec;
cannam@167 778
cannam@12 779 if (feature->label) free(feature->label);
cannam@12 780
cannam@12 781 if (fl[j].label.empty()) {
cannam@12 782 feature->label = 0;
cannam@12 783 } else {
cannam@12 784 feature->label = strdup(fl[j].label.c_str());
cannam@7 785 }
cannam@7 786
cannam@12 787 if (feature->valueCount > m_fvsizes[plugin][n][j]) {
cannam@12 788 resizeFV(plugin, n, j, feature->valueCount);
cannam@12 789 }
cannam@7 790
cannam@7 791 for (unsigned int k = 0; k < feature->valueCount; ++k) {
cannam@76 792 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: k = " << k << std::endl;
cannam@7 793 feature->values[k] = fl[j].values[k];
cannam@3 794 }
cannam@3 795 }
cannam@12 796
cannam@12 797 lastN = n;
cannam@3 798 }
cannam@3 799
cannam@12 800 if (lastN == -1) return 0;
cannam@12 801
cannam@12 802 if (int(outputCount) > lastN + 1) {
cannam@12 803 for (int i = lastN + 1; i < int(outputCount); ++i) {
cannam@12 804 fs[i].featureCount = 0;
cannam@12 805 }
cannam@12 806 }
cannam@3 807
cannam@168 808 // std::cerr << "PluginAdapter(v2)::convertFeatures: NOTE: have " << outputCount << " outputs" << std::endl;
cannam@168 809 // for (int i = 0; i < outputCount; ++i) {
cannam@168 810 // std::cerr << "PluginAdapter(v2)::convertFeatures: NOTE: output " << i << " has " << fs[i].featureCount << " features" << std::endl;
cannam@168 811 // }
cannam@168 812
cannam@168 813
cannam@3 814 return fs;
cannam@3 815 }
cannam@3 816
cannam@12 817 void
cannam@76 818 PluginAdapterBase::Impl::resizeFS(Plugin *plugin, int n)
cannam@12 819 {
cannam@76 820 // std::cerr << "PluginAdapterBase::Impl::resizeFS(" << plugin << ", " << n << ")" << std::endl;
cannam@12 821
cannam@12 822 int i = m_fsizes[plugin].size();
cannam@12 823 if (i >= n) return;
cannam@12 824
cannam@16 825 // std::cerr << "resizing from " << i << std::endl;
cannam@12 826
cannam@12 827 m_fs[plugin] = (VampFeatureList *)realloc
cannam@12 828 (m_fs[plugin], n * sizeof(VampFeatureList));
cannam@12 829
cannam@12 830 while (i < n) {
cannam@12 831 m_fs[plugin][i].featureCount = 0;
cannam@12 832 m_fs[plugin][i].features = 0;
cannam@12 833 m_fsizes[plugin].push_back(0);
cannam@12 834 m_fvsizes[plugin].push_back(std::vector<size_t>());
cannam@12 835 i++;
cannam@12 836 }
cannam@12 837 }
cannam@12 838
cannam@12 839 void
cannam@76 840 PluginAdapterBase::Impl::resizeFL(Plugin *plugin, int n, size_t sz)
cannam@12 841 {
cannam@76 842 // std::cerr << "PluginAdapterBase::Impl::resizeFL(" << plugin << ", " << n << ", "
cannam@16 843 // << sz << ")" << std::endl;
cannam@12 844
cannam@12 845 size_t i = m_fsizes[plugin][n];
cannam@12 846 if (i >= sz) return;
cannam@12 847
cannam@16 848 // std::cerr << "resizing from " << i << std::endl;
cannam@12 849
cannam@168 850 m_fs[plugin][n].features = (VampFeatureUnion *)realloc
cannam@168 851 (m_fs[plugin][n].features, 2 * sz * sizeof(VampFeatureUnion));
cannam@167 852
cannam@12 853 while (m_fsizes[plugin][n] < sz) {
cannam@168 854 m_fs[plugin][n].features[m_fsizes[plugin][n]].v1.hasTimestamp = 0;
cannam@168 855 m_fs[plugin][n].features[m_fsizes[plugin][n]].v1.valueCount = 0;
cannam@168 856 m_fs[plugin][n].features[m_fsizes[plugin][n]].v1.values = 0;
cannam@168 857 m_fs[plugin][n].features[m_fsizes[plugin][n]].v1.label = 0;
cannam@189 858 m_fs[plugin][n].features[m_fsizes[plugin][n] + sz].v2.hasDuration = 0;
cannam@12 859 m_fvsizes[plugin][n].push_back(0);
cannam@12 860 m_fsizes[plugin][n]++;
cannam@12 861 }
cannam@12 862 }
cannam@12 863
cannam@12 864 void
cannam@76 865 PluginAdapterBase::Impl::resizeFV(Plugin *plugin, int n, int j, size_t sz)
cannam@12 866 {
cannam@76 867 // std::cerr << "PluginAdapterBase::Impl::resizeFV(" << plugin << ", " << n << ", "
cannam@16 868 // << j << ", " << sz << ")" << std::endl;
cannam@12 869
cannam@12 870 size_t i = m_fvsizes[plugin][n][j];
cannam@12 871 if (i >= sz) return;
cannam@12 872
cannam@16 873 // std::cerr << "resizing from " << i << std::endl;
cannam@12 874
cannam@168 875 m_fs[plugin][n].features[j].v1.values = (float *)realloc
cannam@168 876 (m_fs[plugin][n].features[j].v1.values, sz * sizeof(float));
cannam@12 877
cannam@12 878 m_fvsizes[plugin][n][j] = sz;
cannam@12 879 }
cannam@12 880
cannam@76 881 PluginAdapterBase::Impl::AdapterMap *
cannam@76 882 PluginAdapterBase::Impl::m_adapterMap = 0;
cannam@3 883
cannam@3 884 }
cannam@3 885
cannam@233 886 _VAMP_SDK_PLUGSPACE_END(PluginAdapter.cpp)
cannam@230 887