comparison transform/ModelTransformerFactory.cpp @ 653:12578237b99c

* Move the plugin dialog configuration guff out into a callback
author Chris Cannam
date Fri, 08 Oct 2010 11:19:16 +0100
parents 5ab561f664f2
children b4a8d8221eaf
comparison
equal deleted inserted replaced
652:8676bacf228f 653:12578237b99c
24 24
25 #include "plugin/FeatureExtractionPluginFactory.h" 25 #include "plugin/FeatureExtractionPluginFactory.h"
26 #include "plugin/RealTimePluginFactory.h" 26 #include "plugin/RealTimePluginFactory.h"
27 #include "plugin/PluginXml.h" 27 #include "plugin/PluginXml.h"
28 28
29 #ifndef NO_SV_GUI
30 #include "widgets/PluginParameterDialog.h"
31 #endif
32
33 #include "data/model/DenseTimeValueModel.h" 29 #include "data/model/DenseTimeValueModel.h"
34 30
35 #include <vamp-hostsdk/PluginHostAdapter.h> 31 #include <vamp-hostsdk/PluginHostAdapter.h>
36 32
37 #include <iostream> 33 #include <iostream>
48 return m_instance; 44 return m_instance;
49 } 45 }
50 46
51 ModelTransformerFactory::~ModelTransformerFactory() 47 ModelTransformerFactory::~ModelTransformerFactory()
52 { 48 {
53 }
54
55 bool
56 ModelTransformerFactory::getChannelRange(TransformId identifier,
57 Vamp::PluginBase *plugin,
58 int &minChannels, int &maxChannels)
59 {
60 Vamp::Plugin *vp = 0;
61 if ((vp = dynamic_cast<Vamp::Plugin *>(plugin)) ||
62 (vp = dynamic_cast<Vamp::PluginHostAdapter *>(plugin))) {
63 minChannels = vp->getMinChannelCount();
64 maxChannels = vp->getMaxChannelCount();
65 return true;
66 } else {
67 return TransformFactory::getInstance()->
68 getTransformChannelRange(identifier, minChannels, maxChannels);
69 }
70 } 49 }
71 50
72 ModelTransformer::Input 51 ModelTransformer::Input
73 ModelTransformerFactory::getConfigurationForTransform(Transform &transform, 52 ModelTransformerFactory::getConfigurationForTransform(Transform &transform,
74 const std::vector<Model *> &candidateInputModels, 53 const std::vector<Model *> &candidateInputModels,
75 Model *defaultInputModel, 54 Model *defaultInputModel,
76 AudioPlaySource *source, 55 AudioPlaySource *source,
77 size_t startFrame, 56 size_t startFrame,
78 size_t duration) 57 size_t duration,
58 UserConfigurator *configurator)
79 { 59 {
80 ModelTransformer::Input input(0); 60 ModelTransformer::Input input(0);
81 61
82 if (candidateInputModels.empty()) return input; 62 if (candidateInputModels.empty()) return input;
83 63
85 //from the dialog for when the candidate input model is changed, 65 //from the dialog for when the candidate input model is changed,
86 //as we'll need to reinitialise the channel settings in the dialog 66 //as we'll need to reinitialise the channel settings in the dialog
87 Model *inputModel = candidateInputModels[0]; 67 Model *inputModel = candidateInputModels[0];
88 QStringList candidateModelNames; 68 QStringList candidateModelNames;
89 QString defaultModelName; 69 QString defaultModelName;
90 std::map<QString, Model *> modelMap; 70 QMap<QString, Model *> modelMap;
91 for (size_t i = 0; i < candidateInputModels.size(); ++i) { 71 for (size_t i = 0; i < candidateInputModels.size(); ++i) {
92 QString modelName = candidateInputModels[i]->objectName(); 72 QString modelName = candidateInputModels[i]->objectName();
93 QString origModelName = modelName; 73 QString origModelName = modelName;
94 int dupcount = 1; 74 int dupcount = 1;
95 while (modelMap.find(modelName) != modelMap.end()) { 75 while (modelMap.contains(modelName)) {
96 modelName = tr("%1 <%2>").arg(origModelName).arg(++dupcount); 76 modelName = tr("%1 <%2>").arg(origModelName).arg(++dupcount);
97 } 77 }
98 modelMap[modelName] = candidateInputModels[i]; 78 modelMap[modelName] = candidateInputModels[i];
99 candidateModelNames.push_back(modelName); 79 candidateModelNames.push_back(modelName);
100 if (candidateInputModels[i] == defaultInputModel) { 80 if (candidateInputModels[i] == defaultInputModel) {
101 defaultModelName = modelName; 81 defaultModelName = modelName;
102 } 82 }
103 } 83 }
104 84
105 QString id = transform.getPluginIdentifier(); 85 QString id = transform.getPluginIdentifier();
106 QString output = transform.getOutput();
107 QString outputLabel = "";
108 QString outputDescription = "";
109 86
110 bool ok = false; 87 bool ok = true;
111 QString configurationXml = m_lastConfigurations[transform.getIdentifier()]; 88 QString configurationXml = m_lastConfigurations[transform.getIdentifier()];
112 89
113 std::cerr << "last configuration: " << configurationXml.toStdString() << std::endl; 90 std::cerr << "last configuration: " << configurationXml.toStdString() << std::endl;
114 91
115 Vamp::PluginBase *plugin = 0; 92 Vamp::PluginBase *plugin = 0;
116
117 bool frequency = false;
118 bool effect = false;
119 bool generator = false;
120 93
121 if (FeatureExtractionPluginFactory::instanceFor(id)) { 94 if (FeatureExtractionPluginFactory::instanceFor(id)) {
122 95
123 std::cerr << "getConfigurationForTransform: instantiating Vamp plugin" << std::endl; 96 std::cerr << "getConfigurationForTransform: instantiating Vamp plugin" << std::endl;
124 97
125 Vamp::Plugin *vp = 98 Vamp::Plugin *vp =
126 FeatureExtractionPluginFactory::instanceFor(id)->instantiatePlugin 99 FeatureExtractionPluginFactory::instanceFor(id)->instantiatePlugin
127 (id, inputModel->getSampleRate()); 100 (id, inputModel->getSampleRate());
128 101
129 if (vp) { 102 plugin = vp;
130
131 plugin = vp;
132 frequency = (vp->getInputDomain() == Vamp::Plugin::FrequencyDomain);
133
134 std::vector<Vamp::Plugin::OutputDescriptor> od =
135 vp->getOutputDescriptors();
136 if (od.size() > 1) {
137 for (size_t i = 0; i < od.size(); ++i) {
138 if (od[i].identifier == output.toStdString()) {
139 outputLabel = od[i].name.c_str();
140 outputDescription = od[i].description.c_str();
141 break;
142 }
143 }
144 }
145 }
146 103
147 } else if (RealTimePluginFactory::instanceFor(id)) { 104 } else if (RealTimePluginFactory::instanceFor(id)) {
148 105
149 RealTimePluginFactory *factory = RealTimePluginFactory::instanceFor(id); 106 RealTimePluginFactory *factory = RealTimePluginFactory::instanceFor(id);
150 const RealTimePluginDescriptor *desc = factory->getPluginDescriptor(id); 107 const RealTimePluginDescriptor *desc = factory->getPluginDescriptor(id);
151
152 if (desc->audioInputPortCount > 0 &&
153 desc->audioOutputPortCount > 0 &&
154 !desc->isSynth) {
155 effect = true;
156 }
157
158 if (desc->audioInputPortCount == 0) {
159 generator = true;
160 }
161
162 if (output != "A") {
163 int outputNo = output.toInt();
164 if (outputNo >= 0 && outputNo < int(desc->controlOutputPortCount)) {
165 outputLabel = desc->controlOutputPortNames[outputNo].c_str();
166 }
167 }
168 108
169 size_t sampleRate = inputModel->getSampleRate(); 109 size_t sampleRate = inputModel->getSampleRate();
170 size_t blockSize = 1024; 110 size_t blockSize = 1024;
171 size_t channels = 1; 111 size_t channels = 1;
172 if (effect && source) { 112 if (source) {
173 sampleRate = source->getTargetSampleRate(); 113 sampleRate = source->getTargetSampleRate();
174 blockSize = source->getTargetBlockSize(); 114 blockSize = source->getTargetBlockSize();
175 channels = source->getTargetChannelCount(); 115 channels = source->getTargetChannelCount();
176 } 116 }
177 117
178 RealTimePluginInstance *rtp = factory->instantiatePlugin 118 RealTimePluginInstance *rtp = factory->instantiatePlugin
179 (id, 0, 0, sampleRate, blockSize, channels); 119 (id, 0, 0, sampleRate, blockSize, channels);
180 120
181 plugin = rtp; 121 plugin = rtp;
182
183 if (effect && source && rtp) {
184 source->setAuditioningEffect(rtp);
185 }
186 } 122 }
187 123
188 if (plugin) { 124 if (plugin) {
189 125
190 // Ensure block size etc are valid 126 // Ensure block size etc are valid
198 134
199 // For this interactive usage, we want to override those with 135 // For this interactive usage, we want to override those with
200 // whatever the user chose last time around 136 // whatever the user chose last time around
201 PluginXml(plugin).setParametersFromXml(configurationXml); 137 PluginXml(plugin).setParametersFromXml(configurationXml);
202 138
203 #ifndef NO_SV_GUI 139 if (configurator) {
204 int sourceChannels = 1; 140 ok = configurator->configure(input, transform, plugin,
205 if (dynamic_cast<DenseTimeValueModel *>(inputModel)) { 141 inputModel, source,
206 sourceChannels = dynamic_cast<DenseTimeValueModel *>(inputModel) 142 startFrame, duration,
207 ->getChannelCount(); 143 modelMap,
208 } 144 candidateModelNames,
209 145 defaultModelName);
210 int minChannels = 1, maxChannels = sourceChannels;
211 getChannelRange(transform.getIdentifier(), plugin,
212 minChannels, maxChannels);
213
214 int targetChannels = sourceChannels;
215 if (!effect) {
216 if (sourceChannels < minChannels) targetChannels = minChannels;
217 if (sourceChannels > maxChannels) targetChannels = maxChannels;
218 }
219
220 int defaultChannel = -1; //!!! no longer saved! [was context.channel]
221
222 PluginParameterDialog *dialog = new PluginParameterDialog(plugin);
223
224 dialog->setMoreInfoUrl(TransformFactory::getInstance()->
225 getTransformInfoUrl(transform.getIdentifier()));
226
227 if (candidateModelNames.size() > 1 && !generator) {
228 dialog->setCandidateInputModels(candidateModelNames,
229 defaultModelName);
230 }
231
232 if (startFrame != 0 || duration != 0) {
233 dialog->setShowSelectionOnlyOption(true);
234 }
235
236 if (targetChannels > 0) {
237 dialog->setChannelArrangement(sourceChannels, targetChannels,
238 defaultChannel);
239 } 146 }
240 147
241 dialog->setOutputLabel(outputLabel, outputDescription);
242
243 dialog->setShowProcessingOptions(true, frequency);
244
245 if (dialog->exec() == QDialog::Accepted) {
246 ok = true;
247 }
248
249 QString selectedInput = dialog->getInputModel();
250 if (selectedInput != "") {
251 if (modelMap.find(selectedInput) != modelMap.end()) {
252 inputModel = modelMap[selectedInput];
253 std::cerr << "Found selected input \"" << selectedInput.toStdString() << "\" in model map, result is " << inputModel << std::endl;
254 } else {
255 std::cerr << "Failed to find selected input \"" << selectedInput.toStdString() << "\" in model map" << std::endl;
256 }
257 } else {
258 std::cerr << "Selected input empty: \"" << selectedInput.toStdString() << "\"" << std::endl;
259 }
260
261 // Write parameters back to transform object
262 TransformFactory::getInstance()->
263 setParametersFromPlugin(transform, plugin);
264
265 input.setChannel(dialog->getChannel());
266
267 //!!! The dialog ought to be taking & returning transform
268 //objects and input objects and stuff rather than passing
269 //around all this misc stuff, but that's for tomorrow
270 //(whenever that may be)
271
272 if (startFrame != 0 || duration != 0) {
273 if (dialog->getSelectionOnly()) {
274 transform.setStartTime(RealTime::frame2RealTime
275 (startFrame, inputModel->getSampleRate()));
276 transform.setDuration(RealTime::frame2RealTime
277 (duration, inputModel->getSampleRate()));
278 }
279 }
280
281 size_t stepSize = 0, blockSize = 0;
282 WindowType windowType = HanningWindow;
283
284 dialog->getProcessingParameters(stepSize,
285 blockSize,
286 windowType);
287
288 transform.setStepSize(stepSize);
289 transform.setBlockSize(blockSize);
290 transform.setWindowType(windowType);
291
292 #endif
293 148
294 TransformFactory::getInstance()-> 149 TransformFactory::getInstance()->
295 makeContextConsistentWithPlugin(transform, plugin); 150 makeContextConsistentWithPlugin(transform, plugin);
296 151
297 configurationXml = PluginXml(plugin).toXmlString(); 152 configurationXml = PluginXml(plugin).toXmlString();
298 153
299 #ifndef NO_SV_GUI 154 delete plugin;
300 delete dialog;
301 #endif
302
303 if (effect && source) {
304 source->setAuditioningEffect(0); // will delete our plugin
305 } else {
306 delete plugin;
307 }
308 } 155 }
309 156
310 if (ok) { 157 if (ok) {
311 m_lastConfigurations[transform.getIdentifier()] = configurationXml; 158 m_lastConfigurations[transform.getIdentifier()] = configurationXml;
312 input.setModel(inputModel); 159 input.setModel(inputModel);