annotate plugin/transform/TransformFactory.cpp @ 339:ba30f4a3e3be

* Some work on correct alignment when moving panes during playback * Overhaul alignment for playback frame values (view manager now always refers to reference-timeline values, only the play source deals in playback model timeline values) * When making a selection, ensure the selection regions shown in other panes (and used for playback constraints if appropriate) are aligned correctly. This may be the coolest feature ever implemented in any program ever.
author Chris Cannam
date Thu, 22 Nov 2007 14:17:19 +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