Mercurial > hg > svapp
view framework/TransformUserConfigurator.cpp @ 747:bac019c94e38
Use Provider structure
author | Chris Cannam |
---|---|
date | Mon, 20 Apr 2020 18:47:04 +0100 |
parents | 846970dbef17 |
children |
line wrap: on
line source
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ /* Sonic Visualiser An audio file viewer and annotation editor. Centre for Digital Music, Queen Mary, University of London. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. See the file COPYING included with this distribution for more information. */ #include "TransformUserConfigurator.h" #include "transform/TransformFactory.h" #include "widgets/PluginParameterDialog.h" #include "plugin/FeatureExtractionPluginFactory.h" #include "plugin/RealTimePluginFactory.h" #include "plugin/RealTimePluginInstance.h" #include "data/model/DenseTimeValueModel.h" #include <vamp-hostsdk/Plugin.h> #include <QStringList> #include <typeinfo> static QWidget *parentWidget = nullptr; void TransformUserConfigurator::setParentWidget(QWidget *w) { parentWidget = w; } bool TransformUserConfigurator::getChannelRange(TransformId identifier, std::shared_ptr<Vamp::PluginBase> plugin, int &minChannels, int &maxChannels) { if (plugin && plugin->getType() == "Feature Extraction Plugin") { auto vp = std::dynamic_pointer_cast<Vamp::Plugin>(plugin); if (vp) { SVDEBUG << "TransformUserConfigurator::getChannelRange: is a Vamp plugin" << endl; minChannels = int(vp->getMinChannelCount()); maxChannels = int(vp->getMaxChannelCount()); return true; } else { SVCERR << "TransformUserConfigurator::getChannelRange: inconsistent plugin identity!" << endl; return false; } } else { SVDEBUG << "TransformUserConfigurator::getChannelRange: is not a Vamp plugin" << endl; return TransformFactory::getInstance()-> getTransformChannelRange(identifier, minChannels, maxChannels); } } bool TransformUserConfigurator::configure(ModelTransformer::Input &input, Transform &transform, std::shared_ptr<Vamp::PluginBase> plugin, ModelId &inputModel, AudioPlaySource *source, sv_frame_t startFrame, sv_frame_t duration, const QMap<QString, ModelId> &modelMap, QStringList candidateModelNames, QString defaultModelName) { bool ok = false; QString id = transform.getPluginIdentifier(); QString output = transform.getOutput(); QString outputLabel = ""; QString outputDescription = ""; bool frequency = false; bool effect = false; bool generator = false; if (!plugin) return false; SVDEBUG << "TransformUserConfigurator::configure: identifier " << id << endl; if (RealTimePluginFactory::instanceFor(id)) { RealTimePluginFactory *factory = RealTimePluginFactory::instanceFor(id); RealTimePluginDescriptor desc = factory->getPluginDescriptor(id); if (desc.audioInputPortCount > 0 && desc.audioOutputPortCount > 0 && !desc.isSynth) { effect = true; } if (desc.audioInputPortCount == 0) { generator = true; } if (output != "A") { int outputNo = output.toInt(); if (outputNo >= 0 && outputNo < int(desc.controlOutputPortCount)) { outputLabel = desc.controlOutputPortNames[outputNo].c_str(); } } auto auditionable = std::dynamic_pointer_cast<Auditionable>(plugin); if (effect && source && auditionable) { SVDEBUG << "Setting auditioning effect" << endl; source->setAuditioningEffect(auditionable); } } else { auto vp = std::dynamic_pointer_cast<Vamp::Plugin>(plugin); frequency = (vp->getInputDomain() == Vamp::Plugin::FrequencyDomain); std::vector<Vamp::Plugin::OutputDescriptor> od = vp->getOutputDescriptors(); if (od.size() > 1) { for (size_t i = 0; i < od.size(); ++i) { if (od[i].identifier == output.toStdString()) { outputLabel = od[i].name.c_str(); outputDescription = od[i].description.c_str(); break; } } } } int sourceChannels = 1; if (auto dtvm = ModelById::getAs<DenseTimeValueModel>(inputModel)) { sourceChannels = dtvm->getChannelCount(); } int minChannels = 1, maxChannels = sourceChannels; getChannelRange(transform.getIdentifier(), plugin, minChannels, maxChannels); int targetChannels = sourceChannels; if (!effect) { if (sourceChannels < minChannels) targetChannels = minChannels; if (sourceChannels > maxChannels) targetChannels = maxChannels; } int defaultChannel = -1; //!!! no longer saved! [was context.channel] PluginParameterDialog *dialog = new PluginParameterDialog (plugin, parentWidget); dialog->setMoreInfoUrl(TransformFactory::getInstance()-> getTransformProvider(transform.getIdentifier()) .infoUrl); if (candidateModelNames.size() > 1 && !generator) { dialog->setCandidateInputModels(candidateModelNames, defaultModelName); } if (startFrame != 0 || duration != 0) { dialog->setShowSelectionOnlyOption(true); } if (targetChannels > 0) { dialog->setChannelArrangement(sourceChannels, targetChannels, defaultChannel); } dialog->setOutputLabel(outputLabel, outputDescription); dialog->setShowProcessingOptions(true, frequency); if (dialog->exec() == QDialog::Accepted) { ok = true; } QString selectedInput = dialog->getInputModel(); if (selectedInput != "") { if (modelMap.contains(selectedInput)) { inputModel = modelMap.value(selectedInput); SVDEBUG << "Found selected input \"" << selectedInput << "\" in model map, result is " << inputModel << endl; } else { SVDEBUG << "Failed to find selected input \"" << selectedInput << "\" in model map" << endl; } } else { SVDEBUG << "Selected input empty: \"" << selectedInput << "\"" << endl; } // Write parameters back to transform object TransformFactory::getInstance()-> setParametersFromPlugin(transform, plugin); input.setChannel(dialog->getChannel()); //!!! The dialog ought to be taking & returning transform //objects and input objects and stuff rather than passing //around all this misc stuff, but that's for tomorrow //(whenever that may be) sv_samplerate_t sampleRate = 0; if (auto m = ModelById::get(inputModel)) { sampleRate = m->getSampleRate(); } if (startFrame != 0 || duration != 0) { if (dialog->getSelectionOnly() && sampleRate != 0) { transform.setStartTime (RealTime::frame2RealTime(startFrame, sampleRate)); transform.setDuration (RealTime::frame2RealTime(duration, sampleRate)); } } int stepSize = 0, blockSize = 0; WindowType windowType = HanningWindow; dialog->getProcessingParameters(stepSize, blockSize, windowType); transform.setStepSize(stepSize); transform.setBlockSize(blockSize); transform.setWindowType(windowType); delete dialog; if (effect && source) { source->setAuditioningEffect({}); } return ok; }