Document.cpp

Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
00002 
00003 /*
00004     Sonic Visualiser
00005     An audio file viewer and annotation editor.
00006     Centre for Digital Music, Queen Mary, University of London.
00007     This file copyright 2006 Chris Cannam and QMUL.
00008     
00009     This program is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU General Public License as
00011     published by the Free Software Foundation; either version 2 of the
00012     License, or (at your option) any later version.  See the file
00013     COPYING included with this distribution for more information.
00014 */
00015 
00016 #include "Document.h"
00017 
00018 #include "data/model/WaveFileModel.h"
00019 #include "data/model/WritableWaveFileModel.h"
00020 #include "data/model/DenseThreeDimensionalModel.h"
00021 #include "data/model/DenseTimeValueModel.h"
00022 #include "layer/Layer.h"
00023 #include "base/CommandHistory.h"
00024 #include "base/Command.h"
00025 #include "view/View.h"
00026 #include "base/PlayParameterRepository.h"
00027 #include "base/PlayParameters.h"
00028 #include "plugin/transform/TransformFactory.h"
00029 #include "plugin/transform/ModelTransformerFactory.h"
00030 #include <QApplication>
00031 #include <QTextStream>
00032 #include <QSettings>
00033 #include <iostream>
00034 
00035 // For alignment:
00036 #include "data/model/AggregateWaveModel.h"
00037 #include "data/model/SparseTimeValueModel.h"
00038 #include "data/model/AlignmentModel.h"
00039 
00040 //#define DEBUG_DOCUMENT 1
00041 
00043 
00044 Document::Document() :
00045     m_mainModel(0),
00046     m_autoAlignment(false)
00047 {
00048     connect(this, SIGNAL(modelAboutToBeDeleted(Model *)),
00049             ModelTransformerFactory::getInstance(),
00050             SLOT(modelAboutToBeDeleted(Model *)));
00051 }
00052 
00053 Document::~Document()
00054 {
00056     //still refer to it in various places that don't have access to
00057     //the document, be nice to fix that
00058 
00059 #ifdef DEBUG_DOCUMENT
00060     std::cerr << "\n\nDocument::~Document: about to clear command history" << std::endl;
00061 #endif
00062     CommandHistory::getInstance()->clear();
00063     
00064 #ifdef DEBUG_DOCUMENT
00065     std::cerr << "Document::~Document: about to delete layers" << std::endl;
00066 #endif
00067     while (!m_layers.empty()) {
00068         deleteLayer(*m_layers.begin(), true);
00069     }
00070 
00071     if (!m_models.empty()) {
00072         std::cerr << "Document::~Document: WARNING: " 
00073                   << m_models.size() << " model(s) still remain -- "
00074                   << "should have been garbage collected when deleting layers"
00075                   << std::endl;
00076         while (!m_models.empty()) {
00077             Model *model = m_models.begin()->first;
00078             if (model == m_mainModel) {
00079                 // just in case!
00080                 std::cerr << "Document::~Document: WARNING: Main model is also"
00081                           << " in models list!" << std::endl;
00082             } else if (model) {
00083                 model->aboutToDelete();
00084                 emit modelAboutToBeDeleted(model);
00085                 delete model;
00086             }
00087             m_models.erase(m_models.begin());
00088         }
00089     }
00090 
00091 #ifdef DEBUG_DOCUMENT
00092     std::cerr << "Document::~Document: About to get rid of main model"
00093               << std::endl;
00094 #endif
00095     if (m_mainModel) {
00096         m_mainModel->aboutToDelete();
00097         emit modelAboutToBeDeleted(m_mainModel);
00098     }
00099 
00100     emit mainModelChanged(0);
00101     delete m_mainModel;
00102 
00103 }
00104 
00105 Layer *
00106 Document::createLayer(LayerFactory::LayerType type)
00107 {
00108     Layer *newLayer = LayerFactory::getInstance()->createLayer(type);
00109     if (!newLayer) return 0;
00110 
00111     newLayer->setObjectName(getUniqueLayerName(newLayer->objectName()));
00112 
00113     m_layers.insert(newLayer);
00114 
00115 #ifdef DEBUG_DOCUMENT
00116     std::cerr << "Document::createLayer: Added layer of type " << type
00117               << ", now have " << m_layers.size() << " layers" << std::endl;
00118 #endif
00119 
00120     emit layerAdded(newLayer);
00121 
00122     return newLayer;
00123 }
00124 
00125 Layer *
00126 Document::createMainModelLayer(LayerFactory::LayerType type)
00127 {
00128     Layer *newLayer = createLayer(type);
00129     if (!newLayer) return 0;
00130     setModel(newLayer, m_mainModel);
00131     return newLayer;
00132 }
00133 
00134 Layer *
00135 Document::createImportedLayer(Model *model)
00136 {
00137     LayerFactory::LayerTypeSet types =
00138         LayerFactory::getInstance()->getValidLayerTypes(model);
00139 
00140     if (types.empty()) {
00141         std::cerr << "WARNING: Document::importLayer: no valid display layer for model" << std::endl;
00142         return 0;
00143     }
00144 
00146     LayerFactory::LayerType type = *types.begin();
00147 
00148     Layer *newLayer = LayerFactory::getInstance()->createLayer(type);
00149     if (!newLayer) return 0;
00150 
00151     newLayer->setObjectName(getUniqueLayerName(newLayer->objectName()));
00152 
00153     addImportedModel(model);
00154     setModel(newLayer, model);
00155 
00157     setChannel(newLayer, -1);
00158 
00159     m_layers.insert(newLayer);
00160 
00161 #ifdef DEBUG_DOCUMENT
00162     std::cerr << "Document::createImportedLayer: Added layer of type " << type
00163               << ", now have " << m_layers.size() << " layers" << std::endl;
00164 #endif
00165 
00166     emit layerAdded(newLayer);
00167     return newLayer;
00168 }
00169 
00170 Layer *
00171 Document::createEmptyLayer(LayerFactory::LayerType type)
00172 {
00173     if (!m_mainModel) return 0;
00174 
00175     Model *newModel =
00176         LayerFactory::getInstance()->createEmptyModel(type, m_mainModel);
00177     if (!newModel) return 0;
00178 
00179     Layer *newLayer = createLayer(type);
00180     if (!newLayer) {
00181         delete newModel;
00182         return 0;
00183     }
00184 
00185     addImportedModel(newModel);
00186     setModel(newLayer, newModel);
00187 
00188     return newLayer;
00189 }
00190 
00191 Layer *
00192 Document::createDerivedLayer(LayerFactory::LayerType type,
00193                              TransformId transform)
00194 {
00195     Layer *newLayer = createLayer(type);
00196     if (!newLayer) return 0;
00197 
00198     newLayer->setObjectName(getUniqueLayerName
00199                             (TransformFactory::getInstance()->
00200                              getTransformFriendlyName(transform)));
00201 
00202     return newLayer;
00203 }
00204 
00205 Layer *
00206 Document::createDerivedLayer(const Transform &transform,
00207                              const ModelTransformer::Input &input)
00208 {
00209     QString message;
00210     Model *newModel = addDerivedModel(transform, input, message);
00211     if (!newModel) {
00212         emit modelGenerationFailed(transform.getIdentifier(), message);
00213         return 0;
00214     } else if (message != "") {
00215         emit modelGenerationWarning(transform.getIdentifier(), message);
00216     }
00217 
00218     LayerFactory::LayerTypeSet types =
00219         LayerFactory::getInstance()->getValidLayerTypes(newModel);
00220 
00221     if (types.empty()) {
00222         std::cerr << "WARNING: Document::createLayerForTransformer: no valid display layer for output of transform " << transform.getIdentifier().toStdString() << std::endl;
00223         delete newModel;
00224         return 0;
00225     }
00226 
00228 
00229     Layer *newLayer = createLayer(*types.begin());
00230     setModel(newLayer, newModel);
00231 
00233     //can be edited without affecting other layers that are based on
00234     //the same model.  Unfortunately we can't just clone it now,
00235     //because it probably hasn't been completed yet -- the transform
00236     //runs in the background.  Maybe the transform has to handle
00237     //cloning and cacheing models itself.
00238     //
00239     // Once we do clone models here, of course, we'll have to avoid
00240     // leaking them too.
00241     //
00242     // We want the user to be able to add a model to a second layer
00243     // _while it's still being calculated in the first_ and have it
00244     // work quickly.  That means we need to put the same physical
00245     // model pointer in both layers, so they can't actually be cloned.
00246     
00247     if (newLayer) {
00248         newLayer->setObjectName(getUniqueLayerName
00249                                 (TransformFactory::getInstance()->
00250                                  getTransformFriendlyName
00251                                  (transform.getIdentifier())));
00252     }
00253 
00254     emit layerAdded(newLayer);
00255     return newLayer;
00256 }
00257 
00258 void
00259 Document::setMainModel(WaveFileModel *model)
00260 {
00261     Model *oldMainModel = m_mainModel;
00262     m_mainModel = model;
00263 
00264     emit modelAdded(m_mainModel);
00265 
00266     std::vector<Layer *> obsoleteLayers;
00267     std::set<QString> failedTransformers;
00268 
00269     // We need to ensure that no layer is left using oldMainModel or
00270     // any of the old derived models as its model.  Either replace the
00271     // model, or delete the layer for each layer that is currently
00272     // using one of these.  Carry out this replacement before we
00273     // delete any of the models.
00274 
00275 #ifdef DEBUG_DOCUMENT
00276     std::cerr << "Document::setMainModel: Have "
00277               << m_layers.size() << " layers" << std::endl;
00278 #endif
00279 
00280     for (LayerSet::iterator i = m_layers.begin(); i != m_layers.end(); ++i) {
00281 
00282         Layer *layer = *i;
00283         Model *model = layer->getModel();
00284 
00285 #ifdef DEBUG_DOCUMENT
00286         std::cerr << "Document::setMainModel: inspecting model "
00287                   << (model ? model->objectName().toStdString() : "(null)") << " in layer "
00288                   << layer->objectName().toStdString() << std::endl;
00289 #endif
00290 
00291         if (model == oldMainModel) {
00292 #ifdef DEBUG_DOCUMENT
00293             std::cerr << "... it uses the old main model, replacing" << std::endl;
00294 #endif
00295             LayerFactory::getInstance()->setModel(layer, m_mainModel);
00296             continue;
00297         }
00298 
00299         if (model && (m_models.find(model) == m_models.end())) {
00300             std::cerr << "WARNING: Document::setMainModel: Unknown model "
00301                       << model << " in layer " << layer << std::endl;
00302             // get rid of this hideous degenerate
00303             obsoleteLayers.push_back(layer);
00304             continue;
00305         }
00306             
00307         if (m_models[model].source &&
00308             (m_models[model].source == oldMainModel)) {
00309 
00310 #ifdef DEBUG_DOCUMENT
00311             std::cerr << "... it uses a model derived from the old main model, regenerating" << std::endl;
00312 #endif
00313 
00314             // This model was derived from the previous main
00315             // model: regenerate it.
00316             
00317             const Transform &transform = m_models[model].transform;
00318             QString transformId = transform.getIdentifier();
00319             
00321             //the main model has changed.
00322 
00323             QString message;
00324             Model *replacementModel =
00325                 addDerivedModel(transform,
00326                                 ModelTransformer::Input
00327                                 (m_mainModel, m_models[model].channel),
00328                                 message);
00329             
00330             if (!replacementModel) {
00331                 std::cerr << "WARNING: Document::setMainModel: Failed to regenerate model for transform \""
00332                           << transformId.toStdString() << "\"" << " in layer " << layer << std::endl;
00333                 if (failedTransformers.find(transformId)
00334                     == failedTransformers.end()) {
00335                     emit modelRegenerationFailed(layer->objectName(),
00336                                                  transformId,
00337                                                  message);
00338                     failedTransformers.insert(transformId);
00339                 }
00340                 obsoleteLayers.push_back(layer);
00341             } else {
00342                 if (message != "") {
00343                     emit modelRegenerationWarning(layer->objectName(),
00344                                                   transformId,
00345                                                   message);
00346                 }
00347 #ifdef DEBUG_DOCUMENT
00348                 std::cerr << "Replacing model " << model << " (type "
00349                           << typeid(*model).name() << ") with model "
00350                           << replacementModel << " (type "
00351                           << typeid(*replacementModel).name() << ") in layer "
00352                           << layer << " (name " << layer->objectName().toStdString() << ")"
00353                           << std::endl;
00354 #endif
00355                 RangeSummarisableTimeValueModel *rm =
00356                     dynamic_cast<RangeSummarisableTimeValueModel *>(replacementModel);
00357 #ifdef DEBUG_DOCUMENT
00358                 if (rm) {
00359                     std::cerr << "new model has " << rm->getChannelCount() << " channels " << std::endl;
00360                 } else {
00361                     std::cerr << "new model is not a RangeSummarisableTimeValueModel!" << std::endl;
00362                 }
00363 #endif
00364                 setModel(layer, replacementModel);
00365             }
00366         }           
00367     }
00368 
00369     for (size_t k = 0; k < obsoleteLayers.size(); ++k) {
00370         deleteLayer(obsoleteLayers[k], true);
00371     }
00372 
00373     for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) {
00374 
00375         if (m_autoAlignment) {
00376 
00377             alignModel(i->first);
00378 
00379         } else if (oldMainModel &&
00380                    (i->first->getAlignmentReference() == oldMainModel)) {
00381 
00382             alignModel(i->first);
00383         }
00384     }
00385 
00386     if (oldMainModel) {
00387         oldMainModel->aboutToDelete();
00388         emit modelAboutToBeDeleted(oldMainModel);
00389     }
00390 
00391     if (m_autoAlignment) {
00392         alignModel(m_mainModel);
00393     }
00394 
00395     emit mainModelChanged(m_mainModel);
00396 
00397     delete oldMainModel;
00398 }
00399 
00400 void
00401 Document::addDerivedModel(const Transform &transform,
00402                           const ModelTransformer::Input &input,
00403                           Model *outputModelToAdd)
00404 {
00405     if (m_models.find(outputModelToAdd) != m_models.end()) {
00406         std::cerr << "WARNING: Document::addDerivedModel: Model already added"
00407                   << std::endl;
00408         return;
00409     }
00410 
00411 #ifdef DEBUG_DOCUMENT
00412     std::cerr << "Document::addDerivedModel: source is " << input.getModel() << " \"" << input.getModel()->objectName().toStdString() << "\"" << std::endl;
00413 #endif
00414 
00415     ModelRecord rec;
00416     rec.source = input.getModel();
00417     rec.channel = input.getChannel();
00418     rec.transform = transform;
00419     rec.refcount = 0;
00420 
00421     outputModelToAdd->setSourceModel(input.getModel());
00422 
00423     m_models[outputModelToAdd] = rec;
00424 
00425     emit modelAdded(outputModelToAdd);
00426 }
00427 
00428 
00429 void
00430 Document::addImportedModel(Model *model)
00431 {
00432     if (m_models.find(model) != m_models.end()) {
00433         std::cerr << "WARNING: Document::addImportedModel: Model already added"
00434                   << std::endl;
00435         return;
00436     }
00437 
00438     ModelRecord rec;
00439     rec.source = 0;
00440     rec.refcount = 0;
00441 
00442     m_models[model] = rec;
00443 
00444     if (m_autoAlignment) alignModel(model);
00445 
00446     emit modelAdded(model);
00447 }
00448 
00449 Model *
00450 Document::addDerivedModel(const Transform &transform,
00451                           const ModelTransformer::Input &input,
00452                           QString &message)
00453 {
00454     Model *model = 0;
00455 
00456     for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) {
00457         if (i->second.transform == transform &&
00458             i->second.source == input.getModel() && 
00459             i->second.channel == input.getChannel()) {
00460             return i->first;
00461         }
00462     }
00463 
00464     model = ModelTransformerFactory::getInstance()->transform
00465         (transform, input, message);
00466 
00467     // The transform we actually used was presumably identical to the
00468     // one asked for, except that the version of the plugin may
00469     // differ.  It's possible that the returned message contains a
00470     // warning about this; that doesn't concern us here, but we do
00471     // need to ensure that the transform we remember is correct for
00472     // what was actually applied, with the current plugin version.
00473 
00474     Transform applied = transform;
00475     applied.setPluginVersion
00476         (TransformFactory::getInstance()->
00477          getDefaultTransformFor(transform.getIdentifier(),
00478                                 lrintf(transform.getSampleRate()))
00479          .getPluginVersion());
00480 
00481     if (!model) {
00482         std::cerr << "WARNING: Document::addDerivedModel: no output model for transform " << transform.getIdentifier().toStdString() << std::endl;
00483     } else {
00484         addDerivedModel(applied, input, model);
00485     }
00486 
00487     return model;
00488 }
00489 
00490 void
00491 Document::releaseModel(Model *model) // Will _not_ release main model!
00492 {
00493     if (model == 0) {
00494         return;
00495     }
00496 
00497     if (model == m_mainModel) {
00498         return;
00499     }
00500 
00501     bool toDelete = false;
00502 
00503     if (m_models.find(model) != m_models.end()) {
00504         
00505         if (m_models[model].refcount == 0) {
00506             std::cerr << "WARNING: Document::releaseModel: model " << model
00507                       << " reference count is zero already!" << std::endl;
00508         } else {
00509             if (--m_models[model].refcount == 0) {
00510                 toDelete = true;
00511             }
00512         }
00513     } else { 
00514         std::cerr << "WARNING: Document::releaseModel: Unfound model "
00515                   << model << std::endl;
00516         toDelete = true;
00517     }
00518 
00519     if (toDelete) {
00520 
00521         int sourceCount = 0;
00522 
00523         for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) {
00524             if (i->second.source == model) {
00525                 ++sourceCount;
00526                 i->second.source = 0;
00527             }
00528         }
00529 
00530         if (sourceCount > 0) {
00531             std::cerr << "Document::releaseModel: Deleting model "
00532                       << model << " even though it is source for "
00533                       << sourceCount << " other derived model(s) -- resetting "
00534                       << "their source fields appropriately" << std::endl;
00535         }
00536 
00537         model->aboutToDelete();
00538         emit modelAboutToBeDeleted(model);
00539         m_models.erase(model);
00540         delete model;
00541     }
00542 }
00543 
00544 void
00545 Document::deleteLayer(Layer *layer, bool force)
00546 {
00547     if (m_layerViewMap.find(layer) != m_layerViewMap.end() &&
00548         m_layerViewMap[layer].size() > 0) {
00549 
00550         std::cerr << "WARNING: Document::deleteLayer: Layer "
00551                   << layer << " [" << layer->objectName().toStdString() << "]"
00552                   << " is still used in " << m_layerViewMap[layer].size()
00553                   << " views!" << std::endl;
00554 
00555         if (force) {
00556 
00557 #ifdef DEBUG_DOCUMENT
00558             std::cerr << "(force flag set -- deleting from all views)" << std::endl;
00559 #endif
00560 
00561             for (std::set<View *>::iterator j = m_layerViewMap[layer].begin();
00562                  j != m_layerViewMap[layer].end(); ++j) {
00563                 // don't use removeLayerFromView, as it issues a command
00564                 layer->setLayerDormant(*j, true);
00565                 (*j)->removeLayer(layer);
00566             }
00567             
00568             m_layerViewMap.erase(layer);
00569 
00570         } else {
00571             return;
00572         }
00573     }
00574 
00575     if (m_layers.find(layer) == m_layers.end()) {
00576         std::cerr << "Document::deleteLayer: Layer "
00577                   << layer << " does not exist, or has already been deleted "
00578                   << "(this may not be as serious as it sounds)" << std::endl;
00579         return;
00580     }
00581 
00582     m_layers.erase(layer);
00583 
00584     std::cerr << "Document::deleteLayer: Removing, now have "
00585               << m_layers.size() << " layers" << std::endl;
00586 
00587     releaseModel(layer->getModel());
00588     emit layerRemoved(layer);
00589     emit layerAboutToBeDeleted(layer);
00590     delete layer;
00591 }
00592 
00593 void
00594 Document::setModel(Layer *layer, Model *model)
00595 {
00596     if (model && 
00597         model != m_mainModel &&
00598         m_models.find(model) == m_models.end()) {
00599         std::cerr << "ERROR: Document::setModel: Layer " << layer
00600                   << " (\"" << layer->objectName().toStdString()
00601                   << "\") wants to use unregistered model " << model
00602                   << ": register the layer's model before setting it!"
00603                   << std::endl;
00604         return;
00605     }
00606 
00607     Model *previousModel = layer->getModel();
00608 
00609     if (previousModel == model) {
00610         std::cerr << "WARNING: Document::setModel: Layer " << layer << " (\""
00611                   << layer->objectName().toStdString()
00612                   << "\") is already set to model "
00613                   << model << " (\""
00614                   << (model ? model->objectName().toStdString() : "(null)")
00615                   << "\")" << std::endl;
00616         return;
00617     }
00618 
00619     if (model && model != m_mainModel) {
00620         m_models[model].refcount ++;
00621     }
00622 
00623     if (model && previousModel) {
00624         PlayParameterRepository::getInstance()->copyParameters
00625             (previousModel, model);
00626     }
00627 
00628     LayerFactory::getInstance()->setModel(layer, model);
00629 
00630     if (previousModel) {
00631         releaseModel(previousModel);
00632     }
00633 }
00634 
00635 void
00636 Document::setChannel(Layer *layer, int channel)
00637 {
00638     LayerFactory::getInstance()->setChannel(layer, channel);
00639 }
00640 
00641 void
00642 Document::addLayerToView(View *view, Layer *layer)
00643 {
00644     Model *model = layer->getModel();
00645     if (!model) {
00646 #ifdef DEBUG_DOCUMENT
00647         std::cerr << "Document::addLayerToView: Layer (\""
00648                   << layer->objectName().toStdString()
00649                   << "\") with no model being added to view: "
00650                   << "normally you want to set the model first" << std::endl;
00651 #endif
00652     } else {
00653         if (model != m_mainModel &&
00654             m_models.find(model) == m_models.end()) {
00655             std::cerr << "ERROR: Document::addLayerToView: Layer " << layer
00656                       << " has unregistered model " << model
00657                       << " -- register the layer's model before adding the layer!" << std::endl;
00658             return;
00659         }
00660     }
00661 
00662     CommandHistory::getInstance()->addCommand
00663         (new Document::AddLayerCommand(this, view, layer));
00664 }
00665 
00666 void
00667 Document::removeLayerFromView(View *view, Layer *layer)
00668 {
00669     CommandHistory::getInstance()->addCommand
00670         (new Document::RemoveLayerCommand(this, view, layer));
00671 }
00672 
00673 void
00674 Document::addToLayerViewMap(Layer *layer, View *view)
00675 {
00676     bool firstView = (m_layerViewMap.find(layer) == m_layerViewMap.end() ||
00677                       m_layerViewMap[layer].empty());
00678 
00679     if (m_layerViewMap[layer].find(view) !=
00680         m_layerViewMap[layer].end()) {
00681         std::cerr << "WARNING: Document::addToLayerViewMap:"
00682                   << " Layer " << layer << " -> view " << view << " already in"
00683                   << " layer view map -- internal inconsistency" << std::endl;
00684     }
00685 
00686     m_layerViewMap[layer].insert(view);
00687 
00688     if (firstView) emit layerInAView(layer, true);
00689 }
00690     
00691 void
00692 Document::removeFromLayerViewMap(Layer *layer, View *view)
00693 {
00694     if (m_layerViewMap[layer].find(view) ==
00695         m_layerViewMap[layer].end()) {
00696         std::cerr << "WARNING: Document::removeFromLayerViewMap:"
00697                   << " Layer " << layer << " -> view " << view << " not in"
00698                   << " layer view map -- internal inconsistency" << std::endl;
00699     }
00700 
00701     m_layerViewMap[layer].erase(view);
00702 
00703     if (m_layerViewMap[layer].empty()) {
00704         m_layerViewMap.erase(layer);
00705         emit layerInAView(layer, false);
00706     }
00707 }
00708 
00709 QString
00710 Document::getUniqueLayerName(QString candidate)
00711 {
00712     for (int count = 1; ; ++count) {
00713 
00714         QString adjusted =
00715             (count > 1 ? QString("%1 <%2>").arg(candidate).arg(count) :
00716              candidate);
00717         
00718         bool duplicate = false;
00719 
00720         for (LayerSet::iterator i = m_layers.begin(); i != m_layers.end(); ++i) {
00721             if ((*i)->objectName() == adjusted) {
00722                 duplicate = true;
00723                 break;
00724             }
00725         }
00726 
00727         if (!duplicate) return adjusted;
00728     }
00729 }
00730 
00731 std::vector<Model *>
00732 Document::getTransformInputModels()
00733 {
00734     std::vector<Model *> models;
00735 
00736     if (!m_mainModel) return models;
00737 
00738     models.push_back(m_mainModel);
00739 
00741 
00742     for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) {
00743 
00744         Model *model = i->first;
00745         if (!model || model == m_mainModel) continue;
00746         DenseTimeValueModel *dtvm = dynamic_cast<DenseTimeValueModel *>(model);
00747         
00748         if (dtvm) {
00749             models.push_back(dtvm);
00750         }
00751     }
00752 
00753     return models;
00754 }
00755 
00756 bool
00757 Document::isKnownModel(const Model *model) const
00758 {
00759     if (model == m_mainModel) return true;
00760     return (m_models.find(const_cast<Model *>(model)) != m_models.end());
00761 }
00762 
00763 TransformId
00764 Document::getAlignmentTransformName()
00765 {
00766     QSettings settings;
00767     settings.beginGroup("Alignment");
00768     TransformId id =
00769         settings.value("transform-id",
00770                        "vamp:match-vamp-plugin:match:path").toString();
00771     settings.endGroup();
00772     return id;
00773 }
00774 
00775 bool
00776 Document::canAlign() 
00777 {
00778     TransformId id = getAlignmentTransformName();
00779     TransformFactory *factory = TransformFactory::getInstance();
00780     return factory->haveTransform(id);
00781 }
00782 
00783 void
00784 Document::alignModel(Model *model)
00785 {
00786     if (!m_mainModel) return;
00787 
00788     RangeSummarisableTimeValueModel *rm = 
00789         dynamic_cast<RangeSummarisableTimeValueModel *>(model);
00790     if (!rm) return;
00791 
00792     if (rm->getAlignmentReference() == m_mainModel) {
00793         std::cerr << "Document::alignModel: model " << rm << " is already aligned to main model " << m_mainModel << std::endl;
00794         return;
00795     }
00796     
00797     if (model == m_mainModel) {
00798         // The reference has an empty alignment to itself.  This makes
00799         // it possible to distinguish between the reference and any
00800         // unaligned model just by looking at the model itself,
00801         // without also knowing what the main model is
00802         std::cerr << "Document::alignModel(" << model << "): is main model, setting appropriately" << std::endl;
00803         rm->setAlignment(new AlignmentModel(model, model, 0, 0));
00804         return;
00805     }
00806 
00807     // This involves creating three new models:
00808 
00809     // 1. an AggregateWaveModel to provide the mixdowns of the main
00810     // model and the new model in its two channels, as input to the
00811     // MATCH plugin
00812 
00813     // 2. a SparseTimeValueModel, which is the model automatically
00814     // created by FeatureExtractionPluginTransformer when running the
00815     // MATCH plugin (thus containing the alignment path)
00816 
00817     // 3. an AlignmentModel, which stores the path model and carries
00818     // out alignment lookups on it.
00819 
00820     // The first two of these are provided as arguments to the
00821     // constructor for the third, which takes responsibility for
00822     // deleting them.  The AlignmentModel, meanwhile, is passed to the
00823     // new model we are aligning, which also takes responsibility for
00824     // it.  We should not have to delete any of these new models here.
00825 
00826     AggregateWaveModel::ChannelSpecList components;
00827 
00828     components.push_back(AggregateWaveModel::ModelChannelSpec
00829                          (m_mainModel, -1));
00830 
00831     components.push_back(AggregateWaveModel::ModelChannelSpec
00832                          (rm, -1));
00833 
00834     Model *aggregate = new AggregateWaveModel(components);
00835 
00836     TransformId id = "vamp:match-vamp-plugin:match:path"; 
00837     
00838     TransformFactory *tf = TransformFactory::getInstance();
00839 
00840     Transform transform = tf->getDefaultTransformFor
00841         (id, aggregate->getSampleRate());
00842 
00843     transform.setStepSize(transform.getBlockSize()/2);
00844     transform.setParameter("serialise", 1);
00845 
00846     std::cerr << "Document::alignModel: Alignment transform step size " << transform.getStepSize() << ", block size " << transform.getBlockSize() << std::endl;
00847 
00848     ModelTransformerFactory *mtf = ModelTransformerFactory::getInstance();
00849 
00850     QString message;
00851     Model *transformOutput = mtf->transform(transform, aggregate, message);
00852 
00853     if (!transformOutput) {
00854         transform.setStepSize(0);
00855         transformOutput = mtf->transform(transform, aggregate, message);
00856     }
00857 
00858     SparseTimeValueModel *path = dynamic_cast<SparseTimeValueModel *>
00859         (transformOutput);
00860 
00861     if (!path) {
00862         std::cerr << "Document::alignModel: ERROR: Failed to create alignment path (no MATCH plugin?)" << std::endl;
00863         emit alignmentFailed(id, message);
00864         delete transformOutput;
00865         delete aggregate;
00866         return;
00867     }
00868 
00869     AlignmentModel *alignmentModel = new AlignmentModel
00870         (m_mainModel, model, aggregate, path);
00871 
00872     rm->setAlignment(alignmentModel);
00873 }
00874 
00875 void
00876 Document::alignModels()
00877 {
00878     for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) {
00879         alignModel(i->first);
00880     }
00881     alignModel(m_mainModel);
00882 }
00883 
00884 Document::AddLayerCommand::AddLayerCommand(Document *d,
00885                                            View *view,
00886                                            Layer *layer) :
00887     m_d(d),
00888     m_view(view),
00889     m_layer(layer),
00890     m_name(qApp->translate("AddLayerCommand", "Add %1 Layer").arg(layer->objectName())),
00891     m_added(false)
00892 {
00893 }
00894 
00895 Document::AddLayerCommand::~AddLayerCommand()
00896 {
00897 #ifdef DEBUG_DOCUMENT
00898     std::cerr << "Document::AddLayerCommand::~AddLayerCommand" << std::endl;
00899 #endif
00900     if (!m_added) {
00901         m_d->deleteLayer(m_layer);
00902     }
00903 }
00904 
00905 void
00906 Document::AddLayerCommand::execute()
00907 {
00908     for (int i = 0; i < m_view->getLayerCount(); ++i) {
00909         if (m_view->getLayer(i) == m_layer) {
00910             // already there
00911             m_layer->setLayerDormant(m_view, false);
00912             m_added = true;
00913             return;
00914         }
00915     }
00916 
00917     m_view->addLayer(m_layer);
00918     m_layer->setLayerDormant(m_view, false);
00919 
00920     m_d->addToLayerViewMap(m_layer, m_view);
00921     m_added = true;
00922 }
00923 
00924 void
00925 Document::AddLayerCommand::unexecute()
00926 {
00927     m_view->removeLayer(m_layer);
00928     m_layer->setLayerDormant(m_view, true);
00929 
00930     m_d->removeFromLayerViewMap(m_layer, m_view);
00931     m_added = false;
00932 }
00933 
00934 Document::RemoveLayerCommand::RemoveLayerCommand(Document *d,
00935                                                  View *view,
00936                                                  Layer *layer) :
00937     m_d(d),
00938     m_view(view),
00939     m_layer(layer),
00940     m_name(qApp->translate("RemoveLayerCommand", "Delete %1 Layer").arg(layer->objectName())),
00941     m_added(true)
00942 {
00943 }
00944 
00945 Document::RemoveLayerCommand::~RemoveLayerCommand()
00946 {
00947 #ifdef DEBUG_DOCUMENT
00948     std::cerr << "Document::RemoveLayerCommand::~RemoveLayerCommand" << std::endl;
00949 #endif
00950     if (!m_added) {
00951         m_d->deleteLayer(m_layer);
00952     }
00953 }
00954 
00955 void
00956 Document::RemoveLayerCommand::execute()
00957 {
00958     bool have = false;
00959     for (int i = 0; i < m_view->getLayerCount(); ++i) {
00960         if (m_view->getLayer(i) == m_layer) {
00961             have = true;
00962             break;
00963         }
00964     }
00965 
00966     if (!have) { // not there!
00967         m_layer->setLayerDormant(m_view, true);
00968         m_added = false;
00969         return;
00970     }
00971 
00972     m_view->removeLayer(m_layer);
00973     m_layer->setLayerDormant(m_view, true);
00974 
00975     m_d->removeFromLayerViewMap(m_layer, m_view);
00976     m_added = false;
00977 }
00978 
00979 void
00980 Document::RemoveLayerCommand::unexecute()
00981 {
00982     m_view->addLayer(m_layer);
00983     m_layer->setLayerDormant(m_view, false);
00984 
00985     m_d->addToLayerViewMap(m_layer, m_view);
00986     m_added = true;
00987 }
00988 
00989 void
00990 Document::toXml(QTextStream &out, QString indent, QString extraAttributes) const
00991 {
00992     out << indent + QString("<data%1%2>\n")
00993         .arg(extraAttributes == "" ? "" : " ").arg(extraAttributes);
00994 
00995     if (m_mainModel) {
00996         m_mainModel->toXml(out, indent + "  ", "mainModel=\"true\"");
00997     }
00998 
00999     // Models that are not used in a layer that is in a view should
01000     // not be written.  Get our list of required models first.
01001 
01002     std::set<const Model *> used;
01003 
01004     for (LayerViewMap::const_iterator i = m_layerViewMap.begin();
01005          i != m_layerViewMap.end(); ++i) {
01006 
01007         if (i->first && !i->second.empty() && i->first->getModel()) {
01008             used.insert(i->first->getModel());
01009         }
01010     }
01011 
01012     for (ModelMap::const_iterator i = m_models.begin();
01013          i != m_models.end(); ++i) {
01014 
01015         const Model *model = i->first;
01016         const ModelRecord &rec = i->second;
01017 
01018         if (used.find(model) == used.end()) continue;
01019         
01020         // We need an intelligent way to determine which models need
01021         // to be streamed (i.e. have been edited, or are small) and
01022         // which should not be (i.e. remain as generated by a
01023         // transform, and are large).
01024         //
01025         // At the moment we can get away with deciding not to stream
01026         // dense 3d models or writable wave file models, provided they
01027         // were generated from a transform, because at the moment there
01028         // is no way to edit those model types so it should be safe to
01029         // regenerate them.  That won't always work in future though.
01030         // It would be particularly nice to be able to ask the user,
01031         // as well as making an intelligent guess.
01032 
01033         bool writeModel = true;
01034         bool haveDerivation = false;
01035 
01036         if (rec.source && rec.transform.getIdentifier() != "") {
01037             haveDerivation = true;
01038         } 
01039 
01040         if (haveDerivation) {
01041             if (dynamic_cast<const WritableWaveFileModel *>(model)) {
01042                 writeModel = false;
01043             } else if (dynamic_cast<const DenseThreeDimensionalModel *>(model)) {
01044                 writeModel = false;
01045             }
01046         }
01047 
01048         if (writeModel) {
01049             i->first->toXml(out, indent + "  ");
01050         }
01051 
01052         if (haveDerivation) {
01053             writeBackwardCompatibleDerivation(out, indent + "  ",
01054                                               i->first, rec);
01055         }
01056 
01058         PlayParameters *playParameters =
01059             PlayParameterRepository::getInstance()->getPlayParameters(i->first);
01060         if (playParameters) {
01061             playParameters->toXml
01062                 (out, indent + "  ",
01063                  QString("model=\"%1\"")
01064                  .arg(XmlExportable::getObjectExportId(i->first)));
01065         }
01066     }
01067             
01068     for (LayerSet::const_iterator i = m_layers.begin();
01069          i != m_layers.end(); ++i) {
01070 
01071         (*i)->toXml(out, indent + "  ");
01072     }
01073 
01074     out << indent + "</data>\n";
01075 }
01076 
01077 void
01078 Document::writeBackwardCompatibleDerivation(QTextStream &out, QString indent,
01079                                             Model *targetModel,
01080                                             const ModelRecord &rec) const
01081 {
01082     // There is a lot of redundancy in the XML we output here, because
01083     // we want it to work with older SV session file reading code as
01084     // well.
01085     //
01086     // Formerly, a transform was described using a derivation element
01087     // which set out the source and target models, execution context
01088     // (step size, input channel etc) and transform id, containing a
01089     // plugin element which set out the transform parameters and so
01090     // on.  (The plugin element came from a "configurationXml" string
01091     // obtained from PluginXml.)
01092     // 
01093     // This has been replaced by a derivation element setting out the
01094     // source and target models and input channel, containing a
01095     // transform element which sets out everything in the Transform.
01096     //
01097     // In order to retain compatibility with older SV code, however,
01098     // we have to write out the same stuff into the derivation as
01099     // before, and manufacture an appropriate plugin element as well
01100     // as the transform element.  In order that newer code knows it's
01101     // dealing with a newer format, we will also write an attribute
01102     // 'type="transform"' in the derivation element.
01103 
01104     const Transform &transform = rec.transform;
01105 
01106     // Just for reference, this is what we would write if we didn't
01107     // have to be backward compatible:
01108     //
01109     //    out << indent
01110     //        << QString("<derivation type=\"transform\" source=\"%1\" "
01111     //                   "model=\"%2\" channel=\"%3\">\n")
01112     //        .arg(XmlExportable::getObjectExportId(rec.source))
01113     //        .arg(XmlExportable::getObjectExportId(targetModel))
01114     //        .arg(rec.channel);
01115     //
01116     //    transform.toXml(out, indent + "  ");
01117     //
01118     //    out << indent << "</derivation>\n";
01119     // 
01120     // Unfortunately, we can't just do that.  So we do this...
01121 
01122     QString extentsAttributes;
01123     if (transform.getStartTime() != RealTime::zeroTime ||
01124         transform.getDuration() != RealTime::zeroTime) {
01125         extentsAttributes = QString("startFrame=\"%1\" duration=\"%2\" ")
01126             .arg(RealTime::realTime2Frame(transform.getStartTime(),
01127                                           targetModel->getSampleRate()))
01128             .arg(RealTime::realTime2Frame(transform.getDuration(),
01129                                           targetModel->getSampleRate()));
01130     }
01131             
01132     out << indent;
01133     out << QString("<derivation type=\"transform\" source=\"%1\" "
01134                    "model=\"%2\" channel=\"%3\" domain=\"%4\" "
01135                    "stepSize=\"%5\" blockSize=\"%6\" %7windowType=\"%8\" "
01136                    "transform=\"%9\">\n")
01137         .arg(XmlExportable::getObjectExportId(rec.source))
01138         .arg(XmlExportable::getObjectExportId(targetModel))
01139         .arg(rec.channel)
01140         .arg(TransformFactory::getInstance()->getTransformInputDomain
01141              (transform.getIdentifier()))
01142         .arg(transform.getStepSize())
01143         .arg(transform.getBlockSize())
01144         .arg(extentsAttributes)
01145         .arg(int(transform.getWindowType()))
01146         .arg(XmlExportable::encodeEntities(transform.getIdentifier()));
01147 
01148     transform.toXml(out, indent + "  ");
01149     
01150     out << indent << "  "
01151         << TransformFactory::getInstance()->getPluginConfigurationXml(transform);
01152 
01153     out << indent << "</derivation>\n";
01154 }
01155 

Generated on Wed Feb 20 15:45:25 2008 for SonicVisualiser by  doxygen 1.5.1