Mercurial > hg > svapp
comparison framework/Document.cpp @ 350:aebee52e86b3
Merge from branch tony_integration
author | Chris Cannam |
---|---|
date | Wed, 14 May 2014 09:54:46 +0100 |
parents | 93cf23bfa1cb |
children | f5c914661f6f 0876ea394902 |
comparison
equal
deleted
inserted
replaced
330:46b24009ce7a | 350:aebee52e86b3 |
---|---|
17 | 17 |
18 #include "data/model/WaveFileModel.h" | 18 #include "data/model/WaveFileModel.h" |
19 #include "data/model/WritableWaveFileModel.h" | 19 #include "data/model/WritableWaveFileModel.h" |
20 #include "data/model/DenseThreeDimensionalModel.h" | 20 #include "data/model/DenseThreeDimensionalModel.h" |
21 #include "data/model/DenseTimeValueModel.h" | 21 #include "data/model/DenseTimeValueModel.h" |
22 #include "data/model/FlexiNoteModel.h" | |
23 | |
22 #include "layer/Layer.h" | 24 #include "layer/Layer.h" |
23 #include "widgets/CommandHistory.h" | 25 #include "widgets/CommandHistory.h" |
24 #include "base/Command.h" | 26 #include "base/Command.h" |
25 #include "view/View.h" | 27 #include "view/View.h" |
26 #include "base/PlayParameterRepository.h" | 28 #include "base/PlayParameterRepository.h" |
27 #include "base/PlayParameters.h" | 29 #include "base/PlayParameters.h" |
28 #include "transform/TransformFactory.h" | 30 #include "transform/TransformFactory.h" |
29 #include "transform/ModelTransformerFactory.h" | 31 #include "transform/ModelTransformerFactory.h" |
32 #include "transform/FeatureExtractionModelTransformer.h" | |
30 #include <QApplication> | 33 #include <QApplication> |
31 #include <QTextStream> | 34 #include <QTextStream> |
32 #include <QSettings> | 35 #include <QSettings> |
33 #include <iostream> | 36 #include <iostream> |
34 #include <typeinfo> | 37 #include <typeinfo> |
35 | 38 |
36 // For alignment: | 39 // For alignment: |
37 #include "data/model/AggregateWaveModel.h" | 40 #include "data/model/AggregateWaveModel.h" |
38 #include "data/model/SparseTimeValueModel.h" | 41 #include "data/model/SparseTimeValueModel.h" |
39 #include "data/model/AlignmentModel.h" | 42 #include "data/model/AlignmentModel.h" |
43 | |
44 using std::vector; | |
40 | 45 |
41 //#define DEBUG_DOCUMENT 1 | 46 //#define DEBUG_DOCUMENT 1 |
42 | 47 |
43 //!!! still need to handle command history, documentRestored/documentModified | 48 //!!! still need to handle command history, documentRestored/documentModified |
44 | 49 |
98 emit modelAboutToBeDeleted(m_mainModel); | 103 emit modelAboutToBeDeleted(m_mainModel); |
99 } | 104 } |
100 | 105 |
101 emit mainModelChanged(0); | 106 emit mainModelChanged(0); |
102 delete m_mainModel; | 107 delete m_mainModel; |
103 | |
104 } | 108 } |
105 | 109 |
106 Layer * | 110 Layer * |
107 Document::createLayer(LayerFactory::LayerType type) | 111 Document::createLayer(LayerFactory::LayerType type) |
108 { | 112 { |
205 | 209 |
206 Layer * | 210 Layer * |
207 Document::createDerivedLayer(const Transform &transform, | 211 Document::createDerivedLayer(const Transform &transform, |
208 const ModelTransformer::Input &input) | 212 const ModelTransformer::Input &input) |
209 { | 213 { |
214 Transforms transforms; | |
215 transforms.push_back(transform); | |
216 vector<Layer *> layers = createDerivedLayers(transforms, input); | |
217 if (layers.empty()) return 0; | |
218 else return layers[0]; | |
219 } | |
220 | |
221 vector<Layer *> | |
222 Document::createDerivedLayers(const Transforms &transforms, | |
223 const ModelTransformer::Input &input) | |
224 { | |
210 QString message; | 225 QString message; |
211 Model *newModel = addDerivedModel(transform, input, message); | 226 vector<Model *> newModels = addDerivedModels(transforms, input, message, 0); |
212 if (!newModel) { | 227 |
213 emit modelGenerationFailed(transform.getIdentifier(), message); | 228 if (newModels.empty()) { |
214 return 0; | 229 //!!! This identifier may be wrong! |
230 emit modelGenerationFailed(transforms[0].getIdentifier(), message); | |
231 return vector<Layer *>(); | |
215 } else if (message != "") { | 232 } else if (message != "") { |
216 emit modelGenerationWarning(transform.getIdentifier(), message); | 233 //!!! This identifier may be wrong! |
217 } | 234 emit modelGenerationWarning(transforms[0].getIdentifier(), message); |
218 | 235 } |
219 LayerFactory::LayerTypeSet types = | 236 |
220 LayerFactory::getInstance()->getValidLayerTypes(newModel); | 237 QStringList names; |
221 | 238 for (int i = 0; i < newModels.size(); ++i) { |
222 if (types.empty()) { | 239 names.push_back(getUniqueLayerName |
223 cerr << "WARNING: Document::createLayerForTransformer: no valid display layer for output of transform " << transform.getIdentifier() << endl; | 240 (TransformFactory::getInstance()-> |
224 newModel->aboutToDelete(); | 241 getTransformFriendlyName |
225 emit modelAboutToBeDeleted(newModel); | 242 (transforms[i].getIdentifier()))); |
226 m_models.erase(newModel); | 243 } |
227 delete newModel; | 244 |
228 return 0; | 245 vector<Layer *> layers = createLayersForDerivedModels(newModels, names); |
229 } | 246 return layers; |
230 | 247 } |
231 //!!! for now, just use the first suitable layer type | 248 |
232 | 249 class AdditionalModelConverter : |
233 Layer *newLayer = createLayer(*types.begin()); | 250 public ModelTransformerFactory::AdditionalModelHandler |
234 setModel(newLayer, newModel); | 251 { |
235 | 252 public: |
236 //!!! We need to clone the model when adding the layer, so that it | 253 AdditionalModelConverter(Document *doc, |
237 //can be edited without affecting other layers that are based on | 254 Document::LayerCreationHandler *handler) : |
238 //the same model. Unfortunately we can't just clone it now, | 255 m_doc(doc), |
239 //because it probably hasn't been completed yet -- the transform | 256 m_handler(handler) { |
240 //runs in the background. Maybe the transform has to handle | 257 } |
241 //cloning and cacheing models itself. | 258 |
242 // | 259 virtual ~AdditionalModelConverter() { } |
243 // Once we do clone models here, of course, we'll have to avoid | 260 |
244 // leaking them too. | 261 void |
245 // | 262 setPrimaryLayers(vector<Layer *> layers) { |
246 // We want the user to be able to add a model to a second layer | 263 m_primary = layers; |
247 // _while it's still being calculated in the first_ and have it | 264 } |
248 // work quickly. That means we need to put the same physical | 265 |
249 // model pointer in both layers, so they can't actually be cloned. | 266 void |
267 moreModelsAvailable(vector<Model *> models) { | |
268 std::cerr << "AdditionalModelConverter::moreModelsAvailable: " << models.size() << " model(s)" << std::endl; | |
269 // We can't automatically regenerate the additional models on | |
270 // reload -- we should delete them instead | |
271 QStringList names; | |
272 foreach (Model *model, models) { | |
273 m_doc->addAdditionalModel(model); | |
274 names.push_back(QString()); | |
275 } | |
276 vector<Layer *> layers = m_doc->createLayersForDerivedModels | |
277 (models, names); | |
278 m_handler->layersCreated(m_primary, layers); | |
279 delete this; | |
280 } | |
281 | |
282 void | |
283 noMoreModelsAvailable() { | |
284 std::cerr << "AdditionalModelConverter::noMoreModelsAvailable" << std::endl; | |
285 m_handler->layersCreated(m_primary, vector<Layer *>()); | |
286 delete this; | |
287 } | |
288 | |
289 private: | |
290 Document *m_doc; | |
291 vector<Layer *> m_primary; | |
292 Document::LayerCreationHandler *m_handler; //!!! how to handle destruction of this? | |
293 }; | |
294 | |
295 void | |
296 Document::createDerivedLayersAsync(const Transforms &transforms, | |
297 const ModelTransformer::Input &input, | |
298 LayerCreationHandler *handler) | |
299 { | |
300 QString message; | |
301 | |
302 AdditionalModelConverter *amc = new AdditionalModelConverter(this, handler); | |
250 | 303 |
251 if (newLayer) { | 304 vector<Model *> newModels = addDerivedModels |
252 newLayer->setObjectName(getUniqueLayerName | 305 (transforms, input, message, amc); |
253 (TransformFactory::getInstance()-> | 306 |
254 getTransformFriendlyName | 307 QStringList names; |
255 (transform.getIdentifier()))); | 308 for (int i = 0; i < newModels.size(); ++i) { |
256 } | 309 names.push_back(getUniqueLayerName |
257 | 310 (TransformFactory::getInstance()-> |
258 emit layerAdded(newLayer); | 311 getTransformFriendlyName |
259 return newLayer; | 312 (transforms[i].getIdentifier()))); |
313 } | |
314 | |
315 vector<Layer *> layers = createLayersForDerivedModels(newModels, names); | |
316 amc->setPrimaryLayers(layers); | |
317 | |
318 if (newModels.empty()) { | |
319 //!!! This identifier may be wrong! | |
320 emit modelGenerationFailed(transforms[0].getIdentifier(), message); | |
321 } else if (message != "") { | |
322 //!!! This identifier may be wrong! | |
323 emit modelGenerationWarning(transforms[0].getIdentifier(), message); | |
324 } | |
325 } | |
326 | |
327 vector<Layer *> | |
328 Document::createLayersForDerivedModels(vector<Model *> newModels, | |
329 QStringList names) | |
330 { | |
331 vector<Layer *> layers; | |
332 | |
333 for (int i = 0; i < (int)newModels.size(); ++i) { | |
334 | |
335 Model *newModel = newModels[i]; | |
336 | |
337 LayerFactory::LayerTypeSet types = | |
338 LayerFactory::getInstance()->getValidLayerTypes(newModel); | |
339 | |
340 if (types.empty()) { | |
341 cerr << "WARNING: Document::createLayerForTransformer: no valid display layer for output of transform " << names[i] << endl; | |
342 //!!! inadequate cleanup: | |
343 newModel->aboutToDelete(); | |
344 emit modelAboutToBeDeleted(newModel); | |
345 m_models.erase(newModel); | |
346 delete newModel; | |
347 return vector<Layer *>(); | |
348 } | |
349 | |
350 //!!! for now, just use the first suitable layer type | |
351 | |
352 Layer *newLayer = createLayer(*types.begin()); | |
353 setModel(newLayer, newModel); | |
354 | |
355 //!!! We need to clone the model when adding the layer, so that it | |
356 //can be edited without affecting other layers that are based on | |
357 //the same model. Unfortunately we can't just clone it now, | |
358 //because it probably hasn't been completed yet -- the transform | |
359 //runs in the background. Maybe the transform has to handle | |
360 //cloning and cacheing models itself. | |
361 // | |
362 // Once we do clone models here, of course, we'll have to avoid | |
363 // leaking them too. | |
364 // | |
365 // We want the user to be able to add a model to a second layer | |
366 // _while it's still being calculated in the first_ and have it | |
367 // work quickly. That means we need to put the same physical | |
368 // model pointer in both layers, so they can't actually be cloned. | |
369 | |
370 if (newLayer) { | |
371 newLayer->setObjectName(names[i]); | |
372 } | |
373 | |
374 emit layerAdded(newLayer); | |
375 layers.push_back(newLayer); | |
376 } | |
377 | |
378 return layers; | |
260 } | 379 } |
261 | 380 |
262 void | 381 void |
263 Document::setMainModel(WaveFileModel *model) | 382 Document::setMainModel(WaveFileModel *model) |
264 { | 383 { |
392 for (size_t k = 0; k < obsoleteLayers.size(); ++k) { | 511 for (size_t k = 0; k < obsoleteLayers.size(); ++k) { |
393 deleteLayer(obsoleteLayers[k], true); | 512 deleteLayer(obsoleteLayers[k], true); |
394 } | 513 } |
395 | 514 |
396 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { | 515 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { |
516 if (i->second.additional) { | |
517 Model *m = i->first; | |
518 emit modelAboutToBeDeleted(m); | |
519 delete m; | |
520 } | |
521 } | |
522 | |
523 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { | |
397 | 524 |
398 Model *m = i->first; | 525 Model *m = i->first; |
399 | 526 |
400 #ifdef DEBUG_DOCUMENT | 527 #ifdef DEBUG_DOCUMENT |
401 SVDEBUG << "considering alignment for model " << m << " (name \"" | 528 SVDEBUG << "considering alignment for model " << m << " (name \"" |
426 | 553 |
427 delete oldMainModel; | 554 delete oldMainModel; |
428 } | 555 } |
429 | 556 |
430 void | 557 void |
431 Document::addDerivedModel(const Transform &transform, | 558 Document::addAlreadyDerivedModel(const Transform &transform, |
432 const ModelTransformer::Input &input, | 559 const ModelTransformer::Input &input, |
433 Model *outputModelToAdd) | 560 Model *outputModelToAdd) |
434 { | 561 { |
435 if (m_models.find(outputModelToAdd) != m_models.end()) { | 562 if (m_models.find(outputModelToAdd) != m_models.end()) { |
436 cerr << "WARNING: Document::addDerivedModel: Model already added" | 563 cerr << "WARNING: Document::addAlreadyDerivedModel: Model already added" |
437 << endl; | 564 << endl; |
438 return; | 565 return; |
439 } | 566 } |
440 | 567 |
441 #ifdef DEBUG_DOCUMENT | 568 #ifdef DEBUG_DOCUMENT |
442 if (input.getModel()) { | 569 if (input.getModel()) { |
443 cerr << "Document::addDerivedModel: source is " << input.getModel() << " \"" << input.getModel()->objectName() << "\"" << endl; | 570 cerr << "Document::addAlreadyDerivedModel: source is " << input.getModel() << " \"" << input.getModel()->objectName() << "\"" << endl; |
444 } else { | 571 } else { |
445 cerr << "Document::addDerivedModel: source is " << input.getModel() << endl; | 572 cerr << "Document::addAlreadyDerivedModel: source is " << input.getModel() << endl; |
446 } | 573 } |
447 #endif | 574 #endif |
448 | 575 |
449 ModelRecord rec; | 576 ModelRecord rec; |
450 rec.source = input.getModel(); | 577 rec.source = input.getModel(); |
451 rec.channel = input.getChannel(); | 578 rec.channel = input.getChannel(); |
452 rec.transform = transform; | 579 rec.transform = transform; |
580 rec.additional = false; | |
453 rec.refcount = 0; | 581 rec.refcount = 0; |
454 | 582 |
455 outputModelToAdd->setSourceModel(input.getModel()); | 583 outputModelToAdd->setSourceModel(input.getModel()); |
456 | 584 |
457 m_models[outputModelToAdd] = rec; | 585 m_models[outputModelToAdd] = rec; |
458 | 586 |
459 #ifdef DEBUG_DOCUMENT | 587 #ifdef DEBUG_DOCUMENT |
460 SVDEBUG << "Document::addDerivedModel: Added model " << outputModelToAdd << endl; | 588 cerr << "Document::addAlreadyDerivedModel: Added model " << outputModelToAdd << endl; |
461 cerr << "Models now: "; | 589 cerr << "Models now: "; |
462 for (ModelMap::const_iterator i = m_models.begin(); i != m_models.end(); ++i) { | 590 for (ModelMap::const_iterator i = m_models.begin(); i != m_models.end(); ++i) { |
463 cerr << i->first << " "; | 591 cerr << i->first << " "; |
464 } | 592 } |
465 cerr << endl; | 593 cerr << endl; |
479 } | 607 } |
480 | 608 |
481 ModelRecord rec; | 609 ModelRecord rec; |
482 rec.source = 0; | 610 rec.source = 0; |
483 rec.refcount = 0; | 611 rec.refcount = 0; |
612 rec.additional = false; | |
484 | 613 |
485 m_models[model] = rec; | 614 m_models[model] = rec; |
486 | 615 |
487 #ifdef DEBUG_DOCUMENT | 616 #ifdef DEBUG_DOCUMENT |
488 SVDEBUG << "Document::addImportedModel: Added model " << model << endl; | 617 SVDEBUG << "Document::addImportedModel: Added model " << model << endl; |
496 if (m_autoAlignment) alignModel(model); | 625 if (m_autoAlignment) alignModel(model); |
497 | 626 |
498 emit modelAdded(model); | 627 emit modelAdded(model); |
499 } | 628 } |
500 | 629 |
630 void | |
631 Document::addAdditionalModel(Model *model) | |
632 { | |
633 if (m_models.find(model) != m_models.end()) { | |
634 cerr << "WARNING: Document::addAdditionalModel: Model already added" | |
635 << endl; | |
636 return; | |
637 } | |
638 | |
639 ModelRecord rec; | |
640 rec.source = 0; | |
641 rec.refcount = 0; | |
642 rec.additional = true; | |
643 | |
644 m_models[model] = rec; | |
645 | |
646 #ifdef DEBUG_DOCUMENT | |
647 SVDEBUG << "Document::addAdditionalModel: Added model " << model << endl; | |
648 cerr << "Models now: "; | |
649 for (ModelMap::const_iterator i = m_models.begin(); i != m_models.end(); ++i) { | |
650 cerr << i->first << " "; | |
651 } | |
652 cerr << endl; | |
653 #endif | |
654 | |
655 if (m_autoAlignment) alignModel(model); | |
656 | |
657 emit modelAdded(model); | |
658 } | |
659 | |
501 Model * | 660 Model * |
502 Document::addDerivedModel(const Transform &transform, | 661 Document::addDerivedModel(const Transform &transform, |
503 const ModelTransformer::Input &input, | 662 const ModelTransformer::Input &input, |
504 QString &message) | 663 QString &message) |
505 { | 664 { |
506 Model *model = 0; | |
507 | |
508 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { | 665 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { |
509 if (i->second.transform == transform && | 666 if (i->second.transform == transform && |
510 i->second.source == input.getModel() && | 667 i->second.source == input.getModel() && |
511 i->second.channel == input.getChannel()) { | 668 i->second.channel == input.getChannel()) { |
512 return i->first; | 669 std::cerr << "derived model taken from map " << std::endl; |
513 } | 670 return i->first; |
514 } | 671 } |
515 | 672 } |
516 model = ModelTransformerFactory::getInstance()->transform | 673 |
517 (transform, input, message); | 674 Transforms tt; |
518 | 675 tt.push_back(transform); |
519 // The transform we actually used was presumably identical to the | 676 vector<Model *> mm = addDerivedModels(tt, input, message, 0); |
520 // one asked for, except that the version of the plugin may | 677 if (mm.empty()) return 0; |
521 // differ. It's possible that the returned message contains a | 678 else return mm[0]; |
522 // warning about this; that doesn't concern us here, but we do | 679 } |
523 // need to ensure that the transform we remember is correct for | 680 |
524 // what was actually applied, with the current plugin version. | 681 vector<Model *> |
525 | 682 Document::addDerivedModels(const Transforms &transforms, |
526 Transform applied = transform; | 683 const ModelTransformer::Input &input, |
527 applied.setPluginVersion | 684 QString &message, |
528 (TransformFactory::getInstance()-> | 685 AdditionalModelConverter *amc) |
529 getDefaultTransformFor(transform.getIdentifier(), | 686 { |
530 lrintf(transform.getSampleRate())) | 687 vector<Model *> mm = |
531 .getPluginVersion()); | 688 ModelTransformerFactory::getInstance()->transformMultiple |
532 | 689 (transforms, input, message, amc); |
533 if (!model) { | 690 |
534 cerr << "WARNING: Document::addDerivedModel: no output model for transform " << transform.getIdentifier() << endl; | 691 for (int j = 0; j < (int)mm.size(); ++j) { |
535 } else { | 692 |
536 addDerivedModel(applied, input, model); | 693 Model *model = mm[j]; |
537 } | 694 |
538 | 695 // The transform we actually used was presumably identical to |
539 return model; | 696 // the one asked for, except that the version of the plugin |
697 // may differ. It's possible that the returned message | |
698 // contains a warning about this; that doesn't concern us | |
699 // here, but we do need to ensure that the transform we | |
700 // remember is correct for what was actually applied, with the | |
701 // current plugin version. | |
702 | |
703 Transform applied = transforms[j]; | |
704 applied.setPluginVersion | |
705 (TransformFactory::getInstance()-> | |
706 getDefaultTransformFor(applied.getIdentifier(), | |
707 lrintf(applied.getSampleRate())) | |
708 .getPluginVersion()); | |
709 | |
710 if (!model) { | |
711 cerr << "WARNING: Document::addDerivedModel: no output model for transform " << applied.getIdentifier() << endl; | |
712 } else { | |
713 addAlreadyDerivedModel(applied, input, model); | |
714 } | |
715 } | |
716 | |
717 return mm; | |
540 } | 718 } |
541 | 719 |
542 void | 720 void |
543 Document::releaseModel(Model *model) // Will _not_ release main model! | 721 Document::releaseModel(Model *model) // Will _not_ release main model! |
544 { | 722 { |
688 PlayParameterRepository::getInstance()->copyParameters | 866 PlayParameterRepository::getInstance()->copyParameters |
689 (previousModel, model); | 867 (previousModel, model); |
690 } | 868 } |
691 | 869 |
692 LayerFactory::getInstance()->setModel(layer, model); | 870 LayerFactory::getInstance()->setModel(layer, model); |
871 // std::cerr << "layer type: " << LayerFactory::getInstance()->getLayerTypeName(LayerFactory::getInstance()->getLayerType(layer)) << std::endl; | |
693 | 872 |
694 if (previousModel) { | 873 if (previousModel) { |
695 releaseModel(previousModel); | 874 releaseModel(previousModel); |
696 } | 875 } |
697 } | 876 } |
1011 View *view, | 1190 View *view, |
1012 Layer *layer) : | 1191 Layer *layer) : |
1013 m_d(d), | 1192 m_d(d), |
1014 m_view(view), | 1193 m_view(view), |
1015 m_layer(layer), | 1194 m_layer(layer), |
1195 m_wasDormant(layer->isLayerDormant(view)), | |
1016 m_name(qApp->translate("RemoveLayerCommand", "Delete %1 Layer").arg(layer->objectName())), | 1196 m_name(qApp->translate("RemoveLayerCommand", "Delete %1 Layer").arg(layer->objectName())), |
1017 m_added(true) | 1197 m_added(true) |
1018 { | 1198 { |
1019 } | 1199 } |
1020 | 1200 |
1064 | 1244 |
1065 void | 1245 void |
1066 Document::RemoveLayerCommand::unexecute() | 1246 Document::RemoveLayerCommand::unexecute() |
1067 { | 1247 { |
1068 m_view->addLayer(m_layer); | 1248 m_view->addLayer(m_layer); |
1069 m_layer->setLayerDormant(m_view, false); | 1249 m_layer->setLayerDormant(m_view, m_wasDormant); |
1070 | 1250 |
1071 m_d->addToLayerViewMap(m_layer, m_view); | 1251 m_d->addToLayerViewMap(m_layer, m_view); |
1072 m_added = true; | 1252 m_added = true; |
1073 } | 1253 } |
1074 | 1254 |