annotate framework/TransformUserConfigurator.cpp @ 786:1089d65c585d tip

Divert some debug output away from stderr
author Chris Cannam
date Fri, 14 Aug 2020 10:46:44 +0100
parents bac019c94e38
children
rev   line source
Chris@205 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@205 2
Chris@205 3 /*
Chris@205 4 Sonic Visualiser
Chris@205 5 An audio file viewer and annotation editor.
Chris@205 6 Centre for Digital Music, Queen Mary, University of London.
Chris@205 7
Chris@205 8 This program is free software; you can redistribute it and/or
Chris@205 9 modify it under the terms of the GNU General Public License as
Chris@205 10 published by the Free Software Foundation; either version 2 of the
Chris@205 11 License, or (at your option) any later version. See the file
Chris@205 12 COPYING included with this distribution for more information.
Chris@205 13 */
Chris@205 14
Chris@205 15 #include "TransformUserConfigurator.h"
Chris@205 16
Chris@205 17 #include "transform/TransformFactory.h"
Chris@205 18
Chris@205 19 #include "widgets/PluginParameterDialog.h"
Chris@205 20
Chris@205 21 #include "plugin/FeatureExtractionPluginFactory.h"
Chris@205 22 #include "plugin/RealTimePluginFactory.h"
Chris@205 23 #include "plugin/RealTimePluginInstance.h"
Chris@205 24
Chris@205 25 #include "data/model/DenseTimeValueModel.h"
Chris@205 26
Chris@205 27 #include <vamp-hostsdk/Plugin.h>
Chris@205 28
Chris@205 29 #include <QStringList>
Chris@205 30
Chris@205 31 #include <typeinfo>
Chris@205 32
Chris@636 33 static QWidget *parentWidget = nullptr;
Chris@395 34
Chris@395 35 void
Chris@395 36 TransformUserConfigurator::setParentWidget(QWidget *w)
Chris@395 37 {
Chris@395 38 parentWidget = w;
Chris@395 39 }
Chris@395 40
Chris@205 41 bool
Chris@205 42 TransformUserConfigurator::getChannelRange(TransformId identifier,
Chris@740 43 std::shared_ptr<Vamp::PluginBase> plugin,
Chris@595 44 int &minChannels, int &maxChannels)
Chris@205 45 {
Chris@205 46 if (plugin && plugin->getType() == "Feature Extraction Plugin") {
Chris@740 47 auto vp = std::dynamic_pointer_cast<Vamp::Plugin>(plugin);
Chris@740 48 if (vp) {
Chris@740 49 SVDEBUG << "TransformUserConfigurator::getChannelRange: is a Vamp plugin" << endl;
Chris@740 50 minChannels = int(vp->getMinChannelCount());
Chris@740 51 maxChannels = int(vp->getMaxChannelCount());
Chris@740 52 return true;
Chris@740 53 } else {
Chris@740 54 SVCERR << "TransformUserConfigurator::getChannelRange: inconsistent plugin identity!" << endl;
Chris@740 55 return false;
Chris@740 56 }
Chris@205 57 } else {
Chris@595 58 SVDEBUG << "TransformUserConfigurator::getChannelRange: is not a Vamp plugin" << endl;
Chris@205 59 return TransformFactory::getInstance()->
Chris@205 60 getTransformChannelRange(identifier, minChannels, maxChannels);
Chris@205 61 }
Chris@205 62 }
Chris@205 63
Chris@205 64 bool
Chris@205 65 TransformUserConfigurator::configure(ModelTransformer::Input &input,
Chris@595 66 Transform &transform,
Chris@740 67 std::shared_ptr<Vamp::PluginBase> plugin,
Chris@685 68 ModelId &inputModel,
Chris@595 69 AudioPlaySource *source,
Chris@595 70 sv_frame_t startFrame,
Chris@595 71 sv_frame_t duration,
Chris@685 72 const QMap<QString, ModelId> &modelMap,
Chris@595 73 QStringList candidateModelNames,
Chris@595 74 QString defaultModelName)
Chris@205 75 {
Chris@205 76 bool ok = false;
Chris@205 77 QString id = transform.getPluginIdentifier();
Chris@205 78 QString output = transform.getOutput();
Chris@205 79 QString outputLabel = "";
Chris@205 80 QString outputDescription = "";
Chris@205 81
Chris@205 82 bool frequency = false;
Chris@205 83 bool effect = false;
Chris@205 84 bool generator = false;
Chris@205 85
Chris@205 86 if (!plugin) return false;
Chris@205 87
Chris@536 88 SVDEBUG << "TransformUserConfigurator::configure: identifier " << id << endl;
Chris@536 89
Chris@529 90 if (RealTimePluginFactory::instanceFor(id)) {
Chris@205 91
Chris@205 92 RealTimePluginFactory *factory = RealTimePluginFactory::instanceFor(id);
Chris@740 93 RealTimePluginDescriptor desc = factory->getPluginDescriptor(id);
Chris@205 94
Chris@740 95 if (desc.audioInputPortCount > 0 &&
Chris@740 96 desc.audioOutputPortCount > 0 &&
Chris@740 97 !desc.isSynth) {
Chris@205 98 effect = true;
Chris@205 99 }
Chris@205 100
Chris@740 101 if (desc.audioInputPortCount == 0) {
Chris@205 102 generator = true;
Chris@205 103 }
Chris@205 104
Chris@205 105 if (output != "A") {
Chris@205 106 int outputNo = output.toInt();
Chris@740 107 if (outputNo >= 0 && outputNo < int(desc.controlOutputPortCount)) {
Chris@740 108 outputLabel = desc.controlOutputPortNames[outputNo].c_str();
Chris@205 109 }
Chris@205 110 }
Chris@205 111
Chris@740 112 auto auditionable = std::dynamic_pointer_cast<Auditionable>(plugin);
Chris@740 113
Chris@740 114 if (effect && source && auditionable) {
Chris@595 115 SVDEBUG << "Setting auditioning effect" << endl;
Chris@739 116 source->setAuditioningEffect(auditionable);
Chris@205 117 }
Chris@529 118
Chris@529 119 } else {
Chris@529 120
Chris@740 121 auto vp = std::dynamic_pointer_cast<Vamp::Plugin>(plugin);
Chris@529 122
Chris@595 123 frequency = (vp->getInputDomain() == Vamp::Plugin::FrequencyDomain);
Chris@529 124
Chris@595 125 std::vector<Vamp::Plugin::OutputDescriptor> od =
Chris@595 126 vp->getOutputDescriptors();
Chris@529 127
Chris@595 128 if (od.size() > 1) {
Chris@595 129 for (size_t i = 0; i < od.size(); ++i) {
Chris@595 130 if (od[i].identifier == output.toStdString()) {
Chris@595 131 outputLabel = od[i].name.c_str();
Chris@595 132 outputDescription = od[i].description.c_str();
Chris@595 133 break;
Chris@595 134 }
Chris@595 135 }
Chris@529 136 }
Chris@205 137 }
Chris@529 138
Chris@205 139 int sourceChannels = 1;
Chris@685 140
Chris@685 141 if (auto dtvm = ModelById::getAs<DenseTimeValueModel>(inputModel)) {
Chris@685 142 sourceChannels = dtvm->getChannelCount();
Chris@205 143 }
Chris@205 144
Chris@205 145 int minChannels = 1, maxChannels = sourceChannels;
Chris@205 146 getChannelRange(transform.getIdentifier(), plugin,
Chris@595 147 minChannels, maxChannels);
Chris@205 148
Chris@205 149 int targetChannels = sourceChannels;
Chris@205 150 if (!effect) {
Chris@595 151 if (sourceChannels < minChannels) targetChannels = minChannels;
Chris@595 152 if (sourceChannels > maxChannels) targetChannels = maxChannels;
Chris@205 153 }
Chris@205 154
Chris@205 155 int defaultChannel = -1; //!!! no longer saved! [was context.channel]
Chris@205 156
Chris@395 157 PluginParameterDialog *dialog = new PluginParameterDialog
Chris@395 158 (plugin, parentWidget);
Chris@205 159
Chris@205 160 dialog->setMoreInfoUrl(TransformFactory::getInstance()->
Chris@747 161 getTransformProvider(transform.getIdentifier())
Chris@747 162 .infoUrl);
Chris@205 163
Chris@205 164 if (candidateModelNames.size() > 1 && !generator) {
Chris@595 165 dialog->setCandidateInputModels(candidateModelNames,
Chris@595 166 defaultModelName);
Chris@205 167 }
Chris@205 168
Chris@205 169 if (startFrame != 0 || duration != 0) {
Chris@595 170 dialog->setShowSelectionOnlyOption(true);
Chris@205 171 }
Chris@205 172
Chris@205 173 if (targetChannels > 0) {
Chris@595 174 dialog->setChannelArrangement(sourceChannels, targetChannels,
Chris@595 175 defaultChannel);
Chris@205 176 }
Chris@205 177
Chris@205 178 dialog->setOutputLabel(outputLabel, outputDescription);
Chris@205 179
Chris@205 180 dialog->setShowProcessingOptions(true, frequency);
Chris@205 181
Chris@205 182 if (dialog->exec() == QDialog::Accepted) {
Chris@595 183 ok = true;
Chris@205 184 }
Chris@205 185
Chris@205 186 QString selectedInput = dialog->getInputModel();
Chris@205 187 if (selectedInput != "") {
Chris@595 188 if (modelMap.contains(selectedInput)) {
Chris@595 189 inputModel = modelMap.value(selectedInput);
Chris@595 190 SVDEBUG << "Found selected input \"" << selectedInput << "\" in model map, result is " << inputModel << endl;
Chris@595 191 } else {
Chris@595 192 SVDEBUG << "Failed to find selected input \"" << selectedInput << "\" in model map" << endl;
Chris@595 193 }
Chris@205 194 } else {
Chris@595 195 SVDEBUG << "Selected input empty: \"" << selectedInput << "\"" << endl;
Chris@205 196 }
Chris@205 197
Chris@205 198 // Write parameters back to transform object
Chris@205 199 TransformFactory::getInstance()->
Chris@595 200 setParametersFromPlugin(transform, plugin);
Chris@205 201
Chris@205 202 input.setChannel(dialog->getChannel());
Chris@205 203
Chris@205 204 //!!! The dialog ought to be taking & returning transform
Chris@205 205 //objects and input objects and stuff rather than passing
Chris@205 206 //around all this misc stuff, but that's for tomorrow
Chris@205 207 //(whenever that may be)
Chris@205 208
Chris@685 209 sv_samplerate_t sampleRate = 0;
Chris@685 210 if (auto m = ModelById::get(inputModel)) {
Chris@685 211 sampleRate = m->getSampleRate();
Chris@685 212 }
Chris@685 213
Chris@205 214 if (startFrame != 0 || duration != 0) {
Chris@685 215 if (dialog->getSelectionOnly() && sampleRate != 0) {
Chris@685 216 transform.setStartTime
Chris@685 217 (RealTime::frame2RealTime(startFrame, sampleRate));
Chris@685 218 transform.setDuration
Chris@685 219 (RealTime::frame2RealTime(duration, sampleRate));
Chris@595 220 }
Chris@205 221 }
Chris@205 222
Chris@366 223 int stepSize = 0, blockSize = 0;
Chris@205 224 WindowType windowType = HanningWindow;
Chris@205 225
Chris@205 226 dialog->getProcessingParameters(stepSize,
Chris@595 227 blockSize,
Chris@595 228 windowType);
Chris@205 229
Chris@205 230 transform.setStepSize(stepSize);
Chris@205 231 transform.setBlockSize(blockSize);
Chris@205 232 transform.setWindowType(windowType);
Chris@205 233
Chris@205 234 delete dialog;
Chris@205 235
Chris@205 236 if (effect && source) {
Chris@739 237 source->setAuditioningEffect({});
Chris@205 238 }
Chris@205 239
Chris@205 240 return ok;
Chris@205 241 }
Chris@205 242