Mercurial > hg > svcore
comparison plugin/transform/ModelTransformerFactory.cpp @ 384:6f6ab834449d spectrogram-cache-rejig
* Merge from trunk
author | Chris Cannam |
---|---|
date | Wed, 27 Feb 2008 11:59:42 +0000 |
parents | 13e5870040e6 |
children |
comparison
equal
deleted
inserted
replaced
337:a6fab10ff9e6 | 384:6f6ab834449d |
---|---|
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 PluginTransformer::ExecutionContext &context, | 73 Model *defaultInputModel, |
73 QString &configurationXml, | 74 AudioCallbackPlaySource *source, |
74 AudioCallbackPlaySource *source, | 75 size_t startFrame, |
75 size_t startFrame, | 76 size_t duration) |
76 size_t duration) | 77 { |
77 { | 78 ModelTransformer::Input input(0); |
78 if (candidateInputModels.empty()) return 0; | 79 |
80 if (candidateInputModels.empty()) return input; | |
79 | 81 |
80 //!!! This will need revision -- we'll have to have a callback | 82 //!!! This will need revision -- we'll have to have a callback |
81 //from the dialog for when the candidate input model is changed, | 83 //from the dialog for when the candidate input model is changed, |
82 //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 |
83 Model *inputModel = candidateInputModels[0]; //!!! for now | 85 Model *inputModel = candidateInputModels[0]; |
84 QStringList candidateModelNames; | 86 QStringList candidateModelNames; |
87 QString defaultModelName; | |
85 std::map<QString, Model *> modelMap; | 88 std::map<QString, Model *> modelMap; |
86 for (size_t i = 0; i < candidateInputModels.size(); ++i) { | 89 for (size_t i = 0; i < candidateInputModels.size(); ++i) { |
87 QString modelName = candidateInputModels[i]->objectName(); | 90 QString modelName = candidateInputModels[i]->objectName(); |
88 QString origModelName = modelName; | 91 QString origModelName = modelName; |
89 int dupcount = 1; | 92 int dupcount = 1; |
90 while (modelMap.find(modelName) != modelMap.end()) { | 93 while (modelMap.find(modelName) != modelMap.end()) { |
91 modelName = tr("%1 <%2>").arg(origModelName).arg(++dupcount); | 94 modelName = tr("%1 <%2>").arg(origModelName).arg(++dupcount); |
92 } | 95 } |
93 modelMap[modelName] = candidateInputModels[i]; | 96 modelMap[modelName] = candidateInputModels[i]; |
94 candidateModelNames.push_back(modelName); | 97 candidateModelNames.push_back(modelName); |
95 } | 98 if (candidateInputModels[i] == defaultInputModel) { |
96 | 99 defaultModelName = modelName; |
97 QString id = identifier.section(':', 0, 2); | 100 } |
98 QString output = identifier.section(':', 3); | 101 } |
102 | |
103 QString id = transform.getPluginIdentifier(); | |
104 QString output = transform.getOutput(); | |
99 QString outputLabel = ""; | 105 QString outputLabel = ""; |
100 QString outputDescription = ""; | 106 QString outputDescription = ""; |
101 | 107 |
102 bool ok = false; | 108 bool ok = false; |
103 configurationXml = m_lastConfigurations[identifier]; | 109 QString configurationXml = m_lastConfigurations[transform.getIdentifier()]; |
104 | 110 |
105 // std::cerr << "last configuration: " << configurationXml.toStdString() << std::endl; | 111 std::cerr << "last configuration: " << configurationXml.toStdString() << std::endl; |
106 | 112 |
107 Vamp::PluginBase *plugin = 0; | 113 Vamp::PluginBase *plugin = 0; |
108 | 114 |
109 bool frequency = false; | 115 bool frequency = false; |
110 bool effect = false; | 116 bool effect = false; |
111 bool generator = false; | 117 bool generator = false; |
112 | 118 |
113 if (FeatureExtractionPluginFactory::instanceFor(id)) { | 119 if (FeatureExtractionPluginFactory::instanceFor(id)) { |
114 | 120 |
115 std::cerr << "getConfigurationForTransformer: instantiating Vamp plugin" << std::endl; | 121 std::cerr << "getConfigurationForTransform: instantiating Vamp plugin" << std::endl; |
116 | 122 |
117 Vamp::Plugin *vp = | 123 Vamp::Plugin *vp = |
118 FeatureExtractionPluginFactory::instanceFor(id)->instantiatePlugin | 124 FeatureExtractionPluginFactory::instanceFor(id)->instantiatePlugin |
119 (id, inputModel->getSampleRate()); | 125 (id, inputModel->getSampleRate()); |
120 | 126 |
177 } | 183 } |
178 } | 184 } |
179 | 185 |
180 if (plugin) { | 186 if (plugin) { |
181 | 187 |
182 context = PluginTransformer::ExecutionContext(context.channel, plugin); | 188 // Ensure block size etc are valid |
183 | 189 TransformFactory::getInstance()-> |
184 if (configurationXml != "") { | 190 makeContextConsistentWithPlugin(transform, plugin); |
185 PluginXml(plugin).setParametersFromXml(configurationXml); | 191 |
186 } | 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); | |
187 | 200 |
188 int sourceChannels = 1; | 201 int sourceChannels = 1; |
189 if (dynamic_cast<DenseTimeValueModel *>(inputModel)) { | 202 if (dynamic_cast<DenseTimeValueModel *>(inputModel)) { |
190 sourceChannels = dynamic_cast<DenseTimeValueModel *>(inputModel) | 203 sourceChannels = dynamic_cast<DenseTimeValueModel *>(inputModel) |
191 ->getChannelCount(); | 204 ->getChannelCount(); |
192 } | 205 } |
193 | 206 |
194 int minChannels = 1, maxChannels = sourceChannels; | 207 int minChannels = 1, maxChannels = sourceChannels; |
195 getChannelRange(identifier, plugin, minChannels, maxChannels); | 208 getChannelRange(transform.getIdentifier(), plugin, |
209 minChannels, maxChannels); | |
196 | 210 |
197 int targetChannels = sourceChannels; | 211 int targetChannels = sourceChannels; |
198 if (!effect) { | 212 if (!effect) { |
199 if (sourceChannels < minChannels) targetChannels = minChannels; | 213 if (sourceChannels < minChannels) targetChannels = minChannels; |
200 if (sourceChannels > maxChannels) targetChannels = maxChannels; | 214 if (sourceChannels > maxChannels) targetChannels = maxChannels; |
201 } | 215 } |
202 | 216 |
203 int defaultChannel = context.channel; | 217 int defaultChannel = -1; //!!! no longer saved! [was context.channel] |
204 | 218 |
205 PluginParameterDialog *dialog = new PluginParameterDialog(plugin); | 219 PluginParameterDialog *dialog = new PluginParameterDialog(plugin); |
206 | 220 |
207 if (candidateModelNames.size() > 1 && !generator) { | 221 if (candidateModelNames.size() > 1 && !generator) { |
208 dialog->setCandidateInputModels(candidateModelNames); | 222 dialog->setCandidateInputModels(candidateModelNames, |
223 defaultModelName); | |
209 } | 224 } |
210 | 225 |
211 if (startFrame != 0 || duration != 0) { | 226 if (startFrame != 0 || duration != 0) { |
212 dialog->setShowSelectionOnlyOption(true); | 227 dialog->setShowSelectionOnlyOption(true); |
213 } | 228 } |
234 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; |
235 } | 250 } |
236 } else { | 251 } else { |
237 std::cerr << "Selected input empty: \"" << selectedInput.toStdString() << "\"" << std::endl; | 252 std::cerr << "Selected input empty: \"" << selectedInput.toStdString() << "\"" << std::endl; |
238 } | 253 } |
239 | |
240 configurationXml = PluginXml(plugin).toXmlString(); | |
241 context.channel = dialog->getChannel(); | |
242 | 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 | |
243 if (startFrame != 0 || duration != 0) { | 266 if (startFrame != 0 || duration != 0) { |
244 if (dialog->getSelectionOnly()) { | 267 if (dialog->getSelectionOnly()) { |
245 context.startFrame = startFrame; | 268 transform.setStartTime(RealTime::frame2RealTime |
246 context.duration = duration; | 269 (startFrame, inputModel->getSampleRate())); |
270 transform.setDuration(RealTime::frame2RealTime | |
271 (duration, inputModel->getSampleRate())); | |
247 } | 272 } |
248 } | 273 } |
249 | 274 |
250 dialog->getProcessingParameters(context.stepSize, | 275 size_t stepSize = 0, blockSize = 0; |
251 context.blockSize, | 276 WindowType windowType = HanningWindow; |
252 context.windowType); | 277 |
253 | 278 dialog->getProcessingParameters(stepSize, |
254 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(); | |
255 | 290 |
256 delete dialog; | 291 delete dialog; |
257 | 292 |
258 if (effect && source) { | 293 if (effect && source) { |
259 source->setAuditioningPlugin(0); // will delete our plugin | 294 source->setAuditioningPlugin(0); // will delete our plugin |
260 } else { | 295 } else { |
261 delete plugin; | 296 delete plugin; |
262 } | 297 } |
263 } | 298 } |
264 | 299 |
265 if (ok) m_lastConfigurations[identifier] = configurationXml; | 300 if (ok) { |
266 | 301 m_lastConfigurations[transform.getIdentifier()] = configurationXml; |
267 return ok ? inputModel : 0; | 302 input.setModel(inputModel); |
268 } | 303 } |
269 | 304 |
305 return input; | |
306 } | |
307 /*!!! | |
270 PluginTransformer::ExecutionContext | 308 PluginTransformer::ExecutionContext |
271 ModelTransformerFactory::getDefaultContextForTransformer(TransformId identifier, | 309 ModelTransformerFactory::getDefaultContextForTransformer(TransformId identifier, |
272 Model *inputModel) | 310 Model *inputModel) |
273 { | 311 { |
274 PluginTransformer::ExecutionContext context(-1); | 312 PluginTransformer::ExecutionContext context(-1); |
287 } | 325 } |
288 } | 326 } |
289 | 327 |
290 return context; | 328 return context; |
291 } | 329 } |
292 | 330 */ |
293 ModelTransformer * | 331 ModelTransformer * |
294 ModelTransformerFactory::createTransformer(TransformId identifier, Model *inputModel, | 332 ModelTransformerFactory::createTransformer(const Transform &transform, |
295 const PluginTransformer::ExecutionContext &context, | 333 const ModelTransformer::Input &input) |
296 QString configurationXml) | |
297 { | 334 { |
298 ModelTransformer *transformer = 0; | 335 ModelTransformer *transformer = 0; |
299 | 336 |
300 QString id = identifier.section(':', 0, 2); | 337 QString id = transform.getPluginIdentifier(); |
301 QString output = identifier.section(':', 3); | |
302 | 338 |
303 if (FeatureExtractionPluginFactory::instanceFor(id)) { | 339 if (FeatureExtractionPluginFactory::instanceFor(id)) { |
304 transformer = new FeatureExtractionModelTransformer | 340 |
305 (inputModel, id, context, configurationXml, output); | 341 transformer = |
342 new FeatureExtractionModelTransformer(input, transform); | |
343 | |
306 } else if (RealTimePluginFactory::instanceFor(id)) { | 344 } else if (RealTimePluginFactory::instanceFor(id)) { |
307 transformer = new RealTimeEffectModelTransformer | 345 |
308 (inputModel, id, context, configurationXml, | 346 transformer = |
309 TransformFactory::getInstance()->getTransformUnits(identifier), | 347 new RealTimeEffectModelTransformer(input, transform); |
310 output == "A" ? -1 : output.toInt()); | 348 |
311 } else { | 349 } else { |
312 std::cerr << "ModelTransformerFactory::createTransformer: Unknown transform \"" | 350 std::cerr << "ModelTransformerFactory::createTransformer: Unknown transform \"" |
313 << identifier.toStdString() << "\"" << std::endl; | 351 << transform.getIdentifier().toStdString() << "\"" << std::endl; |
314 return transformer; | 352 return transformer; |
315 } | 353 } |
316 | 354 |
317 if (transformer) transformer->setObjectName(identifier); | 355 if (transformer) transformer->setObjectName(transform.getIdentifier()); |
318 return transformer; | 356 return transformer; |
319 } | 357 } |
320 | 358 |
321 Model * | 359 Model * |
322 ModelTransformerFactory::transform(TransformId identifier, Model *inputModel, | 360 ModelTransformerFactory::transform(const Transform &transform, |
323 const PluginTransformer::ExecutionContext &context, | 361 const ModelTransformer::Input &input, |
324 QString configurationXml) | 362 QString &message) |
325 { | 363 { |
326 ModelTransformer *t = createTransformer(identifier, inputModel, context, | 364 ModelTransformer *t = createTransformer(transform, input); |
327 configurationXml); | |
328 | |
329 if (!t) return 0; | 365 if (!t) return 0; |
330 | 366 |
331 connect(t, SIGNAL(finished()), this, SLOT(transformerFinished())); | 367 connect(t, SIGNAL(finished()), this, SLOT(transformerFinished())); |
332 | 368 |
333 m_runningTransformers.insert(t); | 369 m_runningTransformers.insert(t); |
334 | 370 |
335 t->start(); | 371 t->start(); |
336 Model *model = t->detachOutputModel(); | 372 Model *model = t->detachOutputModel(); |
337 | 373 |
338 if (model) { | 374 if (model) { |
339 QString imn = inputModel->objectName(); | 375 QString imn = input.getModel()->objectName(); |
340 QString trn = | 376 QString trn = |
341 TransformFactory::getInstance()->getTransformFriendlyName | 377 TransformFactory::getInstance()->getTransformFriendlyName |
342 (identifier); | 378 (transform.getIdentifier()); |
343 if (imn != "") { | 379 if (imn != "") { |
344 if (trn != "") { | 380 if (trn != "") { |
345 model->setObjectName(tr("%1: %2").arg(imn).arg(trn)); | 381 model->setObjectName(tr("%1: %2").arg(imn).arg(trn)); |
346 } else { | 382 } else { |
347 model->setObjectName(imn); | 383 model->setObjectName(imn); |
351 } | 387 } |
352 } else { | 388 } else { |
353 t->wait(); | 389 t->wait(); |
354 } | 390 } |
355 | 391 |
392 message = t->getMessage(); | |
393 | |
356 return model; | 394 return model; |
357 } | 395 } |
358 | 396 |
359 void | 397 void |
360 ModelTransformerFactory::transformerFinished() | 398 ModelTransformerFactory::transformerFinished() |