annotate framework/TransformUserConfigurator.cpp @ 588:d122d3595a32

Store aggregate models in the document and release them when they are invalidated (because their components have been released). They're no longer leaked, but we still don't save them in the session file.
author Chris Cannam
date Mon, 27 Feb 2017 16:26:37 +0000
parents 36aa947ec962
children b23bebfdfaba
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@536 48 SVDEBUG << "TransformUserConfigurator::getChannelRange: is a Vamp plugin" << 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@536 53 SVDEBUG << "TransformUserConfigurator::getChannelRange: is not a Vamp plugin" << 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@536 83 SVDEBUG << "TransformUserConfigurator::configure: identifier " << id << endl;
Chris@536 84
Chris@529 85 if (RealTimePluginFactory::instanceFor(id)) {
Chris@205 86
Chris@205 87 RealTimePluginFactory *factory = RealTimePluginFactory::instanceFor(id);
Chris@205 88 const RealTimePluginDescriptor *desc = factory->getPluginDescriptor(id);
Chris@205 89
Chris@205 90 if (desc->audioInputPortCount > 0 &&
Chris@205 91 desc->audioOutputPortCount > 0 &&
Chris@205 92 !desc->isSynth) {
Chris@205 93 effect = true;
Chris@205 94 }
Chris@205 95
Chris@205 96 if (desc->audioInputPortCount == 0) {
Chris@205 97 generator = true;
Chris@205 98 }
Chris@205 99
Chris@205 100 if (output != "A") {
Chris@205 101 int outputNo = output.toInt();
Chris@205 102 if (outputNo >= 0 && outputNo < int(desc->controlOutputPortCount)) {
Chris@205 103 outputLabel = desc->controlOutputPortNames[outputNo].c_str();
Chris@205 104 }
Chris@205 105 }
Chris@205 106
Chris@205 107 RealTimePluginInstance *rtp =
Chris@205 108 static_cast<RealTimePluginInstance *>(plugin);
Chris@205 109
Chris@205 110 if (effect && source) {
Chris@233 111 SVDEBUG << "Setting auditioning effect" << endl;
Chris@205 112 source->setAuditioningEffect(rtp);
Chris@205 113 }
Chris@529 114
Chris@529 115 } else {
Chris@529 116
Chris@529 117 Vamp::Plugin *vp = static_cast<Vamp::Plugin *>(plugin);
Chris@529 118
Chris@529 119 frequency = (vp->getInputDomain() == Vamp::Plugin::FrequencyDomain);
Chris@529 120
Chris@529 121 std::vector<Vamp::Plugin::OutputDescriptor> od =
Chris@529 122 vp->getOutputDescriptors();
Chris@529 123
Chris@536 124 // cerr << "configure: looking for output: " << output << endl;
Chris@529 125
Chris@529 126 if (od.size() > 1) {
Chris@529 127 for (size_t i = 0; i < od.size(); ++i) {
Chris@529 128 if (od[i].identifier == output.toStdString()) {
Chris@529 129 outputLabel = od[i].name.c_str();
Chris@529 130 outputDescription = od[i].description.c_str();
Chris@529 131 break;
Chris@529 132 }
Chris@529 133 }
Chris@529 134 }
Chris@205 135 }
Chris@529 136
Chris@205 137 int sourceChannels = 1;
Chris@205 138 if (dynamic_cast<DenseTimeValueModel *>(inputModel)) {
Chris@205 139 sourceChannels = dynamic_cast<DenseTimeValueModel *>(inputModel)
Chris@205 140 ->getChannelCount();
Chris@205 141 }
Chris@205 142
Chris@205 143 int minChannels = 1, maxChannels = sourceChannels;
Chris@205 144 getChannelRange(transform.getIdentifier(), plugin,
Chris@205 145 minChannels, maxChannels);
Chris@205 146
Chris@205 147 int targetChannels = sourceChannels;
Chris@205 148 if (!effect) {
Chris@205 149 if (sourceChannels < minChannels) targetChannels = minChannels;
Chris@205 150 if (sourceChannels > maxChannels) targetChannels = maxChannels;
Chris@205 151 }
Chris@205 152
Chris@205 153 int defaultChannel = -1; //!!! no longer saved! [was context.channel]
Chris@205 154
Chris@395 155 PluginParameterDialog *dialog = new PluginParameterDialog
Chris@395 156 (plugin, parentWidget);
Chris@205 157
Chris@205 158 dialog->setMoreInfoUrl(TransformFactory::getInstance()->
Chris@205 159 getTransformInfoUrl(transform.getIdentifier()));
Chris@205 160
Chris@205 161 if (candidateModelNames.size() > 1 && !generator) {
Chris@205 162 dialog->setCandidateInputModels(candidateModelNames,
Chris@205 163 defaultModelName);
Chris@205 164 }
Chris@205 165
Chris@205 166 if (startFrame != 0 || duration != 0) {
Chris@205 167 dialog->setShowSelectionOnlyOption(true);
Chris@205 168 }
Chris@205 169
Chris@205 170 if (targetChannels > 0) {
Chris@205 171 dialog->setChannelArrangement(sourceChannels, targetChannels,
Chris@205 172 defaultChannel);
Chris@205 173 }
Chris@205 174
Chris@205 175 dialog->setOutputLabel(outputLabel, outputDescription);
Chris@205 176
Chris@205 177 dialog->setShowProcessingOptions(true, frequency);
Chris@205 178
Chris@205 179 if (dialog->exec() == QDialog::Accepted) {
Chris@205 180 ok = true;
Chris@205 181 }
Chris@205 182
Chris@205 183 QString selectedInput = dialog->getInputModel();
Chris@205 184 if (selectedInput != "") {
Chris@205 185 if (modelMap.contains(selectedInput)) {
Chris@205 186 inputModel = modelMap.value(selectedInput);
Chris@536 187 SVDEBUG << "Found selected input \"" << selectedInput << "\" in model map, result is " << inputModel << endl;
Chris@205 188 } else {
Chris@536 189 SVDEBUG << "Failed to find selected input \"" << selectedInput << "\" in model map" << endl;
Chris@205 190 }
Chris@205 191 } else {
Chris@536 192 SVDEBUG << "Selected input empty: \"" << selectedInput << "\"" << endl;
Chris@205 193 }
Chris@205 194
Chris@205 195 // Write parameters back to transform object
Chris@205 196 TransformFactory::getInstance()->
Chris@205 197 setParametersFromPlugin(transform, plugin);
Chris@205 198
Chris@205 199 input.setChannel(dialog->getChannel());
Chris@205 200
Chris@205 201 //!!! The dialog ought to be taking & returning transform
Chris@205 202 //objects and input objects and stuff rather than passing
Chris@205 203 //around all this misc stuff, but that's for tomorrow
Chris@205 204 //(whenever that may be)
Chris@205 205
Chris@205 206 if (startFrame != 0 || duration != 0) {
Chris@205 207 if (dialog->getSelectionOnly()) {
Chris@205 208 transform.setStartTime(RealTime::frame2RealTime
Chris@205 209 (startFrame, inputModel->getSampleRate()));
Chris@205 210 transform.setDuration(RealTime::frame2RealTime
Chris@205 211 (duration, inputModel->getSampleRate()));
Chris@205 212 }
Chris@205 213 }
Chris@205 214
Chris@366 215 int stepSize = 0, blockSize = 0;
Chris@205 216 WindowType windowType = HanningWindow;
Chris@205 217
Chris@205 218 dialog->getProcessingParameters(stepSize,
Chris@205 219 blockSize,
Chris@205 220 windowType);
Chris@205 221
Chris@205 222 transform.setStepSize(stepSize);
Chris@205 223 transform.setBlockSize(blockSize);
Chris@205 224 transform.setWindowType(windowType);
Chris@205 225
Chris@205 226 delete dialog;
Chris@205 227
Chris@205 228 if (effect && source) {
Chris@205 229 source->setAuditioningEffect(0);
Chris@205 230 }
Chris@205 231
Chris@205 232 return ok;
Chris@205 233 }
Chris@205 234