annotate framework/TransformUserConfigurator.cpp @ 332:151b7c5864e3 tonioni

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