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