Mercurial > hg > svcore
comparison plugin/transform/ModelTransformerFactory.cpp @ 350:d7c41483af8f
* Merge from transforms branch -- switch over to using Transform object
properly
author | Chris Cannam |
---|---|
date | Fri, 07 Dec 2007 16:47:31 +0000 |
parents | 700cd3350391 |
children | 399ea254afd6 |
comparison
equal
deleted
inserted
replaced
348:edda24bb85fc | 350:d7c41483af8f |
---|---|
49 ModelTransformerFactory::~ModelTransformerFactory() | 49 ModelTransformerFactory::~ModelTransformerFactory() |
50 { | 50 { |
51 } | 51 } |
52 | 52 |
53 bool | 53 bool |
54 ModelTransformerFactory::getChannelRange(TransformId identifier, Vamp::PluginBase *plugin, | 54 ModelTransformerFactory::getChannelRange(TransformId identifier, |
55 Vamp::PluginBase *plugin, | |
55 int &minChannels, int &maxChannels) | 56 int &minChannels, int &maxChannels) |
56 { | 57 { |
57 Vamp::Plugin *vp = 0; | 58 Vamp::Plugin *vp = 0; |
58 if ((vp = dynamic_cast<Vamp::Plugin *>(plugin)) || | 59 if ((vp = dynamic_cast<Vamp::Plugin *>(plugin)) || |
59 (vp = dynamic_cast<Vamp::PluginHostAdapter *>(plugin))) { | 60 (vp = dynamic_cast<Vamp::PluginHostAdapter *>(plugin))) { |
64 return TransformFactory::getInstance()-> | 65 return TransformFactory::getInstance()-> |
65 getTransformChannelRange(identifier, minChannels, maxChannels); | 66 getTransformChannelRange(identifier, minChannels, maxChannels); |
66 } | 67 } |
67 } | 68 } |
68 | 69 |
69 Model * | 70 ModelTransformer::Input |
70 ModelTransformerFactory::getConfigurationForTransformer(TransformId identifier, | 71 ModelTransformerFactory::getConfigurationForTransform(Transform &transform, |
71 const std::vector<Model *> &candidateInputModels, | 72 const std::vector<Model *> &candidateInputModels, |
72 Model *defaultInputModel, | 73 Model *defaultInputModel, |
73 PluginTransformer::ExecutionContext &context, | 74 AudioCallbackPlaySource *source, |
74 QString &configurationXml, | 75 size_t startFrame, |
75 AudioCallbackPlaySource *source, | 76 size_t duration) |
76 size_t startFrame, | 77 { |
77 size_t duration) | 78 ModelTransformer::Input input(0); |
78 { | 79 |
79 if (candidateInputModels.empty()) return 0; | 80 if (candidateInputModels.empty()) return input; |
80 | 81 |
81 //!!! This will need revision -- we'll have to have a callback | 82 //!!! This will need revision -- we'll have to have a callback |
82 //from the dialog for when the candidate input model is changed, | 83 //from the dialog for when the candidate input model is changed, |
83 //as we'll need to reinitialise the channel settings in the dialog | 84 //as we'll need to reinitialise the channel settings in the dialog |
84 Model *inputModel = candidateInputModels[0]; | 85 Model *inputModel = candidateInputModels[0]; |
97 if (candidateInputModels[i] == defaultInputModel) { | 98 if (candidateInputModels[i] == defaultInputModel) { |
98 defaultModelName = modelName; | 99 defaultModelName = modelName; |
99 } | 100 } |
100 } | 101 } |
101 | 102 |
102 QString id = identifier.section(':', 0, 2); | 103 QString id = transform.getPluginIdentifier(); |
103 QString output = identifier.section(':', 3); | 104 QString output = transform.getOutput(); |
104 QString outputLabel = ""; | 105 QString outputLabel = ""; |
105 QString outputDescription = ""; | 106 QString outputDescription = ""; |
106 | 107 |
107 bool ok = false; | 108 bool ok = false; |
108 configurationXml = m_lastConfigurations[identifier]; | 109 QString configurationXml = m_lastConfigurations[transform.getIdentifier()]; |
109 | 110 |
110 // std::cerr << "last configuration: " << configurationXml.toStdString() << std::endl; | 111 std::cerr << "last configuration: " << configurationXml.toStdString() << std::endl; |
111 | 112 |
112 Vamp::PluginBase *plugin = 0; | 113 Vamp::PluginBase *plugin = 0; |
113 | 114 |
114 bool frequency = false; | 115 bool frequency = false; |
115 bool effect = false; | 116 bool effect = false; |
116 bool generator = false; | 117 bool generator = false; |
117 | 118 |
118 if (FeatureExtractionPluginFactory::instanceFor(id)) { | 119 if (FeatureExtractionPluginFactory::instanceFor(id)) { |
119 | 120 |
120 std::cerr << "getConfigurationForTransformer: instantiating Vamp plugin" << std::endl; | 121 std::cerr << "getConfigurationForTransform: instantiating Vamp plugin" << std::endl; |
121 | 122 |
122 Vamp::Plugin *vp = | 123 Vamp::Plugin *vp = |
123 FeatureExtractionPluginFactory::instanceFor(id)->instantiatePlugin | 124 FeatureExtractionPluginFactory::instanceFor(id)->instantiatePlugin |
124 (id, inputModel->getSampleRate()); | 125 (id, inputModel->getSampleRate()); |
125 | 126 |
182 } | 183 } |
183 } | 184 } |
184 | 185 |
185 if (plugin) { | 186 if (plugin) { |
186 | 187 |
187 context = PluginTransformer::ExecutionContext(context.channel, plugin); | 188 // Ensure block size etc are valid |
188 | 189 TransformFactory::getInstance()-> |
189 if (configurationXml != "") { | 190 makeContextConsistentWithPlugin(transform, plugin); |
190 PluginXml(plugin).setParametersFromXml(configurationXml); | 191 |
191 } | 192 // Prepare the plugin with any existing parameters already |
193 // found in the transform | |
194 TransformFactory::getInstance()-> | |
195 setPluginParameters(transform, plugin); | |
196 | |
197 // For this interactive usage, we want to override those with | |
198 // whatever the user chose last time around | |
199 PluginXml(plugin).setParametersFromXml(configurationXml); | |
192 | 200 |
193 int sourceChannels = 1; | 201 int sourceChannels = 1; |
194 if (dynamic_cast<DenseTimeValueModel *>(inputModel)) { | 202 if (dynamic_cast<DenseTimeValueModel *>(inputModel)) { |
195 sourceChannels = dynamic_cast<DenseTimeValueModel *>(inputModel) | 203 sourceChannels = dynamic_cast<DenseTimeValueModel *>(inputModel) |
196 ->getChannelCount(); | 204 ->getChannelCount(); |
197 } | 205 } |
198 | 206 |
199 int minChannels = 1, maxChannels = sourceChannels; | 207 int minChannels = 1, maxChannels = sourceChannels; |
200 getChannelRange(identifier, plugin, minChannels, maxChannels); | 208 getChannelRange(transform.getIdentifier(), plugin, |
209 minChannels, maxChannels); | |
201 | 210 |
202 int targetChannels = sourceChannels; | 211 int targetChannels = sourceChannels; |
203 if (!effect) { | 212 if (!effect) { |
204 if (sourceChannels < minChannels) targetChannels = minChannels; | 213 if (sourceChannels < minChannels) targetChannels = minChannels; |
205 if (sourceChannels > maxChannels) targetChannels = maxChannels; | 214 if (sourceChannels > maxChannels) targetChannels = maxChannels; |
206 } | 215 } |
207 | 216 |
208 int defaultChannel = context.channel; | 217 int defaultChannel = -1; //!!! no longer saved! [was context.channel] |
209 | 218 |
210 PluginParameterDialog *dialog = new PluginParameterDialog(plugin); | 219 PluginParameterDialog *dialog = new PluginParameterDialog(plugin); |
211 | 220 |
212 if (candidateModelNames.size() > 1 && !generator) { | 221 if (candidateModelNames.size() > 1 && !generator) { |
213 dialog->setCandidateInputModels(candidateModelNames, | 222 dialog->setCandidateInputModels(candidateModelNames, |
240 std::cerr << "Failed to find selected input \"" << selectedInput.toStdString() << "\" in model map" << std::endl; | 249 std::cerr << "Failed to find selected input \"" << selectedInput.toStdString() << "\" in model map" << std::endl; |
241 } | 250 } |
242 } else { | 251 } else { |
243 std::cerr << "Selected input empty: \"" << selectedInput.toStdString() << "\"" << std::endl; | 252 std::cerr << "Selected input empty: \"" << selectedInput.toStdString() << "\"" << std::endl; |
244 } | 253 } |
245 | |
246 configurationXml = PluginXml(plugin).toXmlString(); | |
247 context.channel = dialog->getChannel(); | |
248 | 254 |
255 // Write parameters back to transform object | |
256 TransformFactory::getInstance()-> | |
257 setParametersFromPlugin(transform, plugin); | |
258 | |
259 input.setChannel(dialog->getChannel()); | |
260 | |
261 //!!! The dialog ought to be taking & returning transform | |
262 //objects and input objects and stuff rather than passing | |
263 //around all this misc stuff, but that's for tomorrow | |
264 //(whenever that may be) | |
265 | |
249 if (startFrame != 0 || duration != 0) { | 266 if (startFrame != 0 || duration != 0) { |
250 if (dialog->getSelectionOnly()) { | 267 if (dialog->getSelectionOnly()) { |
251 context.startFrame = startFrame; | 268 transform.setStartTime(RealTime::frame2RealTime |
252 context.duration = duration; | 269 (startFrame, inputModel->getSampleRate())); |
270 transform.setDuration(RealTime::frame2RealTime | |
271 (duration, inputModel->getSampleRate())); | |
253 } | 272 } |
254 } | 273 } |
255 | 274 |
256 dialog->getProcessingParameters(context.stepSize, | 275 size_t stepSize = 0, blockSize = 0; |
257 context.blockSize, | 276 WindowType windowType = HanningWindow; |
258 context.windowType); | 277 |
259 | 278 dialog->getProcessingParameters(stepSize, |
260 context.makeConsistentWithPlugin(plugin); | 279 blockSize, |
280 windowType); | |
281 | |
282 transform.setStepSize(stepSize); | |
283 transform.setBlockSize(blockSize); | |
284 transform.setWindowType(windowType); | |
285 | |
286 TransformFactory::getInstance()-> | |
287 makeContextConsistentWithPlugin(transform, plugin); | |
288 | |
289 configurationXml = PluginXml(plugin).toXmlString(); | |
261 | 290 |
262 delete dialog; | 291 delete dialog; |
263 | 292 |
264 if (effect && source) { | 293 if (effect && source) { |
265 source->setAuditioningPlugin(0); // will delete our plugin | 294 source->setAuditioningPlugin(0); // will delete our plugin |
266 } else { | 295 } else { |
267 delete plugin; | 296 delete plugin; |
268 } | 297 } |
269 } | 298 } |
270 | 299 |
271 if (ok) m_lastConfigurations[identifier] = configurationXml; | 300 if (ok) { |
272 | 301 m_lastConfigurations[transform.getIdentifier()] = configurationXml; |
273 return ok ? inputModel : 0; | 302 input.setModel(inputModel); |
274 } | 303 } |
275 | 304 |
305 return input; | |
306 } | |
307 /*!!! | |
276 PluginTransformer::ExecutionContext | 308 PluginTransformer::ExecutionContext |
277 ModelTransformerFactory::getDefaultContextForTransformer(TransformId identifier, | 309 ModelTransformerFactory::getDefaultContextForTransformer(TransformId identifier, |
278 Model *inputModel) | 310 Model *inputModel) |
279 { | 311 { |
280 PluginTransformer::ExecutionContext context(-1); | 312 PluginTransformer::ExecutionContext context(-1); |
293 } | 325 } |
294 } | 326 } |
295 | 327 |
296 return context; | 328 return context; |
297 } | 329 } |
298 | 330 */ |
299 ModelTransformer * | 331 ModelTransformer * |
300 ModelTransformerFactory::createTransformer(TransformId identifier, Model *inputModel, | 332 ModelTransformerFactory::createTransformer(const Transform &transform, |
301 const PluginTransformer::ExecutionContext &context, | 333 const ModelTransformer::Input &input) |
302 QString configurationXml) | |
303 { | 334 { |
304 ModelTransformer *transformer = 0; | 335 ModelTransformer *transformer = 0; |
305 | 336 |
306 QString id = identifier.section(':', 0, 2); | 337 QString id = transform.getPluginIdentifier(); |
307 QString output = identifier.section(':', 3); | |
308 | 338 |
309 if (FeatureExtractionPluginFactory::instanceFor(id)) { | 339 if (FeatureExtractionPluginFactory::instanceFor(id)) { |
310 transformer = new FeatureExtractionModelTransformer | 340 |
311 (inputModel, id, context, configurationXml, output); | 341 transformer = |
342 new FeatureExtractionModelTransformer(input, transform); | |
343 | |
312 } else if (RealTimePluginFactory::instanceFor(id)) { | 344 } else if (RealTimePluginFactory::instanceFor(id)) { |
313 transformer = new RealTimeEffectModelTransformer | 345 |
314 (inputModel, id, context, configurationXml, | 346 transformer = |
315 TransformFactory::getInstance()->getTransformUnits(identifier), | 347 new RealTimeEffectModelTransformer(input, transform); |
316 output == "A" ? -1 : output.toInt()); | 348 |
317 } else { | 349 } else { |
318 std::cerr << "ModelTransformerFactory::createTransformer: Unknown transform \"" | 350 std::cerr << "ModelTransformerFactory::createTransformer: Unknown transform \"" |
319 << identifier.toStdString() << "\"" << std::endl; | 351 << transform.getIdentifier().toStdString() << "\"" << std::endl; |
320 return transformer; | 352 return transformer; |
321 } | 353 } |
322 | 354 |
323 if (transformer) transformer->setObjectName(identifier); | 355 if (transformer) transformer->setObjectName(transform.getIdentifier()); |
324 return transformer; | 356 return transformer; |
325 } | 357 } |
326 | 358 |
327 Model * | 359 Model * |
328 ModelTransformerFactory::transform(TransformId identifier, Model *inputModel, | 360 ModelTransformerFactory::transform(const Transform &transform, |
329 const PluginTransformer::ExecutionContext &context, | 361 const ModelTransformer::Input &input) |
330 QString configurationXml) | 362 { |
331 { | 363 ModelTransformer *t = createTransformer(transform, input); |
332 ModelTransformer *t = createTransformer(identifier, inputModel, context, | |
333 configurationXml); | |
334 | |
335 if (!t) return 0; | 364 if (!t) return 0; |
336 | 365 |
337 connect(t, SIGNAL(finished()), this, SLOT(transformerFinished())); | 366 connect(t, SIGNAL(finished()), this, SLOT(transformerFinished())); |
338 | 367 |
339 m_runningTransformers.insert(t); | 368 m_runningTransformers.insert(t); |
340 | 369 |
341 t->start(); | 370 t->start(); |
342 Model *model = t->detachOutputModel(); | 371 Model *model = t->detachOutputModel(); |
343 | 372 |
344 if (model) { | 373 if (model) { |
345 QString imn = inputModel->objectName(); | 374 QString imn = input.getModel()->objectName(); |
346 QString trn = | 375 QString trn = |
347 TransformFactory::getInstance()->getTransformFriendlyName | 376 TransformFactory::getInstance()->getTransformFriendlyName |
348 (identifier); | 377 (transform.getIdentifier()); |
349 if (imn != "") { | 378 if (imn != "") { |
350 if (trn != "") { | 379 if (trn != "") { |
351 model->setObjectName(tr("%1: %2").arg(imn).arg(trn)); | 380 model->setObjectName(tr("%1: %2").arg(imn).arg(trn)); |
352 } else { | 381 } else { |
353 model->setObjectName(imn); | 382 model->setObjectName(imn); |