18 #include "data/model/WaveFileModel.h" 19 #include "data/model/WritableWaveFileModel.h" 20 #include "data/model/DenseThreeDimensionalModel.h" 21 #include "data/model/DenseTimeValueModel.h" 22 #include "data/model/AggregateWaveModel.h" 24 #include "layer/Layer.h" 25 #include "widgets/CommandHistory.h" 26 #include "base/Command.h" 27 #include "view/View.h" 28 #include "base/PlayParameterRepository.h" 29 #include "base/PlayParameters.h" 30 #include "transform/TransformFactory.h" 31 #include "transform/ModelTransformerFactory.h" 32 #include "transform/FeatureExtractionModelTransformer.h" 33 #include <QApplication> 34 #include <QTextStream> 39 #include "data/model/AlignmentModel.h" 40 #include "align/Align.h" 49 m_autoAlignment(false),
53 connect(ModelTransformerFactory::getInstance(),
54 SIGNAL(transformFailed(QString, QString)),
67 Profiler profiler(
"Document::~Document");
74 SVDEBUG <<
"\n\nDocument::~Document: about to clear command history" << endl;
76 CommandHistory::getInstance()->clear();
79 SVCERR <<
"Document::~Document: about to delete layers" << endl;
86 SVCERR <<
"Document::~Document: about to release normal models" << endl;
89 ModelById::release(mr.first);
93 SVCERR <<
"Document::~Document: about to release aggregate models" << endl;
96 ModelById::release(m);
100 SVCERR <<
"Document::~Document: about to release alignment models" << endl;
103 ModelById::release(m);
106 #ifdef DEBUG_DOCUMENT 107 SVCERR <<
"Document::~Document: about to release main model" << endl;
120 Profiler profiler(
"Document::createLayer");
122 Layer *newLayer = LayerFactory::getInstance()->createLayer(type);
123 if (!newLayer)
return nullptr;
129 #ifdef DEBUG_DOCUMENT 130 SVDEBUG <<
"Document::createLayer: Added layer of type " << type
131 <<
", now have " <<
m_layers.size() <<
" layers" << endl;
142 Profiler profiler(
"Document::createMainModelLayer");
145 if (!newLayer)
return nullptr;
153 Profiler profiler(
"Document::createImportedLayer");
155 LayerFactory::LayerTypeSet types =
156 LayerFactory::getInstance()->getValidLayerTypes(modelId);
159 SVCERR <<
"WARNING: Document::importLayer: no valid display layer for model" << endl;
164 LayerFactory::LayerType type = *types.begin();
166 Layer *newLayer = LayerFactory::getInstance()->createLayer(type);
167 if (!newLayer)
return nullptr;
179 #ifdef DEBUG_DOCUMENT 180 SVDEBUG <<
"Document::createImportedLayer: Added layer of type " << type
181 <<
", now have " <<
m_layers.size() <<
" layers" << endl;
191 Profiler profiler(
"Document::createEmptyLayer");
196 LayerFactory::getInstance()->createEmptyModel(type,
m_mainModel);
197 if (!newModel)
return nullptr;
204 auto newModelId = ModelById::add(newModel);
213 TransformId transform)
215 Profiler profiler(
"Document::createDerivedLayer (type)");
218 if (!newLayer)
return nullptr;
221 (TransformFactory::getInstance()->
222 getTransformFriendlyName(transform)));
229 const ModelTransformer::Input &input)
231 Profiler profiler(
"Document::createDerivedLayer (transform)");
233 Transforms transforms;
234 transforms.push_back(transform);
236 if (layers.empty())
return nullptr;
237 else return layers[0];
242 const ModelTransformer::Input &input)
244 Profiler profiler(
"Document::createDerivedLayers");
247 vector<ModelId> newModels =
250 if (newModels.empty()) {
253 return vector<Layer *>();
254 }
else if (message !=
"") {
260 for (
int i = 0; in_range_for(newModels, i); ++i) {
262 (TransformFactory::getInstance()->
263 getTransformFriendlyName
264 (transforms[i].getIdentifier())));
272 public ModelTransformerFactory::AdditionalModelHandler
290 SVDEBUG <<
"AdditionalModelConverter::moreModelsAvailable: " << models.size() <<
" model(s)" << endl;
294 foreach (ModelId modelId, models) {
295 m_doc->addAdditionalModel(modelId);
296 names.push_back(QString());
298 vector<Layer *> layers = m_doc->createLayersForDerivedModels
300 m_handler->layersCreated(
this, m_primary, layers);
306 SVDEBUG <<
"AdditionalModelConverter::noMoreModelsAvailable" << endl;
307 m_handler->layersCreated(
this, m_primary, vector<Layer *>());
312 foreach (Layer *layer, m_primary) {
313 m_doc->setModel(layer, {});
325 const ModelTransformer::Input &input,
328 Profiler profiler(
"Document::createDerivedLayersAsync");
335 (transforms, input, message, amc);
338 for (
int i = 0; in_range_for(newModels, i); ++i) {
340 (TransformFactory::getInstance()->
341 getTransformFriendlyName
342 (transforms[i].getIdentifier())));
348 if (newModels.empty()) {
352 }
else if (message !=
"") {
372 Profiler profiler(
"Document::createLayersForDerivedModels");
374 vector<Layer *> layers;
376 for (
int i = 0; in_range_for(newModels, i); ++i) {
378 ModelId newModelId = newModels[i];
380 LayerFactory::LayerTypeSet types =
381 LayerFactory::getInstance()->getValidLayerTypes(newModelId);
384 SVCERR <<
"WARNING: Document::createLayerForTransformer: no valid display layer for output of transform " << names[i] << endl;
386 return vector<Layer *>();
410 newLayer->setObjectName(names[i]);
414 layers.push_back(newLayer);
423 Profiler profiler(
"Document::setMainModel");
430 if (
auto model = ModelById::get(modelId)) {
431 emit
activity(tr(
"Set main model to %1").arg(model->objectName()));
433 emit
activity(tr(
"Clear main model"));
436 std::vector<Layer *> obsoleteLayers;
437 std::set<QString> failedTransformers;
445 #ifdef DEBUG_DOCUMENT 446 SVDEBUG <<
"Document::setMainModel: Have " 447 <<
m_layers.size() <<
" layers" << endl;
448 SVDEBUG <<
"Models now: ";
450 SVDEBUG << r.first <<
" ";
453 SVDEBUG <<
"Old main model: " << oldMainModel << endl;
458 ModelId modelId = layer->getModel();
460 #ifdef DEBUG_DOCUMENT 461 SVDEBUG <<
"Document::setMainModel: inspecting model " 462 << modelId <<
" in layer " << layer->objectName() << endl;
465 if (modelId == oldMainModel) {
466 #ifdef DEBUG_DOCUMENT 467 SVDEBUG <<
"... it uses the old main model, replacing" << endl;
469 LayerFactory::getInstance()->setModel(layer,
m_mainModel);
473 if (modelId.isNone()) {
474 SVCERR <<
"WARNING: Document::setMainModel: Null model in layer " 477 obsoleteLayers.push_back(layer);
481 if (m_models.find(modelId) == m_models.end()) {
482 SVCERR <<
"WARNING: Document::setMainModel: Unknown model " 483 << modelId <<
" in layer " << layer << endl;
485 obsoleteLayers.push_back(layer);
491 if (!record.
source.isNone() && (record.
source == oldMainModel)) {
493 #ifdef DEBUG_DOCUMENT 494 SVDEBUG <<
"... it uses a model derived from the old main model, regenerating" << endl;
500 const Transform &transform = record.
transform;
501 QString transformId = transform.getIdentifier();
507 ModelId replacementModel =
509 ModelTransformer::Input
513 if (replacementModel.isNone()) {
514 SVCERR <<
"WARNING: Document::setMainModel: Failed to regenerate model for transform \"" 515 << transformId <<
"\"" <<
" in layer " << layer << endl;
516 if (failedTransformers.find(transformId)
517 == failedTransformers.end()) {
521 failedTransformers.insert(transformId);
523 obsoleteLayers.push_back(layer);
530 #ifdef DEBUG_DOCUMENT 531 SVDEBUG <<
"Replacing model " << modelId <<
") with model " 532 << replacementModel <<
") in layer " 533 << layer <<
" (name " << layer->objectName() <<
")" 536 auto rm = ModelById::getAs<RangeSummarisableTimeValueModel>(replacementModel);
538 SVDEBUG <<
"new model has " << rm->getChannelCount() <<
" channels " << endl;
540 SVDEBUG <<
"new model " << replacementModel <<
" is not a RangeSummarisableTimeValueModel!" << endl;
548 for (
size_t k = 0; k < obsoleteLayers.size(); ++k) {
552 std::set<ModelId> additionalModels;
553 for (
const auto &rec : m_models) {
554 if (rec.second.additional) {
555 additionalModels.insert(rec.first);
558 for (ModelId a: additionalModels) {
562 for (
const auto &rec : m_models) {
564 auto m = ModelById::get(rec.first);
567 #ifdef DEBUG_DOCUMENT 568 SVDEBUG <<
"considering alignment for model " << rec.first << endl;
575 }
else if (!oldMainModel.isNone() &&
576 (m->getAlignmentReference() == oldMainModel)) {
583 SVDEBUG <<
"Document::setMainModel: auto-alignment is on, aligning main model if applicable" << endl;
586 SVDEBUG <<
"Document::setMainModel: auto-alignment is off" << endl;
591 if (!oldMainModel.isNone()) {
596 PlayParameterRepository::getInstance()->removePlayable
597 (oldMainModel.untyped);
599 ModelById::release(oldMainModel);
605 const ModelTransformer::Input &input,
606 ModelId outputModelToAdd)
608 Profiler profiler(
"Document::addAlreadyDerivedModel");
611 SVCERR <<
"WARNING: Document::addAlreadyDerivedModel: Model already added" 616 #ifdef DEBUG_DOCUMENT 617 SVDEBUG <<
"Document::addAlreadyDerivedModel: source is " << input.getModel() << endl;
621 rec.
source = input.getModel();
622 rec.
channel = input.getChannel();
626 if (
auto m = ModelById::get(outputModelToAdd)) {
627 m->setSourceModel(input.getModel());
632 #ifdef DEBUG_DOCUMENT 633 SVDEBUG <<
"Document::addAlreadyDerivedModel: Added model " << outputModelToAdd << endl;
634 SVDEBUG <<
"Models now: ";
636 SVDEBUG << rec.first <<
" ";
647 Profiler profiler(
"Document::addNonDerivedModel");
649 if (ModelById::isa<AggregateWaveModel>(modelId)) {
650 #ifdef DEBUG_DOCUMENT 651 SVCERR <<
"Document::addNonDerivedModel: Model " << modelId <<
" is an aggregate model, adding it to aggregates" << endl;
656 if (ModelById::isa<AlignmentModel>(modelId)) {
657 #ifdef DEBUG_DOCUMENT 658 SVCERR <<
"Document::addNonDerivedModel: Model " << modelId <<
" is an alignment model, adding it to alignments" << endl;
665 SVCERR <<
"WARNING: Document::addNonDerivedModel: Model already added" 677 #ifdef DEBUG_DOCUMENT 678 SVCERR <<
"Document::addNonDerivedModel: Added model " << modelId << endl;
679 SVCERR <<
"Models now: ";
681 SVCERR << rec.first <<
" ";
687 SVDEBUG <<
"Document::addNonDerivedModel: auto-alignment is on, aligning model if possible" << endl;
690 SVDEBUG <<
"Document(" <<
this <<
"): addNonDerivedModel: auto-alignment is off" << endl;
699 Profiler profiler(
"Document::addAdditionalModel");
702 SVCERR <<
"WARNING: Document::addAdditionalModel: Model already added" 714 #ifdef DEBUG_DOCUMENT 715 SVDEBUG <<
"Document::addAdditionalModel: Added model " << modelId << endl;
716 SVDEBUG <<
"Models now: ";
718 SVDEBUG << rec.first <<
" ";
724 ModelById::isa<RangeSummarisableTimeValueModel>(modelId)) {
725 SVDEBUG <<
"Document::addAdditionalModel: auto-alignment is on and model is an alignable type, aligning it if possible" << endl;
734 const ModelTransformer::Input &input,
737 Profiler profiler(
"Document::addDerivedModel");
740 if (rec.second.transform == transform &&
741 rec.second.source == input.getModel() &&
742 rec.second.channel == input.getChannel()) {
743 SVDEBUG <<
"derived model taken from map " << endl;
749 tt.push_back(transform);
751 if (mm.empty())
return {};
757 const ModelTransformer::Input &input,
761 Profiler profiler(
"Document::addDerivedModels");
764 ModelTransformerFactory::getInstance()->transformMultiple
765 (transforms, input, message, amc);
767 for (
int j = 0; in_range_for(mm, j); ++j) {
769 ModelId modelId = mm[j];
770 Transform applied = transforms[j];
772 if (modelId.isNone()) {
773 SVCERR <<
"WARNING: Document::addDerivedModel: no output model for transform " << applied.getIdentifier() << endl;
788 applied.setPluginVersion
789 (TransformFactory::getInstance()->
790 getDefaultTransformFor(applied.getIdentifier(),
791 applied.getSampleRate())
792 .getPluginVersion());
803 Profiler profiler(
"Document::releaseModel");
818 #pragma clang diagnostic ignored "-Wpotentially-evaluated-expression" 821 if (
auto model = ModelById::get(modelId)) {
822 SVCERR <<
"Document::releaseModel(" << modelId <<
"), name " 823 << model->objectName() <<
", type " 824 <<
typeid(*model.get()).name() << endl;
826 SVCERR <<
"Document::releaseModel(" << modelId <<
")" << endl;
829 if (modelId.isNone()) {
833 #ifdef DEBUG_DOCUMENT 834 SVCERR <<
"Document::releaseModel(" << modelId <<
")" << endl;
838 #ifdef DEBUG_DOCUMENT 839 SVCERR <<
"Document::releaseModel: It's the main model, ignoring" 848 #ifdef DEBUG_DOCUMENT 849 SVCERR <<
"Document::releaseModel: It's not a regular layer model, ignoring" << endl;
855 if (layer->getModel() == modelId) {
856 #ifdef DEBUG_DOCUMENT 857 SVCERR <<
"Document::releaseModel: It's still in use in at least one layer (e.g. " << layer <<
", \"" << layer->getLayerPresentationName() <<
"\"), ignoring" << endl;
863 #ifdef DEBUG_DOCUMENT 864 SVCERR <<
"Document::releaseModel: Seems to be OK to release this one" 871 if (m.second.source == modelId) {
873 m.second.source = {};
877 if (sourceCount > 0) {
878 SVCERR <<
"Document::releaseModel: Request to release model " 879 << modelId <<
" even though it was source for " 880 << sourceCount <<
" other derived model(s) -- have cleared " 881 <<
"their source fields" << endl;
884 m_models.erase(modelId);
885 ModelById::release(modelId);
891 Profiler profiler(
"Document::deleteLayer");
898 SVDEBUG <<
"NOTE: Document::deleteLayer: Layer " 899 << layer <<
" [" << layer->objectName() <<
"]" 901 <<
" views. Force flag set, so removing from them" << endl;
903 for (std::set<View *>::iterator j =
m_layerViewMap[layer].begin();
906 layer->setLayerDormant(*j,
true);
907 (*j)->removeLayer(layer);
914 SVCERR <<
"WARNING: Document::deleteLayer: Layer " 915 << layer <<
" [" << layer->objectName() <<
"]" 917 <<
" views! Force flag is not set, so not deleting" << endl;
932 SVDEBUG <<
"Document::deleteLayer: Layer " 933 << layer <<
" (typeid " <<
typeid(layer).name() <<
934 ") does not exist, or has already been deleted " 935 <<
"(this may not be as serious as it sounds)" << endl;
939 #ifdef DEBUG_DOCUMENT 940 SVDEBUG <<
"Document::deleteLayer: Removing (and about to release model), now have " 941 <<
m_layers.size() <<
" layers" << endl;
953 Profiler profiler(
"Document::setModel");
955 if (!modelId.isNone() &&
958 SVCERR <<
"ERROR: Document::setModel: Layer " << layer
959 <<
" (\"" << layer->objectName()
960 <<
"\") wants to use unregistered model " << modelId
961 <<
": register the layer's model before setting it!" 966 ModelId previousModel = layer->getModel();
968 if (previousModel == modelId) {
969 SVDEBUG <<
"NOTE: Document::setModel: Layer " << layer <<
" (\"" 970 << layer->objectName()
971 <<
"\") is already set to model " 976 if (!modelId.isNone() && !previousModel.isNone()) {
977 PlayParameterRepository::getInstance()->copyParameters
978 (previousModel.untyped, modelId.untyped);
981 LayerFactory::getInstance()->setModel(layer, modelId);
989 LayerFactory::getInstance()->setChannel(layer, channel);
995 ModelId modelId = layer->getModel();
996 if (modelId.isNone()) {
997 #ifdef DEBUG_DOCUMENT 998 SVDEBUG <<
"Document::addLayerToView: Layer (\"" 999 << layer->objectName()
1000 <<
"\") with no model being added to view: " 1001 <<
"normally you want to set the model first" << endl;
1006 SVCERR <<
"ERROR: Document::addLayerToView: Layer " << layer
1007 <<
" has unregistered model " << modelId
1008 <<
" -- register the layer's model before adding the layer!" << endl;
1013 CommandHistory::getInstance()->addCommand
1020 CommandHistory::getInstance()->addCommand
1032 SVCERR <<
"WARNING: Document::addToLayerViewMap:" 1033 <<
" Layer " << layer <<
" -> view " << view <<
" already in" 1034 <<
" layer view map -- internal inconsistency" << endl;
1047 SVCERR <<
"WARNING: Document::removeFromLayerViewMap:" 1048 <<
" Layer " << layer <<
" -> view " << view <<
" not in" 1049 <<
" layer view map -- internal inconsistency" << endl;
1063 for (
int count = 1; ; ++count) {
1066 (count > 1 ? QString(
"%1 <%2>").arg(candidate).arg(count) :
1069 bool duplicate =
false;
1072 if ((*i)->objectName() == adjusted) {
1078 if (!duplicate)
return adjusted;
1082 std::vector<ModelId>
1085 std::vector<ModelId> models;
1095 ModelId modelId = rec.first;
1098 auto dtvm = ModelById::getAs<DenseTimeValueModel>(modelId);
1100 models.push_back(modelId);
1112 if (rec.first == modelId)
return true;
1120 return Align::canAlign();
1126 SVDEBUG <<
"Document::alignModel(" << modelId <<
", " << forceRecalculate
1127 <<
") (main model is " <<
m_mainModel <<
")" << endl;
1129 auto rm = ModelById::getAs<RangeSummarisableTimeValueModel>(modelId);
1131 SVDEBUG <<
"(model " << modelId <<
" is not an alignable sort)" << endl;
1136 SVDEBUG <<
"(no main model to align to)" << endl;
1137 if (forceRecalculate && !rm->getAlignment().isNone()) {
1138 SVDEBUG <<
"(but model is aligned, and forceRecalculate is true, " 1139 <<
"so resetting alignment to nil)" << endl;
1140 rm->setAlignment({});
1146 SVDEBUG <<
"(model " << modelId <<
" is already aligned to main model " 1148 if (!forceRecalculate) {
1151 SVDEBUG <<
"(but forceRecalculate is true, so realigning anyway)" 1161 SVDEBUG <<
"Document::alignModel(" << modelId
1162 <<
"): is main model, setting alignment to itself" << endl;
1163 auto alignment = std::make_shared<AlignmentModel>(modelId, modelId,
1166 ModelId alignmentModelId = ModelById::add(alignment);
1167 rm->setAlignment(alignmentModelId);
1172 auto w = ModelById::getAs<WritableWaveFileModel>(modelId);
1173 if (w && w->getWriteProportion() < 100) {
1174 SVDEBUG <<
"Document::alignModel(" << modelId
1175 <<
"): model write is not complete, deferring" 1177 connect(w.get(), SIGNAL(writeCompleted(ModelId)),
1182 SVDEBUG <<
"Document::alignModel: aligning..." << endl;
1183 if (!rm->getAlignmentReference().isNone()) {
1184 SVDEBUG <<
"(Note: model " << modelId
1185 <<
" is currently aligned to model " 1186 << rm->getAlignmentReference() <<
"; this will replace that)" 1196 SVDEBUG <<
"Document::performDeferredAlignment: aligning..." << endl;
1224 m_name(qApp->translate(
"AddLayerCommand",
"Add %1 Layer").arg(layer->objectName())),
1231 #ifdef DEBUG_DOCUMENT 1232 SVDEBUG <<
"Document::AddLayerCommand::~AddLayerCommand" << endl;
1242 #ifdef DEBUG_DOCUMENT 1243 SVDEBUG <<
"Document::AddLayerCommand::getName(): Name is " 1252 for (
int i = 0; i <
m_view->getLayerCount(); ++i) {
1284 m_wasDormant(layer->isLayerDormant(view)),
1285 m_name(qApp->translate(
"RemoveLayerCommand",
"Delete %1 Layer").arg(layer->objectName())),
1292 #ifdef DEBUG_DOCUMENT 1293 SVDEBUG <<
"Document::RemoveLayerCommand::~RemoveLayerCommand" << endl;
1303 #ifdef DEBUG_DOCUMENT 1304 SVDEBUG <<
"Document::RemoveLayerCommand::getName(): Name is " 1314 for (
int i = 0; i <
m_view->getLayerCount(); ++i) {
1347 toXml(out, indent, extraAttributes,
false);
1353 toXml(out, indent, extraAttributes,
true);
1358 bool asTemplate)
const 1360 out << indent + QString(
"<data%1%2>\n")
1361 .arg(extraAttributes ==
"" ?
"" :
" ").arg(extraAttributes);
1363 auto mainModel = ModelById::getAs<WaveFileModel>(
m_mainModel);
1366 #ifdef DEBUG_DOCUMENT 1367 SVDEBUG <<
"Document::toXml: writing main model" << endl;
1373 mainModel->toXml(out, indent +
" ",
"mainModel=\"true\"");
1376 auto playParameters =
1377 PlayParameterRepository::getInstance()->getPlayParameters
1379 if (playParameters) {
1380 playParameters->toXml
1382 QString(
"model=\"%1\"")
1383 .arg(mainModel->getExportId()));
1386 #ifdef DEBUG_DOCUMENT 1387 SVDEBUG <<
"Document::toXml: have no main model to write" << endl;
1394 std::set<ModelId> used;
1399 if (i->first && !i->second.empty()) {
1400 ModelId modelId = i->first->getModel();
1401 ModelId sourceId = i->first->getSourceModel();
1402 if (!modelId.isNone()) used.insert(modelId);
1403 if (!sourceId.isNone()) used.insert(sourceId);
1422 #ifdef DEBUG_DOCUMENT 1423 SVDEBUG <<
"Document::toXml: checking aggregate model " 1427 auto aggregate = ModelById::getAs<AggregateWaveModel>(modelId);
1428 if (!aggregate)
continue;
1429 if (used.find(modelId) == used.end()) {
1430 #ifdef DEBUG_DOCUMENT 1431 SVDEBUG <<
"(unused, skipping)" << endl;
1436 #ifdef DEBUG_DOCUMENT 1437 SVDEBUG <<
"(used, writing)" << endl;
1440 aggregate->toXml(out, indent +
" ");
1443 std::set<ModelId> written;
1452 const int nonDerivedPass = 0, derivedPass = 1;
1453 for (
int pass = nonDerivedPass; pass <= derivedPass; ++pass) {
1457 ModelId modelId = rec.first;
1459 if (used.find(modelId) == used.end())
continue;
1461 auto model = ModelById::get(modelId);
1462 if (!model)
continue;
1464 #ifdef DEBUG_DOCUMENT 1465 SVDEBUG <<
"Document::toXml: looking at model " << modelId
1466 <<
" [pass = " << pass <<
"]" << endl;
1483 bool writeModel =
true;
1484 bool haveDerivation =
false;
1486 if (!rec.second.source.isNone() &&
1487 rec.second.transform.getIdentifier() !=
"") {
1488 haveDerivation =
true;
1491 if (pass == nonDerivedPass) {
1492 if (haveDerivation) {
1493 SVDEBUG <<
"skipping derived model " << model->objectName() <<
" during nonDerivedPass" << endl;
1497 if (!haveDerivation) {
1498 SVDEBUG <<
"skipping non-derived model " << model->objectName() <<
" during derivedPass" << endl;
1503 if (haveDerivation) {
1504 if (ModelById::isa<WritableWaveFileModel>(modelId) ||
1505 ModelById::isa<DenseThreeDimensionalModel>(modelId)) {
1511 model->toXml(out, indent +
" ");
1512 written.insert(modelId);
1515 if (haveDerivation) {
1517 modelId, rec.second);
1520 auto playParameters =
1521 PlayParameterRepository::getInstance()->getPlayParameters
1523 if (playParameters) {
1524 playParameters->toXml
1526 QString(
"model=\"%1\"")
1527 .arg(model->getExportId()));
1538 for (
auto modelId: written) {
1540 auto model = ModelById::get(modelId);
1541 if (!model)
continue;
1543 auto alignment = ModelById::get(model->getAlignment());
1544 if (!alignment)
continue;
1546 alignment->toXml(out, indent +
" ");
1550 (*i)->toXml(out, indent +
" ");
1553 out << indent +
"</data>\n";
1560 if (!mainModel)
return;
1562 out << QString(
"<model id=\"%1\" name=\"placeholder\" sampleRate=\"%2\" type=\"wavefile\" file=\":samples/silent.wav\" mainModel=\"true\"/>\n")
1563 .arg(mainModel->getExportId())
1564 .arg(mainModel->getSampleRate());
1569 ModelId targetModelId,
1594 const Transform &transform = rec.
transform;
1596 auto targetModel = ModelById::get(targetModelId);
1597 if (!targetModel)
return;
1615 QString extentsAttributes;
1616 if (transform.getStartTime() != RealTime::zeroTime ||
1617 transform.getDuration() != RealTime::zeroTime) {
1618 extentsAttributes = QString(
"startFrame=\"%1\" duration=\"%2\" ")
1619 .arg(RealTime::realTime2Frame(transform.getStartTime(),
1620 targetModel->getSampleRate()))
1621 .arg(RealTime::realTime2Frame(transform.getDuration(),
1622 targetModel->getSampleRate()));
1626 out << QString(
"<derivation type=\"transform\" source=\"%1\" " 1627 "model=\"%2\" channel=\"%3\" domain=\"%4\" " 1628 "stepSize=\"%5\" blockSize=\"%6\" %7windowType=\"%8\" " 1629 "transform=\"%9\">\n")
1630 .arg(ModelById::getExportId(rec.
source))
1631 .arg(targetModel->getExportId())
1633 .arg(TransformFactory::getInstance()->getTransformInputDomain
1634 (transform.getIdentifier()))
1635 .arg(transform.getStepSize())
1636 .arg(transform.getBlockSize())
1637 .arg(extentsAttributes)
1638 .arg(
int(transform.getWindowType()))
1639 .arg(XmlExportable::encodeEntities(transform.getIdentifier()));
1641 transform.toXml(out, indent +
" ");
1643 out << indent <<
" " 1644 << TransformFactory::getInstance()->getPluginConfigurationXml(transform);
1646 out << indent <<
"</derivation>\n";
void setMainModel(ModelId)
Set the main model (the source for playback sample rate, etc) to the given wave file model...
std::vector< ModelId > getTransformInputModels()
void setChannel(Layer *, int)
Set the given layer to use the given channel of its model (-1 means all available channels)...
void writeBackwardCompatibleDerivation(QTextStream &, QString, ModelId, const ModelRecord &) const
void writePlaceholderMainModel(QTextStream &, QString) const
void mainModelChanged(ModelId)
virtual ~AddLayerCommand()
void cancelAsyncLayerCreation(LayerCreationAsyncHandle handle)
Indicate that the async layer creation task associated with the given handle should be cancelled...
void noMoreModelsAvailable() override
RemoveLayerCommand(Document *d, View *view, Layer *layer)
AddLayerCommand(Document *d, View *view, Layer *layer)
void layerAboutToBeDeleted(Layer *)
void layerRemoved(Layer *)
LayerCreationAsyncHandle createDerivedLayersAsync(const Transforms &, const ModelTransformer::Input &, LayerCreationHandler *handler)
Create suitable layers for the given transforms, which must be identical apart from the output (i...
void modelRegenerationWarning(QString layerName, QString transformName, QString message)
friend class AdditionalModelConverter
Add derived models associated with the given set of related transforms, running the transforms and re...
QString getName() const override
void * LayerCreationAsyncHandle
void addNonDerivedModel(ModelId)
Add an imported model, i.e.
Layer * createMainModelLayer(LayerFactory::LayerType)
Create and return a new layer of the given type, associated with the current main model (if appropria...
void modelGenerationFailed(QString transformName, QString message)
Layer * createLayer(LayerFactory::LayerType)
Create and return a new layer of the given type, associated with no model.
void performDeferredAlignment(ModelId)
void moreModelsAvailable(vector< ModelId > models) override
void realignModels()
Re-generate alignments for all appropriate models against the main model.
Document()
!! still need to handle command history, documentRestored/documentModified
void alignModels()
Generate alignments for all appropriate models against the main model.
QString getName() const override
void releaseModel(ModelId model)
vector< Layer * > m_primary
void addToLayerViewMap(Layer *, View *)
void addAdditionalModel(ModelId)
Add an extra derived model (returned at the end of processing a transform).
void setPrimaryLayers(vector< Layer * > layers)
void toXmlAsTemplate(QTextStream &, QString indent, QString extraAttributes) const
void unexecute() override
void modelRegenerationFailed(QString layerName, QString transformName, QString message)
virtual ~RemoveLayerCommand()
void removeLayerFromView(View *, Layer *)
Remove the given layer from the given view.
void alignModel(ModelId, bool forceRecalculate=false)
If model is suitable for alignment, align it against the main model and store the alignment in the mo...
ModelId m_mainModel
The model that provides the underlying sample rate, etc.
Layer * createEmptyLayer(LayerFactory::LayerType)
Create and return a new layer of the given type, with an appropriate empty model. ...
std::vector< Layer * > createLayersForDerivedModels(std::vector< ModelId >, QStringList names)
QString getUniqueLayerName(QString candidate)
void layerInAView(Layer *, bool)
void toXml(QTextStream &, QString indent, QString extraAttributes) const override
bool isKnownModel(ModelId) const
Return true if the model id is known to be the main model or one of the other existing models that ca...
void alignmentFailed(ModelId, QString message)
static bool canAlign()
Return true if alignment is supported (i.e.
~AdditionalModelConverter() override
std::set< ModelId > m_alignmentModels
Layer * createDerivedLayer(LayerFactory::LayerType, TransformId)
Create and return a new layer of the given type, associated with the given transform name...
std::map< ModelId, ModelRecord > m_models
Document::LayerCreationHandler * m_handler
A Sonic Visualiser document consists of a set of data models, and also the visualisation layers used ...
void modelGenerationWarning(QString transformName, QString message)
void addLayerToView(View *, Layer *)
Add the given layer to the given view.
void setModel(Layer *, ModelId)
Associate the given model with the given layer.
void removeFromLayerViewMap(Layer *, View *)
void unexecute() override
std::vector< Layer * > createDerivedLayers(const Transforms &, const ModelTransformer::Input &)
Create and return suitable layers for the given transforms, which must be identical apart from the ou...
LayerViewMap m_layerViewMap
AdditionalModelConverter(Document *doc, Document::LayerCreationHandler *handler)
void alignmentComplete(ModelId)
void addAlreadyDerivedModel(const Transform &transform, const ModelTransformer::Input &input, ModelId outputModelToAdd)
Add a derived model associated with the given transform.
void deleteLayer(Layer *, bool force=false)
Delete the given layer, and also its associated model if no longer used by any other layer...
ModelId addDerivedModel(const Transform &transform, const ModelTransformer::Input &input, QString &returnedMessage)
Add a derived model associated with the given transform, running the transform and returning the resu...
std::set< ModelId > m_aggregateModels
Layer * createImportedLayer(ModelId)
Create and return a new layer associated with the given model, and register the model as an imported ...
std::vector< ModelId > addDerivedModels(const Transforms &transforms, const ModelTransformer::Input &input, QString &returnedMessage, AdditionalModelConverter *)