changeset 672:ae7584dbd668 tuning-difference

Provide facility to re-align models
author Chris Cannam
date Fri, 17 May 2019 09:45:12 +0100
parents b6cafe05017d
children d62fd61082a1
files framework/Align.cpp framework/Document.cpp framework/Document.h
diffstat 3 files changed, 63 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/framework/Align.cpp	Thu May 16 15:55:46 2019 +0100
+++ b/framework/Align.cpp	Fri May 17 09:45:12 2019 +0100
@@ -103,24 +103,24 @@
     if (!reference || !rm) return false; // but this should have been tested already
    
     // This involves creating either three or four new models:
-
+    //
     // 1. an AggregateWaveModel to provide the mixdowns of the main
     // model and the new model in its two channels, as input to the
     // MATCH plugin
-
+    //
     // 2a. a SparseTimeValueModel which will be automatically created
     // by FeatureExtractionModelTransformer when running the
     // TuningDifference plugin to receive the relative tuning of the
     // second model (if pitch-aware alignment is enabled in the
     // preferences)
-    
+    //
     // 2b. a SparseTimeValueModel which will be automatically created
     // by FeatureExtractionPluginTransformer when running the MATCH
     // plugin to perform alignment (so containing the alignment path)
-
+    //
     // 3. an AlignmentModel, which stores the path model and carries
     // out alignment lookups on it.
-
+    //
     // The AggregateWaveModel [1] is registered with the document,
     // which deletes it when it is invalidated (when one of its
     // components is deleted). The SparseTimeValueModel [2a] is reused
@@ -130,6 +130,11 @@
     // is attached to the new model we are aligning, which also takes
     // ownership of it. The only one of these models that we need to
     // delete here is the SparseTimeValueModel [2a].
+    //
+    // (We also create a sneaky additional SparseTimeValueModel
+    // temporarily so we can attach completion information to it -
+    // this is quite unnecessary from the perspective of simply
+    // producing the results.)
 
     AggregateWaveModel::ChannelSpecList components;
 
--- a/framework/Document.cpp	Thu May 16 15:55:46 2019 +0100
+++ b/framework/Document.cpp	Fri May 17 09:45:12 2019 +0100
@@ -867,17 +867,13 @@
     if (m_layerViewMap.find(layer) != m_layerViewMap.end() &&
         m_layerViewMap[layer].size() > 0) {
 
-        SVCERR << "WARNING: Document::deleteLayer: Layer "
-                  << layer << " [" << layer->objectName() << "]"
-                  << " is still used in " << m_layerViewMap[layer].size()
-                  << " views!" << endl;
-
         if (force) {
 
-#ifdef DEBUG_DOCUMENT
-            SVCERR << "(force flag set -- deleting from all views)" << endl;
-#endif
-
+            SVDEBUG << "NOTE: Document::deleteLayer: Layer "
+                    << layer << " [" << layer->objectName() << "]"
+                    << " is still used in " << m_layerViewMap[layer].size()
+                    << " views. Force flag set, so removing from them" << endl;
+            
             for (std::set<View *>::iterator j = m_layerViewMap[layer].begin();
                  j != m_layerViewMap[layer].end(); ++j) {
                 // don't use removeLayerFromView, as it issues a command
@@ -888,6 +884,12 @@
             m_layerViewMap.erase(layer);
 
         } else {
+
+            SVCERR << "WARNING: Document::deleteLayer: Layer "
+                   << layer << " [" << layer->objectName() << "]"
+                   << " is still used in " << m_layerViewMap[layer].size()
+                   << " views! Force flag is not set, so not deleting" << endl;
+            
             return;
         }
     }
@@ -1101,14 +1103,10 @@
 }
 
 void
-Document::alignModel(Model *model)
+Document::alignModel(Model *model, bool forceRecalculate)
 {
-    SVDEBUG << "Document::alignModel(" << model << ") (main model is " << m_mainModel << ")" << endl;
-
-    if (!m_mainModel) {
-        SVDEBUG << "(no main model to align to)" << endl;
-        return;
-    }
+    SVDEBUG << "Document::alignModel(" << model << ", " << forceRecalculate
+            << ") (main model is " << m_mainModel << ")" << endl;
 
     RangeSummarisableTimeValueModel *rm = 
         dynamic_cast<RangeSummarisableTimeValueModel *>(model);
@@ -1117,9 +1115,25 @@
         return;
     }
 
+    if (!m_mainModel) {
+        SVDEBUG << "(no main model to align to)" << endl;
+        if (forceRecalculate && rm->getAlignment()) {
+            SVDEBUG << "(but model is aligned, and forceRecalculate is true, "
+                    << "so resetting alignment to nil)" << endl;
+            rm->setAlignment(nullptr);
+        }
+        return;
+    }
+
     if (rm->getAlignmentReference() == m_mainModel) {
-        SVDEBUG << "(model " << rm << " is already aligned to main model " << m_mainModel << ")" << endl;
-        return;
+        SVDEBUG << "(model " << rm << " is already aligned to main model "
+                << m_mainModel << ")" << endl;
+        if (!forceRecalculate) {
+            return;
+        } else {
+            SVDEBUG << "(but forceRecalculate is true, so realigning anyway)"
+                    << endl;
+        }
     }
     
     if (model == m_mainModel) {
@@ -1127,7 +1141,8 @@
         // it possible to distinguish between the reference and any
         // unaligned model just by looking at the model itself,
         // without also knowing what the main model is
-        SVDEBUG << "Document::alignModel(" << model << "): is main model, setting alignment to itself appropriately" << endl;
+        SVDEBUG << "Document::alignModel(" << model
+                << "): is main model, setting alignment to itself" << endl;
         rm->setAlignment(new AlignmentModel(model, model, nullptr));
         return;
     }
@@ -1155,6 +1170,15 @@
     alignModel(m_mainModel);
 }
 
+void
+Document::realignModels()
+{
+    for (const ModelRecord &rec: m_models) {
+        alignModel(rec.model, true);
+    }
+    alignModel(m_mainModel);
+}
+
 Document::AddLayerCommand::AddLayerCommand(Document *d,
                                            View *view,
                                            Layer *layer) :
--- a/framework/Document.h	Thu May 16 15:55:46 2019 +0100
+++ b/framework/Document.h	Fri May 17 09:45:12 2019 +0100
@@ -294,6 +294,12 @@
     void alignModels();
 
     /**
+     * Re-generate alignments for all appropriate models against the
+     * main model.  Existing alignments will be re-calculated.
+     */
+    void realignModels();
+
+    /**
      * Return true if any external files (most obviously audio) failed
      * to be found on load, so that the document is incomplete
      * compared to its saved description.
@@ -338,11 +344,11 @@
 
     /**
      * If model is suitable for alignment, align it against the main
-     * model and store the alignment in the model.  (If the model has
-     * an alignment already for the current main model, leave it
-     * unchanged.)
+     * model and store the alignment in the model. If the model has an
+     * alignment already for the current main model, leave it
+     * unchanged unless forceRecalculate is true.
      */
-    void alignModel(Model *);
+    void alignModel(Model *, bool forceRecalculate = false);
 
     /*
      * Every model that is in use by a layer in the document must be