changeset 702:e4d92aaa689c

Abandon ongoing alignment if asked to re-align before it has completed
author Chris Cannam
date Wed, 14 Aug 2019 13:55:12 +0100
parents e3dc68cc07f9
children 0a43c88cea48 286bd8bb13cc
files framework/Align.cpp framework/Align.h
diffstat 2 files changed, 72 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/framework/Align.cpp	Thu Aug 08 13:34:12 2019 +0100
+++ b/framework/Align.cpp	Wed Aug 14 13:55:12 2019 +0100
@@ -88,6 +88,67 @@
         (tdId == "" || factory->haveTransform(tdId));
 }
 
+void
+Align::abandonOngoingAlignment(ModelId otherId)
+{
+    auto other = ModelById::getAs<RangeSummarisableTimeValueModel>(otherId);
+    if (!other) {
+        return;
+    }
+
+    ModelId alignmentModelId = other->getAlignment();
+    if (alignmentModelId.isNone()) {
+        return;
+    }
+
+    SVCERR << "Align::abandonOngoingAlignment: An alignment is ongoing for model "
+           << otherId << " (alignment model id " << alignmentModelId
+           << "), abandoning it..." << endl;
+    
+    other->setAlignment({});
+
+    for (auto pp: m_pendingProcesses) {
+        if (alignmentModelId == pp.second) {
+            QProcess *process = pp.first;
+            m_pendingProcesses.erase(process);
+            SVCERR << "Align::abandonOngoingAlignment: Killing external "
+                   << "alignment process " << process << "..." << endl;
+            delete process; // kills the process itself
+            break;
+        }
+    }
+
+    if (m_pendingAlignments.find(alignmentModelId) !=
+        m_pendingAlignments.end()) {
+        SVCERR << "Align::abandonOngoingAlignment: Releasing path output model "
+               << m_pendingAlignments[alignmentModelId]
+               << "..." << endl;
+        ModelById::release(m_pendingAlignments[alignmentModelId]);
+        SVCERR << "Align::abandonOngoingAlignment: Dropping alignment model "
+               << alignmentModelId
+               << " from pending alignments..." << endl;
+        m_pendingAlignments.erase(alignmentModelId);
+    }
+
+    for (auto ptd: m_pendingTuningDiffs) {
+        if (alignmentModelId == ptd.second.alignment) {
+            SVCERR << "Align::abandonOngoingAlignment: Releasing preparatory model "
+                   << ptd.second.preparatory << "..." << endl;
+            ModelById::release(ptd.second.preparatory);
+            SVCERR << "Align::abandonOngoingAlignment: Releasing pending tuning-diff model "
+                   << ptd.first << "..." << endl;
+            ModelById::release(ptd.first);
+            SVCERR << "Align::abandonOngoingAlignment: Dropping tuning-diff model "
+                   << ptd.first
+                   << " from pending tuning diffs..." << endl;
+            m_pendingTuningDiffs.erase(ptd.first);
+            break;
+        }
+    }
+
+    SVCERR << "Align::abandonOngoingAlignment: done" << endl;
+}
+
 bool
 Align::alignModelViaTransform(Document *doc,
                               ModelId referenceId,
@@ -102,7 +163,12 @@
         ModelById::getAs<RangeSummarisableTimeValueModel>(otherId);
 
     if (!reference || !other) return false;
-   
+
+    // There may be an alignment already happening; we should stop it,
+    // which we can do by discarding the output models for its
+    // transforms
+    abandonOngoingAlignment(otherId);
+    
     // This involves creating a number of new models:
     //
     // 1. an AggregateWaveModel to provide the mixdowns of the main
@@ -245,8 +311,8 @@
         m_pendingTuningDiffs.end()) {
         SVDEBUG << "NOTE: Align::tuningDifferenceCompletionChanged: Model "
                 << tuningDiffOutputModelId
-                << " not found in pending tuning diff map, probably "
-                << "completed already" << endl;
+                << " not found in pending tuning diff map, presuming "
+                << "completed or abandoned" << endl;
         return;
     }
 
--- a/framework/Align.h	Thu Aug 08 13:34:12 2019 +0100
+++ b/framework/Align.h	Wed Aug 14 13:55:12 2019 +0100
@@ -105,6 +105,8 @@
                                        ModelId, // an AlignmentModel
                                        float tuningFrequency = 0.f);
 
+    void abandonOngoingAlignment(ModelId otherId);
+
     QMutex m_mutex;
 
     struct TuningDiffRec {
@@ -112,7 +114,7 @@
         ModelId alignment; // an AlignmentModel
         ModelId preparatory; // a SparseTimeValueModel
     };
-
+    
     // tuning-difference output model (a SparseTimeValueModel) -> data
     // needed for subsequent alignment
     std::map<ModelId, TuningDiffRec> m_pendingTuningDiffs;