Mercurial > hg > svcore
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); |