annotate framework/TransformUserConfigurator.cpp @ 530:066d8c5f3b21 project-file-rework

Cut down vastly on the number of config.pri files and places where their contents has to be effectively duplicated without them
author Chris Cannam
date Mon, 24 Oct 2016 17:53:33 +0100
parents 167fe01d5631
children 7a3fa603190e
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@395 33 static QWidget *parentWidget = 0;
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@205 43 Vamp::PluginBase *plugin,
Chris@205 44 int &minChannels, int &maxChannels)
Chris@205 45 {
Chris@205 46 if (plugin && plugin->getType() == "Feature Extraction Plugin") {
Chris@205 47 Vamp::Plugin *vp = static_cast<Vamp::Plugin *>(plugin);
Chris@233 48 SVDEBUG << "TransformUserConfigurator::getChannelRange: is a VP" << endl;
Chris@436 49 minChannels = int(vp->getMinChannelCount());
Chris@436 50 maxChannels = int(vp->getMaxChannelCount());
Chris@205 51 return true;
Chris@205 52 } else {
Chris@233 53 SVDEBUG << "TransformUserConfigurator::getChannelRange: is not a VP" << endl;
Chris@205 54 return TransformFactory::getInstance()->
Chris@205 55 getTransformChannelRange(identifier, minChannels, maxChannels);
Chris@205 56 }
Chris@205 57 }
Chris@205 58
Chris@205 59 bool
Chris@205 60 TransformUserConfigurator::configure(ModelTransformer::Input &input,
Chris@205 61 Transform &transform,
Chris@205 62 Vamp::PluginBase *plugin,
Chris@214 63 Model *&inputModel,
Chris@205 64 AudioPlaySource *source,
Chris@437 65 sv_frame_t startFrame,
Chris@437 66 sv_frame_t duration,
Chris@205 67 const QMap<QString, Model *> &modelMap,
Chris@205 68 QStringList candidateModelNames,
Chris@205 69 QString defaultModelName)
Chris@205 70 {
Chris@205 71 bool ok = false;
Chris@205 72 QString id = transform.getPluginIdentifier();
Chris@205 73 QString output = transform.getOutput();
Chris@205 74 QString outputLabel = "";
Chris@205 75 QString outputDescription = "";
Chris@205 76
Chris@205 77 bool frequency = false;
Chris@205 78 bool effect = false;
Chris@205 79 bool generator = false;
Chris@205 80
Chris@205 81 if (!plugin) return false;
Chris@205 82
Chris@205 83 if (FeatureExtractionPluginFactory::instanceFor(id)) {
Chris@205 84
Chris@205 85 Vamp::Plugin *vp = static_cast<Vamp::Plugin *>(plugin);
Chris@205 86
Chris@205 87 frequency = (vp->getInputDomain() == Vamp::Plugin::FrequencyDomain);
Chris@205 88
Chris@205 89 std::vector<Vamp::Plugin::OutputDescriptor> od =
Chris@205 90 vp->getOutputDescriptors();
Chris@205 91
Chris@293 92 cerr << "configure: looking for output: " << output << endl;
Chris@205 93
Chris@205 94 if (od.size() > 1) {
Chris@205 95 for (size_t i = 0; i < od.size(); ++i) {
Chris@205 96 if (od[i].identifier == output.toStdString()) {
Chris@205 97 outputLabel = od[i].name.c_str();
Chris@205 98 outputDescription = od[i].description.c_str();
Chris@205 99 break;
Chris@205 100 }
Chris@205 101 }
Chris@205 102 }
Chris@205 103
Chris@205 104 } else if (RealTimePluginFactory::instanceFor(id)) {
Chris@205 105
Chris@205 106 RealTimePluginFactory *factory = RealTimePluginFactory::instanceFor(id);
Chris@205 107 const RealTimePluginDescriptor *desc = factory->getPluginDescriptor(id);
Chris@205 108
Chris@205 109 if (desc->audioInputPortCount > 0 &&
Chris@205 110 desc->audioOutputPortCount > 0 &&
Chris@205 111 !desc->isSynth) {
Chris@205 112 effect = true;
Chris@205 113 }
Chris@205 114
Chris@205 115 if (desc->audioInputPortCount == 0) {
Chris@205 116 generator = true;
Chris@205 117 }
Chris@205 118
Chris@205 119 if (output != "A") {
Chris@205 120 int outputNo = output.toInt();
Chris@205 121 if (outputNo >= 0 && outputNo < int(desc->controlOutputPortCount)) {
Chris@205 122 outputLabel = desc->controlOutputPortNames[outputNo].c_str();
Chris@205 123 }
Chris@205 124 }
Chris@205 125
Chris@205 126 RealTimePluginInstance *rtp =
Chris@205 127 static_cast<RealTimePluginInstance *>(plugin);
Chris@205 128
Chris@205 129 if (effect && source) {
Chris@233 130 SVDEBUG << "Setting auditioning effect" << endl;
Chris@205 131 source->setAuditioningEffect(rtp);
Chris@205 132 }
Chris@205 133 }
Chris@205 134
Chris@205 135 int sourceChannels = 1;
Chris@205 136 if (dynamic_cast<DenseTimeValueModel *>(inputModel)) {
Chris@205 137 sourceChannels = dynamic_cast<DenseTimeValueModel *>(inputModel)
Chris@205 138 ->getChannelCount();
Chris@205 139 }
Chris@205 140
Chris@205 141 int minChannels = 1, maxChannels = sourceChannels;
Chris@205 142 getChannelRange(transform.getIdentifier(), plugin,
Chris@205 143 minChannels, maxChannels);
Chris@205 144
Chris@205 145 int targetChannels = sourceChannels;
Chris@205 146 if (!effect) {
Chris@205 147 if (sourceChannels < minChannels) targetChannels = minChannels;
Chris@205 148 if (sourceChannels > maxChannels) targetChannels = maxChannels;
Chris@205 149 }
Chris@205 150
Chris@205 151 int defaultChannel = -1; //!!! no longer saved! [was context.channel]
Chris@205 152
Chris@395 153 PluginParameterDialog *dialog = new PluginParameterDialog
Chris@395 154 (plugin, parentWidget);
Chris@205 155
Chris@205 156 dialog->setMoreInfoUrl(TransformFactory::getInstance()->
Chris@205 157 getTransformInfoUrl(transform.getIdentifier()));
Chris@205 158
Chris@205 159 if (candidateModelNames.size() > 1 && !generator) {
Chris@205 160 dialog->setCandidateInputModels(candidateModelNames,
Chris@205 161 defaultModelName);
Chris@205 162 }
Chris@205 163
Chris@205 164 if (startFrame != 0 || duration != 0) {
Chris@205 165 dialog->setShowSelectionOnlyOption(true);
Chris@205 166 }
Chris@205 167
Chris@205 168 if (targetChannels > 0) {
Chris@205 169 dialog->setChannelArrangement(sourceChannels, targetChannels,
Chris@205 170 defaultChannel);
Chris@205 171 }
Chris@205 172
Chris@205 173 dialog->setOutputLabel(outputLabel, outputDescription);
Chris@205 174
Chris@205 175 dialog->setShowProcessingOptions(true, frequency);
Chris@205 176
Chris@205 177 if (dialog->exec() == QDialog::Accepted) {
Chris@205 178 ok = true;
Chris@205 179 }
Chris@205 180
Chris@205 181 QString selectedInput = dialog->getInputModel();
Chris@205 182 if (selectedInput != "") {
Chris@205 183 if (modelMap.contains(selectedInput)) {
Chris@205 184 inputModel = modelMap.value(selectedInput);
Chris@293 185 cerr << "Found selected input \"" << selectedInput << "\" in model map, result is " << inputModel << endl;
Chris@205 186 } else {
Chris@293 187 cerr << "Failed to find selected input \"" << selectedInput << "\" in model map" << endl;
Chris@205 188 }
Chris@205 189 } else {
Chris@293 190 cerr << "Selected input empty: \"" << selectedInput << "\"" << endl;
Chris@205 191 }
Chris@205 192
Chris@205 193 // Write parameters back to transform object
Chris@205 194 TransformFactory::getInstance()->
Chris@205 195 setParametersFromPlugin(transform, plugin);
Chris@205 196
Chris@205 197 input.setChannel(dialog->getChannel());
Chris@205 198
Chris@205 199 //!!! The dialog ought to be taking & returning transform
Chris@205 200 //objects and input objects and stuff rather than passing
Chris@205 201 //around all this misc stuff, but that's for tomorrow
Chris@205 202 //(whenever that may be)
Chris@205 203
Chris@205 204 if (startFrame != 0 || duration != 0) {
Chris@205 205 if (dialog->getSelectionOnly()) {
Chris@205 206 transform.setStartTime(RealTime::frame2RealTime
Chris@205 207 (startFrame, inputModel->getSampleRate()));
Chris@205 208 transform.setDuration(RealTime::frame2RealTime
Chris@205 209 (duration, inputModel->getSampleRate()));
Chris@205 210 }
Chris@205 211 }
Chris@205 212
Chris@366 213 int stepSize = 0, blockSize = 0;
Chris@205 214 WindowType windowType = HanningWindow;
Chris@205 215
Chris@205 216 dialog->getProcessingParameters(stepSize,
Chris@205 217 blockSize,
Chris@205 218 windowType);
Chris@205 219
Chris@205 220 transform.setStepSize(stepSize);
Chris@205 221 transform.setBlockSize(blockSize);
Chris@205 222 transform.setWindowType(windowType);
Chris@205 223
Chris@205 224 delete dialog;
Chris@205 225
Chris@205 226 if (effect && source) {
Chris@205 227 source->setAuditioningEffect(0);
Chris@205 228 }
Chris@205 229
Chris@205 230 return ok;
Chris@205 231 }
Chris@205 232