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);