comparison framework/TransformUserConfigurator.cpp @ 205:a3fbd52031a5

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