annotate transform/TransformFactory.cpp @ 52:527598e2fa10

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