annotate plugin/transform/TransformFactory.cpp @ 332:13e5870040e6

* some tidying, and put some actual work in TransformFactory
author Chris Cannam
date Wed, 07 Nov 2007 14:53:12 +0000
parents 6e9dcf09b7fe
children 1afaf98dbf11
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@330 429 return (m_transforms.find(identifier) != m_transforms.end());
Chris@330 430 }
Chris@330 431
Chris@330 432 QString
Chris@330 433 TransformFactory::getTransformName(TransformId identifier)
Chris@330 434 {
Chris@330 435 if (m_transforms.find(identifier) != m_transforms.end()) {
Chris@330 436 return m_transforms[identifier].name;
Chris@330 437 } else return "";
Chris@330 438 }
Chris@330 439
Chris@330 440 QString
Chris@330 441 TransformFactory::getTransformFriendlyName(TransformId identifier)
Chris@330 442 {
Chris@330 443 if (m_transforms.find(identifier) != m_transforms.end()) {
Chris@330 444 return m_transforms[identifier].friendlyName;
Chris@330 445 } else return "";
Chris@330 446 }
Chris@330 447
Chris@330 448 QString
Chris@330 449 TransformFactory::getTransformUnits(TransformId identifier)
Chris@330 450 {
Chris@330 451 if (m_transforms.find(identifier) != m_transforms.end()) {
Chris@330 452 return m_transforms[identifier].units;
Chris@330 453 } else return "";
Chris@330 454 }
Chris@330 455
Chris@330 456 bool
Chris@330 457 TransformFactory::isTransformConfigurable(TransformId identifier)
Chris@330 458 {
Chris@330 459 if (m_transforms.find(identifier) != m_transforms.end()) {
Chris@330 460 return m_transforms[identifier].configurable;
Chris@330 461 } else return false;
Chris@330 462 }
Chris@330 463
Chris@330 464 bool
Chris@330 465 TransformFactory::getTransformChannelRange(TransformId identifier,
Chris@330 466 int &min, int &max)
Chris@330 467 {
Chris@330 468 QString id = identifier.section(':', 0, 2);
Chris@330 469
Chris@330 470 if (FeatureExtractionPluginFactory::instanceFor(id)) {
Chris@330 471
Chris@330 472 Vamp::Plugin *plugin =
Chris@330 473 FeatureExtractionPluginFactory::instanceFor(id)->
Chris@330 474 instantiatePlugin(id, 48000);
Chris@330 475 if (!plugin) return false;
Chris@330 476
Chris@330 477 min = plugin->getMinChannelCount();
Chris@330 478 max = plugin->getMaxChannelCount();
Chris@330 479 delete plugin;
Chris@330 480
Chris@330 481 return true;
Chris@330 482
Chris@330 483 } else if (RealTimePluginFactory::instanceFor(id)) {
Chris@330 484
Chris@330 485 const RealTimePluginDescriptor *descriptor =
Chris@330 486 RealTimePluginFactory::instanceFor(id)->
Chris@330 487 getPluginDescriptor(id);
Chris@330 488 if (!descriptor) return false;
Chris@330 489
Chris@330 490 min = descriptor->audioInputPortCount;
Chris@330 491 max = descriptor->audioInputPortCount;
Chris@330 492
Chris@330 493 return true;
Chris@330 494 }
Chris@330 495
Chris@330 496 return false;
Chris@330 497 }
Chris@332 498
Chris@332 499 void
Chris@332 500 TransformFactory::setParametersFromPlugin(Transform &transform,
Chris@332 501 Vamp::PluginBase *plugin)
Chris@332 502 {
Chris@332 503 Transform::ParameterMap pmap;
Chris@332 504
Chris@332 505 Vamp::PluginBase::ParameterList parameters =
Chris@332 506 plugin->getParameterDescriptors();
Chris@332 507
Chris@332 508 for (Vamp::PluginBase::ParameterList::const_iterator i = parameters.begin();
Chris@332 509 i != parameters.end(); ++i) {
Chris@332 510 pmap[i->identifier.c_str()] = plugin->getParameter(i->identifier);
Chris@332 511 }
Chris@332 512
Chris@332 513 transform.setParameters(pmap);
Chris@332 514
Chris@332 515 if (plugin->getPrograms().empty()) {
Chris@332 516 transform.setProgram("");
Chris@332 517 } else {
Chris@332 518 transform.setProgram(plugin->getCurrentProgram().c_str());
Chris@332 519 }
Chris@332 520
Chris@332 521 RealTimePluginInstance *rtpi =
Chris@332 522 dynamic_cast<RealTimePluginInstance *>(plugin);
Chris@332 523
Chris@332 524 Transform::ConfigurationMap cmap;
Chris@332 525
Chris@332 526 if (rtpi) {
Chris@332 527
Chris@332 528 RealTimePluginInstance::ConfigurationPairMap configurePairs =
Chris@332 529 rtpi->getConfigurePairs();
Chris@332 530
Chris@332 531 for (RealTimePluginInstance::ConfigurationPairMap::const_iterator i
Chris@332 532 = configurePairs.begin(); i != configurePairs.end(); ++i) {
Chris@332 533 cmap[i->first.c_str()] = i->second.c_str();
Chris@332 534 }
Chris@332 535 }
Chris@332 536
Chris@332 537 transform.setConfiguration(cmap);
Chris@332 538 }
Chris@332 539
Chris@332 540 void
Chris@332 541 TransformFactory::makeContextConsistentWithPlugin(Transform &transform,
Chris@332 542 Vamp::PluginBase *plugin)
Chris@332 543 {
Chris@332 544 const Vamp::Plugin *vp = dynamic_cast<const Vamp::Plugin *>(plugin);
Chris@332 545 if (!vp) {
Chris@332 546 // std::cerr << "makeConsistentWithPlugin: not a Vamp::Plugin" << std::endl;
Chris@332 547 vp = dynamic_cast<const Vamp::PluginHostAdapter *>(plugin); //!!! why?
Chris@332 548 }
Chris@332 549 if (!vp) {
Chris@332 550 // std::cerr << "makeConsistentWithPlugin: not a Vamp::PluginHostAdapter" << std::endl;
Chris@332 551 vp = dynamic_cast<const Vamp::HostExt::PluginWrapper *>(plugin); //!!! no, I mean really why?
Chris@332 552 }
Chris@332 553 if (!vp) {
Chris@332 554 // std::cerr << "makeConsistentWithPlugin: not a Vamp::HostExt::PluginWrapper" << std::endl;
Chris@332 555 }
Chris@332 556
Chris@332 557 if (!vp) {
Chris@332 558 // time domain input for real-time effects plugin
Chris@332 559 if (!transform.getBlockSize()) {
Chris@332 560 if (!transform.getStepSize()) transform.setStepSize(1024);
Chris@332 561 transform.setBlockSize(transform.getStepSize());
Chris@332 562 } else {
Chris@332 563 transform.setStepSize(transform.getBlockSize());
Chris@332 564 }
Chris@332 565 } else {
Chris@332 566 Vamp::Plugin::InputDomain domain = vp->getInputDomain();
Chris@332 567 if (!transform.getStepSize()) {
Chris@332 568 transform.setStepSize(vp->getPreferredStepSize());
Chris@332 569 }
Chris@332 570 if (!transform.getBlockSize()) {
Chris@332 571 transform.setBlockSize(vp->getPreferredBlockSize());
Chris@332 572 }
Chris@332 573 if (!transform.getBlockSize()) {
Chris@332 574 transform.setBlockSize(1024);
Chris@332 575 }
Chris@332 576 if (!transform.getStepSize()) {
Chris@332 577 if (domain == Vamp::Plugin::FrequencyDomain) {
Chris@332 578 // std::cerr << "frequency domain, step = " << blockSize/2 << std::endl;
Chris@332 579 transform.setStepSize(transform.getBlockSize()/2);
Chris@332 580 } else {
Chris@332 581 // std::cerr << "time domain, step = " << blockSize/2 << std::endl;
Chris@332 582 transform.setStepSize(transform.getBlockSize());
Chris@332 583 }
Chris@332 584 }
Chris@332 585 }
Chris@332 586 }
Chris@332 587
Chris@332 588 Transform
Chris@332 589 TransformFactory::getDefaultTransformFor(TransformId id, size_t rate)
Chris@332 590 {
Chris@332 591 Transform t;
Chris@332 592 t.setIdentifier(id);
Chris@332 593
Chris@332 594 if (rate == 0) {
Chris@332 595 rate = 44100;
Chris@332 596 } else {
Chris@332 597 t.setSampleRate(rate);
Chris@332 598 }
Chris@332 599
Chris@332 600 QString pluginId = t.getPluginIdentifier();
Chris@332 601
Chris@332 602 if (t.getType() == Transform::FeatureExtraction) {
Chris@332 603
Chris@332 604 FeatureExtractionPluginFactory *factory =
Chris@332 605 FeatureExtractionPluginFactory::instanceFor(pluginId);
Chris@332 606
Chris@332 607 Vamp::Plugin *plugin = factory->instantiatePlugin
Chris@332 608 (pluginId, rate);
Chris@332 609
Chris@332 610 if (plugin) {
Chris@332 611 setParametersFromPlugin(t, plugin);
Chris@332 612 makeContextConsistentWithPlugin(t, plugin);
Chris@332 613 delete plugin;
Chris@332 614 }
Chris@332 615
Chris@332 616 } else {
Chris@332 617
Chris@332 618 RealTimePluginFactory *factory =
Chris@332 619 RealTimePluginFactory::instanceFor(pluginId);
Chris@332 620
Chris@332 621 RealTimePluginInstance *plugin = factory->instantiatePlugin
Chris@332 622 (pluginId, 0, 0, rate, 1024, 1);
Chris@332 623
Chris@332 624 if (plugin) {
Chris@332 625 setParametersFromPlugin(t, plugin);
Chris@332 626 makeContextConsistentWithPlugin(t, plugin);
Chris@332 627 delete plugin;
Chris@332 628 }
Chris@332 629 }
Chris@332 630
Chris@332 631 return t;
Chris@332 632 }
Chris@332 633