comparison framework/Document.cpp @ 297:1e61f0c26593 tonioni_multi_transform

Enable multi-transform stuff through to here
author Chris Cannam
date Mon, 02 Dec 2013 15:06:16 +0000
parents 19282182e60d
children f72d58d1ccb0
comparison
equal deleted inserted replaced
296:19282182e60d 297:1e61f0c26593
38 38
39 // For alignment: 39 // For alignment:
40 #include "data/model/AggregateWaveModel.h" 40 #include "data/model/AggregateWaveModel.h"
41 #include "data/model/SparseTimeValueModel.h" 41 #include "data/model/SparseTimeValueModel.h"
42 #include "data/model/AlignmentModel.h" 42 #include "data/model/AlignmentModel.h"
43
44 using std::vector;
43 45
44 //#define DEBUG_DOCUMENT 1 46 //#define DEBUG_DOCUMENT 1
45 47
46 //!!! still need to handle command history, documentRestored/documentModified 48 //!!! still need to handle command history, documentRestored/documentModified
47 49
203 (TransformFactory::getInstance()-> 205 (TransformFactory::getInstance()->
204 getTransformFriendlyName(transform))); 206 getTransformFriendlyName(transform)));
205 207
206 return newLayer; 208 return newLayer;
207 } 209 }
210
208 Layer * 211 Layer *
209 Document::createDerivedLayer(const Transform &transform, 212 Document::createDerivedLayer(const Transform &transform,
210 const ModelTransformer::Input &input) 213 const ModelTransformer::Input &input)
211 { 214 {
215 Transforms transforms;
216 transforms.push_back(transform);
217 vector<Layer *> layers = createDerivedLayers(transforms, input);
218 if (layers.empty()) return 0;
219 else return layers[0];
220 }
221
222 vector<Layer *>
223 Document::createDerivedLayers(const Transforms &transforms,
224 const ModelTransformer::Input &input)
225 {
212 QString message; 226 QString message;
213 Model *newModel = addDerivedModel(transform, input, message); 227 vector<Model *> newModels = addDerivedModels(transforms, input, message);
214 if (!newModel) { 228
215 emit modelGenerationFailed(transform.getIdentifier(), message); 229 if (newModels.empty()) {
216 return 0; 230 //!!! This identifier may be wrong!
231 emit modelGenerationFailed(transforms[0].getIdentifier(), message);
232 return vector<Layer *>();
217 } else if (message != "") { 233 } else if (message != "") {
218 emit modelGenerationWarning(transform.getIdentifier(), message); 234 //!!! This identifier may be wrong!
219 } 235 emit modelGenerationWarning(transforms[0].getIdentifier(), message);
220 236 }
221 LayerFactory::LayerTypeSet types = 237
222 LayerFactory::getInstance()->getValidLayerTypes(newModel); 238 vector<Layer *> layers;
223 239
224 if (types.empty()) { 240 for (int i = 0; i < (int)newModels.size(); ++i) {
225 cerr << "WARNING: Document::createLayerForTransformer: no valid display layer for output of transform " << transform.getIdentifier() << endl; 241
226 newModel->aboutToDelete(); 242 Model *newModel = newModels[i];
227 emit modelAboutToBeDeleted(newModel); 243
228 m_models.erase(newModel); 244 LayerFactory::LayerTypeSet types =
229 delete newModel; 245 LayerFactory::getInstance()->getValidLayerTypes(newModel);
230 return 0; 246
231 } 247 if (types.empty()) {
232 248 cerr << "WARNING: Document::createLayerForTransformer: no valid display layer for output of transform " << transforms[i].getIdentifier() << endl;
233 //!!! for now, just use the first suitable layer type 249 //!!! inadequate cleanup:
234 250 newModel->aboutToDelete();
235 Layer *newLayer = createLayer(*types.begin()); 251 emit modelAboutToBeDeleted(newModel);
236 setModel(newLayer, newModel); 252 m_models.erase(newModel);
237 253 delete newModel;
238 //!!! We need to clone the model when adding the layer, so that it 254 return vector<Layer *>();
239 //can be edited without affecting other layers that are based on 255 }
240 //the same model. Unfortunately we can't just clone it now, 256
241 //because it probably hasn't been completed yet -- the transform 257 //!!! for now, just use the first suitable layer type
242 //runs in the background. Maybe the transform has to handle 258
243 //cloning and cacheing models itself. 259 Layer *newLayer = createLayer(*types.begin());
244 // 260 setModel(newLayer, newModel);
245 // Once we do clone models here, of course, we'll have to avoid 261
246 // leaking them too. 262 //!!! We need to clone the model when adding the layer, so that it
247 // 263 //can be edited without affecting other layers that are based on
248 // We want the user to be able to add a model to a second layer 264 //the same model. Unfortunately we can't just clone it now,
249 // _while it's still being calculated in the first_ and have it 265 //because it probably hasn't been completed yet -- the transform
250 // work quickly. That means we need to put the same physical 266 //runs in the background. Maybe the transform has to handle
251 // model pointer in both layers, so they can't actually be cloned. 267 //cloning and cacheing models itself.
268 //
269 // Once we do clone models here, of course, we'll have to avoid
270 // leaking them too.
271 //
272 // We want the user to be able to add a model to a second layer
273 // _while it's still being calculated in the first_ and have it
274 // work quickly. That means we need to put the same physical
275 // model pointer in both layers, so they can't actually be cloned.
252 276
253 if (newLayer) { 277 if (newLayer) {
254 newLayer->setObjectName(getUniqueLayerName 278 newLayer->setObjectName(getUniqueLayerName
255 (TransformFactory::getInstance()-> 279 (TransformFactory::getInstance()->
256 getTransformFriendlyName 280 getTransformFriendlyName
257 (transform.getIdentifier()))); 281 (transforms[i].getIdentifier())));
258 } 282 }
259 283
260 emit layerAdded(newLayer); 284 emit layerAdded(newLayer);
261 return newLayer; 285 layers.push_back(newLayer);
262 } 286 }
263 287
264 Layer * 288 return layers;
265 Document::createDerivedLayer(const Transform &transform, 289 }
266 const ModelTransformer::Input &input,
267 const LayerFactory::LayerType type)
268 {
269 // !!! THIS IS TOTALLY REDUNDANT CODE, EXCEPT FOR THE type SETTING
270
271 QString message;
272 Model *newModel = addDerivedModel(transform, input, message);
273 if (!newModel) {
274 emit modelGenerationFailed(transform.getIdentifier(), message);
275 return 0;
276 } else if (message != "") {
277 emit modelGenerationWarning(transform.getIdentifier(), message);
278 }
279
280 LayerFactory::LayerTypeSet types =
281 LayerFactory::getInstance()->getValidLayerTypes(newModel);
282
283 if (types.empty()) {
284 std::cerr << "WARNING: Document::createLayerForTransformer: no valid display layer for output of transform " << transform.getIdentifier() << std::endl;
285 newModel->aboutToDelete();
286 emit modelAboutToBeDeleted(newModel);
287 m_models.erase(newModel);
288 delete newModel;
289 return 0;
290 }
291
292 //!!! creating layer with the specified type
293
294 Layer *newLayer = createLayer(type);
295 setModel(newLayer, newModel);
296
297 //!!! We need to clone the model when adding the layer, so that it
298 //can be edited without affecting other layers that are based on
299 //the same model. Unfortunately we can't just clone it now,
300 //because it probably hasn't been completed yet -- the transform
301 //runs in the background. Maybe the transform has to handle
302 //cloning and cacheing models itself.
303 //
304 // Once we do clone models here, of course, we'll have to avoid
305 // leaking them too.
306 //
307 // We want the user to be able to add a model to a second layer
308 // _while it's still being calculated in the first_ and have it
309 // work quickly. That means we need to put the same physical
310 // model pointer in both layers, so they can't actually be cloned.
311
312 if (newLayer) {
313 newLayer->setObjectName(getUniqueLayerName
314 (TransformFactory::getInstance()->
315 getTransformFriendlyName
316 (transform.getIdentifier())));
317 }
318
319 emit layerAdded(newLayer);
320 return newLayer;
321 }
322
323 290
324 void 291 void
325 Document::setMainModel(WaveFileModel *model) 292 Document::setMainModel(WaveFileModel *model)
326 { 293 {
327 Model *oldMainModel = m_mainModel; 294 Model *oldMainModel = m_mainModel;
563 Model * 530 Model *
564 Document::addDerivedModel(const Transform &transform, 531 Document::addDerivedModel(const Transform &transform,
565 const ModelTransformer::Input &input, 532 const ModelTransformer::Input &input,
566 QString &message) 533 QString &message)
567 { 534 {
568 Model *model = 0;
569 // model = (Model) new FlexiNoteModel();
570 // return model;
571
572 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { 535 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) {
573 if (i->second.transform == transform && 536 if (i->second.transform == transform &&
574 i->second.source == input.getModel() && 537 i->second.source == input.getModel() &&
575 i->second.channel == input.getChannel()) { 538 i->second.channel == input.getChannel()) {
576 std::cerr << "derived model taken from map " << std::endl; 539 std::cerr << "derived model taken from map " << std::endl;
577 return i->first; 540 return i->first;
578 } 541 }
579 } 542 }
580 543
581 model = ModelTransformerFactory::getInstance()->transform 544 Transforms tt;
582 (transform, input, message); 545 tt.push_back(transform);
583 546 vector<Model *> mm = addDerivedModels(tt, input, message);
584 // The transform we actually used was presumably identical to the 547 if (mm.empty()) return 0;
585 // one asked for, except that the version of the plugin may 548 else return mm[0];
586 // differ. It's possible that the returned message contains a 549 }
587 // warning about this; that doesn't concern us here, but we do 550
588 // need to ensure that the transform we remember is correct for 551 vector<Model *>
589 // what was actually applied, with the current plugin version. 552 Document::addDerivedModels(const Transforms &transforms,
590 553 const ModelTransformer::Input &input,
591 Transform applied = transform; 554 QString &message)
592 applied.setPluginVersion 555 {
593 (TransformFactory::getInstance()-> 556 vector<Model *> mm =
594 getDefaultTransformFor(transform.getIdentifier(), 557 ModelTransformerFactory::getInstance()->transformMultiple
595 lrintf(transform.getSampleRate())) 558 (transforms, input, message);
596 .getPluginVersion()); 559
597 560 for (int j = 0; j < (int)mm.size(); ++j) {
598 if (!model) { 561
599 cerr << "WARNING: Document::addDerivedModel: no output model for transform " << transform.getIdentifier() << endl; 562 Model *model = mm[j];
600 } else { 563
601 addDerivedModel(applied, input, model); 564 // The transform we actually used was presumably identical to
602 } 565 // the one asked for, except that the version of the plugin
603 // std::cerr << "derived model name: " << model->getTypeName() << std::endl; 566 // may differ. It's possible that the returned message
567 // contains a warning about this; that doesn't concern us
568 // here, but we do need to ensure that the transform we
569 // remember is correct for what was actually applied, with the
570 // current plugin version.
571
572 Transform applied = transforms[j];
573 applied.setPluginVersion
574 (TransformFactory::getInstance()->
575 getDefaultTransformFor(applied.getIdentifier(),
576 lrintf(applied.getSampleRate()))
577 .getPluginVersion());
578
579 if (!model) {
580 cerr << "WARNING: Document::addDerivedModel: no output model for transform " << applied.getIdentifier() << endl;
581 } else {
582 addDerivedModel(applied, input, model);
583 }
584 }
604 585
605 return model; 586 return mm;
606 } 587 }
607 588
608 void 589 void
609 Document::releaseModel(Model *model) // Will _not_ release main model! 590 Document::releaseModel(Model *model) // Will _not_ release main model!
610 { 591 {