annotate plugin/transform/TransformFactory.cpp @ 341:db8fcd280234

* Fix log range mapper bug
author Chris Cannam
date Mon, 26 Nov 2007 13:33:14 +0000
parents 1afaf98dbf11
children d7c41483af8f 94fc0591ea43
rev   line source
Chris@330 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@330 2
Chris@330 3 /*
Chris@330 4 Sonic Visualiser
Chris@330 5 An audio file viewer and annotation editor.
Chris@330 6 Centre for Digital Music, Queen Mary, University of London.
Chris@330 7 This file copyright 2006 Chris Cannam and QMUL.
Chris@330 8
Chris@330 9 This program is free software; you can redistribute it and/or
Chris@330 10 modify it under the terms of the GNU General Public License as
Chris@330 11 published by the Free Software Foundation; either version 2 of the
Chris@330 12 License, or (at your option) any later version. See the file
Chris@330 13 COPYING included with this distribution for more information.
Chris@330 14 */
Chris@330 15
Chris@330 16 #include "TransformFactory.h"
Chris@330 17
Chris@330 18 #include "plugin/FeatureExtractionPluginFactory.h"
Chris@330 19 #include "plugin/RealTimePluginFactory.h"
Chris@332 20 #include "plugin/RealTimePluginInstance.h"
Chris@330 21 #include "plugin/PluginXml.h"
Chris@330 22
Chris@332 23 #include "vamp-sdk/Plugin.h"
Chris@330 24 #include "vamp-sdk/PluginHostAdapter.h"
Chris@332 25 #include "vamp-sdk/hostext/PluginWrapper.h"
Chris@330 26
Chris@330 27 #include <iostream>
Chris@330 28 #include <set>
Chris@330 29
Chris@330 30 #include <QRegExp>
Chris@330 31
Chris@330 32 TransformFactory *
Chris@330 33 TransformFactory::m_instance = new TransformFactory;
Chris@330 34
Chris@330 35 TransformFactory *
Chris@330 36 TransformFactory::getInstance()
Chris@330 37 {
Chris@330 38 return m_instance;
Chris@330 39 }
Chris@330 40
Chris@330 41 TransformFactory::~TransformFactory()
Chris@330 42 {
Chris@330 43 }
Chris@330 44
Chris@330 45 TransformList
Chris@330 46 TransformFactory::getAllTransforms()
Chris@330 47 {
Chris@330 48 if (m_transforms.empty()) populateTransforms();
Chris@330 49
Chris@330 50 std::set<TransformDescription> dset;
Chris@330 51 for (TransformDescriptionMap::const_iterator i = m_transforms.begin();
Chris@330 52 i != m_transforms.end(); ++i) {
Chris@330 53 dset.insert(i->second);
Chris@330 54 }
Chris@330 55
Chris@330 56 TransformList list;
Chris@330 57 for (std::set<TransformDescription>::const_iterator i = dset.begin();
Chris@330 58 i != dset.end(); ++i) {
Chris@330 59 list.push_back(*i);
Chris@330 60 }
Chris@330 61
Chris@330 62 return list;
Chris@330 63 }
Chris@330 64
Chris@330 65 std::vector<QString>
Chris@330 66 TransformFactory::getAllTransformTypes()
Chris@330 67 {
Chris@330 68 if (m_transforms.empty()) populateTransforms();
Chris@330 69
Chris@330 70 std::set<QString> types;
Chris@330 71 for (TransformDescriptionMap::const_iterator i = m_transforms.begin();
Chris@330 72 i != m_transforms.end(); ++i) {
Chris@330 73 types.insert(i->second.type);
Chris@330 74 }
Chris@330 75
Chris@330 76 std::vector<QString> rv;
Chris@330 77 for (std::set<QString>::iterator i = types.begin(); i != types.end(); ++i) {
Chris@330 78 rv.push_back(*i);
Chris@330 79 }
Chris@330 80
Chris@330 81 return rv;
Chris@330 82 }
Chris@330 83
Chris@330 84 std::vector<QString>
Chris@330 85 TransformFactory::getTransformCategories(QString transformType)
Chris@330 86 {
Chris@330 87 if (m_transforms.empty()) populateTransforms();
Chris@330 88
Chris@330 89 std::set<QString> categories;
Chris@330 90 for (TransformDescriptionMap::const_iterator i = m_transforms.begin();
Chris@330 91 i != m_transforms.end(); ++i) {
Chris@330 92 if (i->second.type == transformType) {
Chris@330 93 categories.insert(i->second.category);
Chris@330 94 }
Chris@330 95 }
Chris@330 96
Chris@330 97 bool haveEmpty = false;
Chris@330 98
Chris@330 99 std::vector<QString> rv;
Chris@330 100 for (std::set<QString>::iterator i = categories.begin();
Chris@330 101 i != categories.end(); ++i) {
Chris@330 102 if (*i != "") rv.push_back(*i);
Chris@330 103 else haveEmpty = true;
Chris@330 104 }
Chris@330 105
Chris@330 106 if (haveEmpty) rv.push_back(""); // make sure empty category sorts last
Chris@330 107
Chris@330 108 return rv;
Chris@330 109 }
Chris@330 110
Chris@330 111 std::vector<QString>
Chris@330 112 TransformFactory::getTransformMakers(QString transformType)
Chris@330 113 {
Chris@330 114 if (m_transforms.empty()) populateTransforms();
Chris@330 115
Chris@330 116 std::set<QString> makers;
Chris@330 117 for (TransformDescriptionMap::const_iterator i = m_transforms.begin();
Chris@330 118 i != m_transforms.end(); ++i) {
Chris@330 119 if (i->second.type == transformType) {
Chris@330 120 makers.insert(i->second.maker);
Chris@330 121 }
Chris@330 122 }
Chris@330 123
Chris@330 124 bool haveEmpty = false;
Chris@330 125
Chris@330 126 std::vector<QString> rv;
Chris@330 127 for (std::set<QString>::iterator i = makers.begin();
Chris@330 128 i != makers.end(); ++i) {
Chris@330 129 if (*i != "") rv.push_back(*i);
Chris@330 130 else haveEmpty = true;
Chris@330 131 }
Chris@330 132
Chris@330 133 if (haveEmpty) rv.push_back(""); // make sure empty category sorts last
Chris@330 134
Chris@330 135 return rv;
Chris@330 136 }
Chris@330 137
Chris@330 138 void
Chris@330 139 TransformFactory::populateTransforms()
Chris@330 140 {
Chris@330 141 TransformDescriptionMap transforms;
Chris@330 142
Chris@330 143 populateFeatureExtractionPlugins(transforms);
Chris@330 144 populateRealTimePlugins(transforms);
Chris@330 145
Chris@330 146 // disambiguate plugins with similar names
Chris@330 147
Chris@330 148 std::map<QString, int> names;
Chris@330 149 std::map<QString, QString> pluginSources;
Chris@330 150 std::map<QString, QString> pluginMakers;
Chris@330 151
Chris@330 152 for (TransformDescriptionMap::iterator i = transforms.begin();
Chris@330 153 i != transforms.end(); ++i) {
Chris@330 154
Chris@330 155 TransformDescription desc = i->second;
Chris@330 156
Chris@330 157 QString td = desc.name;
Chris@330 158 QString tn = td.section(": ", 0, 0);
Chris@330 159 QString pn = desc.identifier.section(":", 1, 1);
Chris@330 160
Chris@330 161 if (pluginSources.find(tn) != pluginSources.end()) {
Chris@330 162 if (pluginSources[tn] != pn && pluginMakers[tn] != desc.maker) {
Chris@330 163 ++names[tn];
Chris@330 164 }
Chris@330 165 } else {
Chris@330 166 ++names[tn];
Chris@330 167 pluginSources[tn] = pn;
Chris@330 168 pluginMakers[tn] = desc.maker;
Chris@330 169 }
Chris@330 170 }
Chris@330 171
Chris@330 172 std::map<QString, int> counts;
Chris@330 173 m_transforms.clear();
Chris@330 174
Chris@330 175 for (TransformDescriptionMap::iterator i = transforms.begin();
Chris@330 176 i != transforms.end(); ++i) {
Chris@330 177
Chris@330 178 TransformDescription desc = i->second;
Chris@330 179 QString identifier = desc.identifier;
Chris@330 180 QString maker = desc.maker;
Chris@330 181
Chris@330 182 QString td = desc.name;
Chris@330 183 QString tn = td.section(": ", 0, 0);
Chris@330 184 QString to = td.section(": ", 1);
Chris@330 185
Chris@330 186 if (names[tn] > 1) {
Chris@330 187 maker.replace(QRegExp(tr(" [\\(<].*$")), "");
Chris@330 188 tn = QString("%1 [%2]").arg(tn).arg(maker);
Chris@330 189 }
Chris@330 190
Chris@330 191 if (to != "") {
Chris@330 192 desc.name = QString("%1: %2").arg(tn).arg(to);
Chris@330 193 } else {
Chris@330 194 desc.name = tn;
Chris@330 195 }
Chris@330 196
Chris@330 197 m_transforms[identifier] = desc;
Chris@330 198 }
Chris@330 199 }
Chris@330 200
Chris@330 201 void
Chris@330 202 TransformFactory::populateFeatureExtractionPlugins(TransformDescriptionMap &transforms)
Chris@330 203 {
Chris@330 204 std::vector<QString> plugs =
Chris@330 205 FeatureExtractionPluginFactory::getAllPluginIdentifiers();
Chris@330 206
Chris@330 207 for (size_t i = 0; i < plugs.size(); ++i) {
Chris@330 208
Chris@330 209 QString pluginId = plugs[i];
Chris@330 210
Chris@330 211 FeatureExtractionPluginFactory *factory =
Chris@330 212 FeatureExtractionPluginFactory::instanceFor(pluginId);
Chris@330 213
Chris@330 214 if (!factory) {
Chris@330 215 std::cerr << "WARNING: TransformFactory::populateTransforms: No feature extraction plugin factory for instance " << pluginId.toLocal8Bit().data() << std::endl;
Chris@330 216 continue;
Chris@330 217 }
Chris@330 218
Chris@330 219 Vamp::Plugin *plugin =
Chris@330 220 factory->instantiatePlugin(pluginId, 48000);
Chris@330 221
Chris@330 222 if (!plugin) {
Chris@330 223 std::cerr << "WARNING: TransformFactory::populateTransforms: Failed to instantiate plugin " << pluginId.toLocal8Bit().data() << std::endl;
Chris@330 224 continue;
Chris@330 225 }
Chris@330 226
Chris@330 227 QString pluginName = plugin->getName().c_str();
Chris@330 228 QString category = factory->getPluginCategory(pluginId);
Chris@330 229
Chris@330 230 Vamp::Plugin::OutputList outputs =
Chris@330 231 plugin->getOutputDescriptors();
Chris@330 232
Chris@330 233 for (size_t j = 0; j < outputs.size(); ++j) {
Chris@330 234
Chris@330 235 QString transformId = QString("%1:%2")
Chris@330 236 .arg(pluginId).arg(outputs[j].identifier.c_str());
Chris@330 237
Chris@330 238 QString userName;
Chris@330 239 QString friendlyName;
Chris@330 240 QString units = outputs[j].unit.c_str();
Chris@330 241 QString description = plugin->getDescription().c_str();
Chris@330 242 QString maker = plugin->getMaker().c_str();
Chris@330 243 if (maker == "") maker = tr("<unknown maker>");
Chris@330 244
Chris@330 245 if (description == "") {
Chris@330 246 if (outputs.size() == 1) {
Chris@330 247 description = tr("Extract features using \"%1\" plugin (from %2)")
Chris@330 248 .arg(pluginName).arg(maker);
Chris@330 249 } else {
Chris@330 250 description = tr("Extract features using \"%1\" output of \"%2\" plugin (from %3)")
Chris@330 251 .arg(outputs[j].name.c_str()).arg(pluginName).arg(maker);
Chris@330 252 }
Chris@330 253 } else {
Chris@330 254 if (outputs.size() == 1) {
Chris@330 255 description = tr("%1 using \"%2\" plugin (from %3)")
Chris@330 256 .arg(description).arg(pluginName).arg(maker);
Chris@330 257 } else {
Chris@330 258 description = tr("%1 using \"%2\" output of \"%3\" plugin (from %4)")
Chris@330 259 .arg(description).arg(outputs[j].name.c_str()).arg(pluginName).arg(maker);
Chris@330 260 }
Chris@330 261 }
Chris@330 262
Chris@330 263 if (outputs.size() == 1) {
Chris@330 264 userName = pluginName;
Chris@330 265 friendlyName = pluginName;
Chris@330 266 } else {
Chris@330 267 userName = QString("%1: %2")
Chris@330 268 .arg(pluginName)
Chris@330 269 .arg(outputs[j].name.c_str());
Chris@330 270 friendlyName = outputs[j].name.c_str();
Chris@330 271 }
Chris@330 272
Chris@330 273 bool configurable = (!plugin->getPrograms().empty() ||
Chris@330 274 !plugin->getParameterDescriptors().empty());
Chris@330 275
Chris@330 276 // std::cerr << "Feature extraction plugin transform: " << transformId.toStdString() << std::endl;
Chris@330 277
Chris@330 278 transforms[transformId] =
Chris@330 279 TransformDescription(tr("Analysis"),
Chris@332 280 category,
Chris@332 281 transformId,
Chris@332 282 userName,
Chris@332 283 friendlyName,
Chris@332 284 description,
Chris@332 285 maker,
Chris@332 286 units,
Chris@332 287 configurable);
Chris@330 288 }
Chris@330 289
Chris@330 290 delete plugin;
Chris@330 291 }
Chris@330 292 }
Chris@330 293
Chris@330 294 void
Chris@330 295 TransformFactory::populateRealTimePlugins(TransformDescriptionMap &transforms)
Chris@330 296 {
Chris@330 297 std::vector<QString> plugs =
Chris@330 298 RealTimePluginFactory::getAllPluginIdentifiers();
Chris@330 299
Chris@330 300 static QRegExp unitRE("[\\[\\(]([A-Za-z0-9/]+)[\\)\\]]$");
Chris@330 301
Chris@330 302 for (size_t i = 0; i < plugs.size(); ++i) {
Chris@330 303
Chris@330 304 QString pluginId = plugs[i];
Chris@330 305
Chris@330 306 RealTimePluginFactory *factory =
Chris@330 307 RealTimePluginFactory::instanceFor(pluginId);
Chris@330 308
Chris@330 309 if (!factory) {
Chris@330 310 std::cerr << "WARNING: TransformFactory::populateTransforms: No real time plugin factory for instance " << pluginId.toLocal8Bit().data() << std::endl;
Chris@330 311 continue;
Chris@330 312 }
Chris@330 313
Chris@330 314 const RealTimePluginDescriptor *descriptor =
Chris@330 315 factory->getPluginDescriptor(pluginId);
Chris@330 316
Chris@330 317 if (!descriptor) {
Chris@330 318 std::cerr << "WARNING: TransformFactory::populateTransforms: Failed to query plugin " << pluginId.toLocal8Bit().data() << std::endl;
Chris@330 319 continue;
Chris@330 320 }
Chris@330 321
Chris@330 322 //!!! if (descriptor->controlOutputPortCount == 0 ||
Chris@330 323 // descriptor->audioInputPortCount == 0) continue;
Chris@330 324
Chris@330 325 // std::cout << "TransformFactory::populateRealTimePlugins: plugin " << pluginId.toStdString() << " has " << descriptor->controlOutputPortCount << " control output ports, " << descriptor->audioOutputPortCount << " audio outputs, " << descriptor->audioInputPortCount << " audio inputs" << std::endl;
Chris@330 326
Chris@330 327 QString pluginName = descriptor->name.c_str();
Chris@330 328 QString category = factory->getPluginCategory(pluginId);
Chris@330 329 bool configurable = (descriptor->parameterCount > 0);
Chris@330 330 QString maker = descriptor->maker.c_str();
Chris@330 331 if (maker == "") maker = tr("<unknown maker>");
Chris@330 332
Chris@330 333 if (descriptor->audioInputPortCount > 0) {
Chris@330 334
Chris@330 335 for (size_t j = 0; j < descriptor->controlOutputPortCount; ++j) {
Chris@330 336
Chris@330 337 QString transformId = QString("%1:%2").arg(pluginId).arg(j);
Chris@330 338 QString userName;
Chris@330 339 QString units;
Chris@330 340 QString portName;
Chris@330 341
Chris@330 342 if (j < descriptor->controlOutputPortNames.size() &&
Chris@330 343 descriptor->controlOutputPortNames[j] != "") {
Chris@330 344
Chris@330 345 portName = descriptor->controlOutputPortNames[j].c_str();
Chris@330 346
Chris@330 347 userName = tr("%1: %2")
Chris@330 348 .arg(pluginName)
Chris@330 349 .arg(portName);
Chris@330 350
Chris@330 351 if (unitRE.indexIn(portName) >= 0) {
Chris@330 352 units = unitRE.cap(1);
Chris@330 353 }
Chris@330 354
Chris@330 355 } else if (descriptor->controlOutputPortCount > 1) {
Chris@330 356
Chris@330 357 userName = tr("%1: Output %2")
Chris@330 358 .arg(pluginName)
Chris@330 359 .arg(j + 1);
Chris@330 360
Chris@330 361 } else {
Chris@330 362
Chris@330 363 userName = pluginName;
Chris@330 364 }
Chris@330 365
Chris@330 366 QString description;
Chris@330 367
Chris@330 368 if (portName != "") {
Chris@330 369 description = tr("Extract \"%1\" data output from \"%2\" effect plugin (from %3)")
Chris@330 370 .arg(portName)
Chris@330 371 .arg(pluginName)
Chris@330 372 .arg(maker);
Chris@330 373 } else {
Chris@330 374 description = tr("Extract data output %1 from \"%2\" effect plugin (from %3)")
Chris@330 375 .arg(j + 1)
Chris@330 376 .arg(pluginName)
Chris@330 377 .arg(maker);
Chris@330 378 }
Chris@330 379
Chris@330 380 transforms[transformId] =
Chris@330 381 TransformDescription(tr("Effects Data"),
Chris@332 382 category,
Chris@332 383 transformId,
Chris@332 384 userName,
Chris@332 385 userName,
Chris@332 386 description,
Chris@332 387 maker,
Chris@332 388 units,
Chris@332 389 configurable);
Chris@330 390 }
Chris@330 391 }
Chris@330 392
Chris@330 393 if (!descriptor->isSynth || descriptor->audioInputPortCount > 0) {
Chris@330 394
Chris@330 395 if (descriptor->audioOutputPortCount > 0) {
Chris@330 396
Chris@330 397 QString transformId = QString("%1:A").arg(pluginId);
Chris@330 398 QString type = tr("Effects");
Chris@330 399
Chris@330 400 QString description = tr("Transform audio signal with \"%1\" effect plugin (from %2)")
Chris@330 401 .arg(pluginName)
Chris@330 402 .arg(maker);
Chris@330 403
Chris@330 404 if (descriptor->audioInputPortCount == 0) {
Chris@330 405 type = tr("Generators");
Chris@330 406 QString description = tr("Generate audio signal using \"%1\" plugin (from %2)")
Chris@330 407 .arg(pluginName)
Chris@330 408 .arg(maker);
Chris@330 409 }
Chris@330 410
Chris@330 411 transforms[transformId] =
Chris@330 412 TransformDescription(type,
Chris@332 413 category,
Chris@332 414 transformId,
Chris@332 415 pluginName,
Chris@332 416 pluginName,
Chris@332 417 description,
Chris@332 418 maker,
Chris@332 419 "",
Chris@332 420 configurable);
Chris@330 421 }
Chris@330 422 }
Chris@330 423 }
Chris@330 424 }
Chris@330 425
Chris@330 426 bool
Chris@330 427 TransformFactory::haveTransform(TransformId identifier)
Chris@330 428 {
Chris@333 429 if (m_transforms.empty()) populateTransforms();
Chris@330 430 return (m_transforms.find(identifier) != m_transforms.end());
Chris@330 431 }
Chris@330 432
Chris@330 433 QString
Chris@330 434 TransformFactory::getTransformName(TransformId identifier)
Chris@330 435 {
Chris@330 436 if (m_transforms.find(identifier) != m_transforms.end()) {
Chris@330 437 return m_transforms[identifier].name;
Chris@330 438 } else return "";
Chris@330 439 }
Chris@330 440
Chris@330 441 QString
Chris@330 442 TransformFactory::getTransformFriendlyName(TransformId identifier)
Chris@330 443 {
Chris@330 444 if (m_transforms.find(identifier) != m_transforms.end()) {
Chris@330 445 return m_transforms[identifier].friendlyName;
Chris@330 446 } else return "";
Chris@330 447 }
Chris@330 448
Chris@330 449 QString
Chris@330 450 TransformFactory::getTransformUnits(TransformId identifier)
Chris@330 451 {
Chris@330 452 if (m_transforms.find(identifier) != m_transforms.end()) {
Chris@330 453 return m_transforms[identifier].units;
Chris@330 454 } else return "";
Chris@330 455 }
Chris@330 456
Chris@330 457 bool
Chris@330 458 TransformFactory::isTransformConfigurable(TransformId identifier)
Chris@330 459 {
Chris@330 460 if (m_transforms.find(identifier) != m_transforms.end()) {
Chris@330 461 return m_transforms[identifier].configurable;
Chris@330 462 } else return false;
Chris@330 463 }
Chris@330 464
Chris@330 465 bool
Chris@330 466 TransformFactory::getTransformChannelRange(TransformId identifier,
Chris@330 467 int &min, int &max)
Chris@330 468 {
Chris@330 469 QString id = identifier.section(':', 0, 2);
Chris@330 470
Chris@330 471 if (FeatureExtractionPluginFactory::instanceFor(id)) {
Chris@330 472
Chris@330 473 Vamp::Plugin *plugin =
Chris@330 474 FeatureExtractionPluginFactory::instanceFor(id)->
Chris@330 475 instantiatePlugin(id, 48000);
Chris@330 476 if (!plugin) return false;
Chris@330 477
Chris@330 478 min = plugin->getMinChannelCount();
Chris@330 479 max = plugin->getMaxChannelCount();
Chris@330 480 delete plugin;
Chris@330 481
Chris@330 482 return true;
Chris@330 483
Chris@330 484 } else if (RealTimePluginFactory::instanceFor(id)) {
Chris@330 485
Chris@330 486 const RealTimePluginDescriptor *descriptor =
Chris@330 487 RealTimePluginFactory::instanceFor(id)->
Chris@330 488 getPluginDescriptor(id);
Chris@330 489 if (!descriptor) return false;
Chris@330 490
Chris@330 491 min = descriptor->audioInputPortCount;
Chris@330 492 max = descriptor->audioInputPortCount;
Chris@330 493
Chris@330 494 return true;
Chris@330 495 }
Chris@330 496
Chris@330 497 return false;
Chris@330 498 }
Chris@332 499
Chris@332 500 void
Chris@332 501 TransformFactory::setParametersFromPlugin(Transform &transform,
Chris@332 502 Vamp::PluginBase *plugin)
Chris@332 503 {
Chris@332 504 Transform::ParameterMap pmap;
Chris@332 505
Chris@332 506 Vamp::PluginBase::ParameterList parameters =
Chris@332 507 plugin->getParameterDescriptors();
Chris@332 508
Chris@332 509 for (Vamp::PluginBase::ParameterList::const_iterator i = parameters.begin();
Chris@332 510 i != parameters.end(); ++i) {
Chris@332 511 pmap[i->identifier.c_str()] = plugin->getParameter(i->identifier);
Chris@332 512 }
Chris@332 513
Chris@332 514 transform.setParameters(pmap);
Chris@332 515
Chris@332 516 if (plugin->getPrograms().empty()) {
Chris@332 517 transform.setProgram("");
Chris@332 518 } else {
Chris@332 519 transform.setProgram(plugin->getCurrentProgram().c_str());
Chris@332 520 }
Chris@332 521
Chris@332 522 RealTimePluginInstance *rtpi =
Chris@332 523 dynamic_cast<RealTimePluginInstance *>(plugin);
Chris@332 524
Chris@332 525 Transform::ConfigurationMap cmap;
Chris@332 526
Chris@332 527 if (rtpi) {
Chris@332 528
Chris@332 529 RealTimePluginInstance::ConfigurationPairMap configurePairs =
Chris@332 530 rtpi->getConfigurePairs();
Chris@332 531
Chris@332 532 for (RealTimePluginInstance::ConfigurationPairMap::const_iterator i
Chris@332 533 = configurePairs.begin(); i != configurePairs.end(); ++i) {
Chris@332 534 cmap[i->first.c_str()] = i->second.c_str();
Chris@332 535 }
Chris@332 536 }
Chris@332 537
Chris@332 538 transform.setConfiguration(cmap);
Chris@332 539 }
Chris@332 540
Chris@332 541 void
Chris@332 542 TransformFactory::makeContextConsistentWithPlugin(Transform &transform,
Chris@332 543 Vamp::PluginBase *plugin)
Chris@332 544 {
Chris@332 545 const Vamp::Plugin *vp = dynamic_cast<const Vamp::Plugin *>(plugin);
Chris@332 546 if (!vp) {
Chris@332 547 // std::cerr << "makeConsistentWithPlugin: not a Vamp::Plugin" << std::endl;
Chris@332 548 vp = dynamic_cast<const Vamp::PluginHostAdapter *>(plugin); //!!! why?
Chris@332 549 }
Chris@332 550 if (!vp) {
Chris@332 551 // std::cerr << "makeConsistentWithPlugin: not a Vamp::PluginHostAdapter" << std::endl;
Chris@332 552 vp = dynamic_cast<const Vamp::HostExt::PluginWrapper *>(plugin); //!!! no, I mean really why?
Chris@332 553 }
Chris@332 554 if (!vp) {
Chris@332 555 // std::cerr << "makeConsistentWithPlugin: not a Vamp::HostExt::PluginWrapper" << std::endl;
Chris@332 556 }
Chris@332 557
Chris@332 558 if (!vp) {
Chris@332 559 // time domain input for real-time effects plugin
Chris@332 560 if (!transform.getBlockSize()) {
Chris@332 561 if (!transform.getStepSize()) transform.setStepSize(1024);
Chris@332 562 transform.setBlockSize(transform.getStepSize());
Chris@332 563 } else {
Chris@332 564 transform.setStepSize(transform.getBlockSize());
Chris@332 565 }
Chris@332 566 } else {
Chris@332 567 Vamp::Plugin::InputDomain domain = vp->getInputDomain();
Chris@332 568 if (!transform.getStepSize()) {
Chris@332 569 transform.setStepSize(vp->getPreferredStepSize());
Chris@332 570 }
Chris@332 571 if (!transform.getBlockSize()) {
Chris@332 572 transform.setBlockSize(vp->getPreferredBlockSize());
Chris@332 573 }
Chris@332 574 if (!transform.getBlockSize()) {
Chris@332 575 transform.setBlockSize(1024);
Chris@332 576 }
Chris@332 577 if (!transform.getStepSize()) {
Chris@332 578 if (domain == Vamp::Plugin::FrequencyDomain) {
Chris@332 579 // std::cerr << "frequency domain, step = " << blockSize/2 << std::endl;
Chris@332 580 transform.setStepSize(transform.getBlockSize()/2);
Chris@332 581 } else {
Chris@332 582 // std::cerr << "time domain, step = " << blockSize/2 << std::endl;
Chris@332 583 transform.setStepSize(transform.getBlockSize());
Chris@332 584 }
Chris@332 585 }
Chris@332 586 }
Chris@332 587 }
Chris@332 588
Chris@332 589 Transform
Chris@332 590 TransformFactory::getDefaultTransformFor(TransformId id, size_t rate)
Chris@332 591 {
Chris@332 592 Transform t;
Chris@332 593 t.setIdentifier(id);
Chris@332 594
Chris@332 595 if (rate == 0) {
Chris@332 596 rate = 44100;
Chris@332 597 } else {
Chris@332 598 t.setSampleRate(rate);
Chris@332 599 }
Chris@332 600
Chris@332 601 QString pluginId = t.getPluginIdentifier();
Chris@332 602
Chris@332 603 if (t.getType() == Transform::FeatureExtraction) {
Chris@332 604
Chris@332 605 FeatureExtractionPluginFactory *factory =
Chris@332 606 FeatureExtractionPluginFactory::instanceFor(pluginId);
Chris@332 607
Chris@332 608 Vamp::Plugin *plugin = factory->instantiatePlugin
Chris@332 609 (pluginId, rate);
Chris@332 610
Chris@332 611 if (plugin) {
Chris@332 612 setParametersFromPlugin(t, plugin);
Chris@332 613 makeContextConsistentWithPlugin(t, plugin);
Chris@332 614 delete plugin;
Chris@332 615 }
Chris@332 616
Chris@332 617 } else {
Chris@332 618
Chris@332 619 RealTimePluginFactory *factory =
Chris@332 620 RealTimePluginFactory::instanceFor(pluginId);
Chris@332 621
Chris@332 622 RealTimePluginInstance *plugin = factory->instantiatePlugin
Chris@332 623 (pluginId, 0, 0, rate, 1024, 1);
Chris@332 624
Chris@332 625 if (plugin) {
Chris@332 626 setParametersFromPlugin(t, plugin);
Chris@332 627 makeContextConsistentWithPlugin(t, plugin);
Chris@332 628 delete plugin;
Chris@332 629 }
Chris@332 630 }
Chris@332 631
Chris@332 632 return t;
Chris@332 633 }
Chris@332 634