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