changeset 781:b651dc5ff555

Add subsequence option all over the place
author Chris Cannam
date Thu, 16 Jul 2020 18:01:50 +0100
parents 8fa98f89eda8
children 700fc9e4852d
files align/Align.cpp align/Align.h align/MATCHAligner.cpp align/MATCHAligner.h align/TransformDTWAligner.cpp align/TransformDTWAligner.h
diffstat 6 files changed, 74 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/align/Align.cpp	Wed Jul 01 15:34:46 2020 +0100
+++ b/align/Align.cpp	Thu Jul 16 18:01:50 2020 +0100
@@ -140,6 +140,7 @@
             aligner = make_shared<MATCHAligner>(doc,
                                                 reference,
                                                 toAlign,
+                                                getUseSubsequenceAlignment(),
                                                 withTuningDifference);
             break;
         }
@@ -157,6 +158,7 @@
                 (doc,
                  reference,
                  toAlign,
+                 getUseSubsequenceAlignment(),
                  transform,
                  [](double prev, double curr) {
                      RiseFallDTW::Value v;
@@ -229,6 +231,14 @@
     return Transform(xml);
 }
 
+bool
+Align::getUseSubsequenceAlignment()
+{
+    QSettings settings;
+    settings.beginGroup("Alignment");
+    return settings.value("alignment-subsequence", false).toBool();
+}
+
 void
 Align::setAlignmentPreference(AlignmentType type)
 {
@@ -257,6 +267,15 @@
     settings.endGroup();
 }
 
+void
+Align::setUseSubsequenceAlignment(bool subsequence)
+{
+    QSettings settings;
+    settings.beginGroup("Alignment");
+    settings.setValue("alignment-subsequence", subsequence);
+    settings.endGroup();
+}
+
 bool
 Align::canAlign() 
 {
--- a/align/Align.h	Wed Jul 01 15:34:46 2020 +0100
+++ b/align/Align.h	Thu Jul 16 18:01:50 2020 +0100
@@ -115,6 +115,21 @@
      * TransformDrivenDTWAlignment in order to change this setting.
      */ 
     static void setPreferredAlignmentTransform(Transform transform);
+
+    /**
+     * Return true if subsequence alignment is preferred. In this case
+     * the toAlign model is aligned to the best-matching subsequence
+     * of the reference model rather than to the whole reference. This
+     * is only possible for the true built-in alignment types - it's
+     * meaningless for linear or trimmed linear alignment, and for
+     * external program alignment. The default is false.
+     */
+    static bool getUseSubsequenceAlignment();
+
+    /**
+     * Set whether subsequence alignment is to be preferred.
+     */
+    static void setUseSubsequenceAlignment(bool subsequence);
     
     /**
      * Align the "other" model to the reference, attaching an
--- a/align/MATCHAligner.cpp	Wed Jul 01 15:34:46 2020 +0100
+++ b/align/MATCHAligner.cpp	Thu Jul 16 18:01:50 2020 +0100
@@ -30,10 +30,12 @@
 MATCHAligner::MATCHAligner(Document *doc,
                            ModelId reference,
                            ModelId toAlign,
+                           bool subsequence,
                            bool withTuningDifference) :
     m_document(doc),
     m_reference(reference),
     m_toAlign(toAlign),
+    m_subsequence(subsequence),
     m_withTuningDifference(withTuningDifference),
     m_tuningFrequency(440.f),
     m_incomplete(true)
@@ -55,13 +57,20 @@
 }
 
 QString
-MATCHAligner::getAlignmentTransformName()
+MATCHAligner::getAlignmentTransformName(bool subsequence)
 {
     QSettings settings;
     settings.beginGroup("Alignment");
-    TransformId id = settings.value
-        ("transform-id",
-         "vamp:match-vamp-plugin:match:path").toString();
+    TransformId id;
+    if (subsequence) {
+        id = settings.value
+            ("transform-id-subsequence",
+             "vamp:match-vamp-plugin:match-subsequence:path").toString();
+    } else {
+        id = settings.value
+            ("transform-id",
+             "vamp:match-vamp-plugin:match:path").toString();
+    }
     settings.endGroup();
     return id;
 }
@@ -83,9 +92,11 @@
 MATCHAligner::isAvailable()
 {
     TransformFactory *factory = TransformFactory::getInstance();
-    TransformId id = getAlignmentTransformName();
+    TransformId id = getAlignmentTransformName(false);
+    TransformId subId = getAlignmentTransformName(true);
     TransformId tdId = getTuningDifferenceTransformName();
     return factory->haveTransform(id) &&
+        (subId == "" || factory->haveTransform(subId)) &&
         (tdId == "" || factory->haveTransform(tdId));
 }
 
@@ -267,7 +278,7 @@
 bool
 MATCHAligner::beginAlignmentPhase()
 {
-    TransformId id = getAlignmentTransformName();
+    TransformId id = getAlignmentTransformName(m_subsequence);
     
     SVDEBUG << "MATCHAligner::beginAlignmentPhase: transform is "
             << id << endl;
--- a/align/MATCHAligner.h	Wed Jul 01 15:34:46 2020 +0100
+++ b/align/MATCHAligner.h	Thu Jul 16 18:01:50 2020 +0100
@@ -28,6 +28,7 @@
     MATCHAligner(Document *doc,
                  ModelId reference,
                  ModelId toAlign,
+                 bool subsequence,
                  bool withTuningDifference);
 
     // Destroy the aligner, cleanly cancelling any ongoing alignment
@@ -42,7 +43,7 @@
     void tuningDifferenceCompletionChanged(ModelId);
 
 private:
-    static QString getAlignmentTransformName();
+    static QString getAlignmentTransformName(bool subsequence);
     static QString getTuningDifferenceTransformName();
 
     bool beginAlignmentPhase();
@@ -54,6 +55,7 @@
     ModelId m_alignmentModel; // an AlignmentModel
     ModelId m_tuningDiffOutputModel; // SparseTimeValueModel, unreg'd with doc
     ModelId m_pathOutputModel; // SparseTimeValueModel, unreg'd with doc
+    bool m_subsequence;
     bool m_withTuningDifference;
     float m_tuningFrequency;
     bool m_incomplete;
--- a/align/TransformDTWAligner.cpp	Wed Jul 01 15:34:46 2020 +0100
+++ b/align/TransformDTWAligner.cpp	Thu Jul 16 18:01:50 2020 +0100
@@ -56,6 +56,7 @@
 TransformDTWAligner::TransformDTWAligner(Document *doc,
                                          ModelId reference,
                                          ModelId toAlign,
+                                         bool subsequence,
                                          Transform transform,
                                          DTWType dtwType) :
     m_document(doc),
@@ -63,6 +64,7 @@
     m_toAlign(toAlign),
     m_transform(transform),
     m_dtwType(dtwType),
+    m_subsequence(subsequence),
     m_incomplete(true),
     m_magnitudePreprocessor(identityMagnitudePreprocessor),
     m_riseFallPreprocessor(identityRiseFallPreprocessor)
@@ -72,6 +74,7 @@
 TransformDTWAligner::TransformDTWAligner(Document *doc,
                                          ModelId reference,
                                          ModelId toAlign,
+                                         bool subsequence,
                                          Transform transform,
                                          MagnitudePreprocessor outputPreprocessor) :
     m_document(doc),
@@ -79,6 +82,7 @@
     m_toAlign(toAlign),
     m_transform(transform),
     m_dtwType(Magnitude),
+    m_subsequence(subsequence),
     m_incomplete(true),
     m_magnitudePreprocessor(outputPreprocessor),
     m_riseFallPreprocessor(identityRiseFallPreprocessor)
@@ -88,6 +92,7 @@
 TransformDTWAligner::TransformDTWAligner(Document *doc,
                                          ModelId reference,
                                          ModelId toAlign,
+                                         bool subsequence,
                                          Transform transform,
                                          RiseFallPreprocessor outputPreprocessor) :
     m_document(doc),
@@ -95,6 +100,7 @@
     m_toAlign(toAlign),
     m_transform(transform),
     m_dtwType(RiseFall),
+    m_subsequence(subsequence),
     m_incomplete(true),
     m_magnitudePreprocessor(identityMagnitudePreprocessor),
     m_riseFallPreprocessor(outputPreprocessor)
@@ -361,7 +367,11 @@
                << "]: serialising DTW to avoid over-allocation" << endl;
 #endif
         QMutexLocker locker(&m_dtwMutex);
-        alignment = dtw.alignSequences(s1, s2);
+        if (m_subsequence) {
+            alignment = dtw.alignSubsequence(s1, s2);
+        } else {
+            alignment = dtw.alignSequences(s1, s2);
+        }
     }
 
 #ifdef DEBUG_TRANSFORM_DTW_ALIGNER
@@ -450,7 +460,11 @@
                << "]: serialising DTW to avoid over-allocation" << endl;
 #endif
         QMutexLocker locker(&m_dtwMutex);
-        alignment = dtw.alignSequences(s1, s2);
+        if (m_subsequence) {
+            alignment = dtw.alignSubsequence(s1, s2);
+        } else {
+            alignment = dtw.alignSequences(s1, s2);
+        }
     }
 
 #ifdef DEBUG_TRANSFORM_DTW_ALIGNER
--- a/align/TransformDTWAligner.h	Wed Jul 01 15:34:46 2020 +0100
+++ b/align/TransformDTWAligner.h	Thu Jul 16 18:01:50 2020 +0100
@@ -48,6 +48,7 @@
     TransformDTWAligner(Document *doc,
                         ModelId reference,
                         ModelId toAlign,
+                        bool subsequence,
                         Transform transform,
                         DTWType dtwType);
 
@@ -61,6 +62,7 @@
     TransformDTWAligner(Document *doc,
                         ModelId reference,
                         ModelId toAlign,
+                        bool subsequence,
                         Transform transform,
                         MagnitudePreprocessor outputPreprocessor);
 
@@ -75,6 +77,7 @@
     TransformDTWAligner(Document *doc,
                         ModelId reference,
                         ModelId toAlign,
+                        bool subsequence,
                         Transform transform,
                         RiseFallPreprocessor outputPreprocessor);
 
@@ -112,6 +115,7 @@
     ModelId m_alignmentModel;
     Transform m_transform;
     DTWType m_dtwType;
+    bool m_subsequence;
     bool m_incomplete;
     MagnitudePreprocessor m_magnitudePreprocessor;
     RiseFallPreprocessor m_riseFallPreprocessor;