annotate align/Align.h @ 786:1089d65c585d tip

Divert some debug output away from stderr
author Chris Cannam
date Fri, 14 Aug 2020 10:46:44 +0100
parents e136dd3bb5c6
children
rev   line source
Chris@420 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@420 2
Chris@420 3 /*
Chris@420 4 Sonic Visualiser
Chris@420 5 An audio file viewer and annotation editor.
Chris@420 6 Centre for Digital Music, Queen Mary, University of London.
Chris@420 7
Chris@420 8 This program is free software; you can redistribute it and/or
Chris@420 9 modify it under the terms of the GNU General Public License as
Chris@420 10 published by the Free Software Foundation; either version 2 of the
Chris@420 11 License, or (at your option) any later version. See the file
Chris@420 12 COPYING included with this distribution for more information.
Chris@420 13 */
Chris@420 14
Chris@754 15 #ifndef SV_ALIGN_H
Chris@754 16 #define SV_ALIGN_H
Chris@420 17
Chris@420 18 #include <QString>
Chris@423 19 #include <QObject>
Chris@423 20 #include <QProcess>
Chris@670 21 #include <QMutex>
Chris@423 22 #include <set>
Chris@420 23
Chris@753 24 #include "Aligner.h"
Chris@683 25
Chris@776 26 #include "transform/Transform.h"
Chris@776 27
Chris@423 28 class AlignmentModel;
Chris@664 29 class Document;
Chris@420 30
Chris@423 31 class Align : public QObject
Chris@420 32 {
Chris@423 33 Q_OBJECT
Chris@423 34
Chris@420 35 public:
Chris@670 36 Align() { }
Chris@420 37
Chris@767 38 enum AlignmentType {
Chris@767 39 NoAlignment,
Chris@767 40 LinearAlignment,
Chris@767 41 TrimmedLinearAlignment,
Chris@767 42 MATCHAlignment,
Chris@767 43 MATCHAlignmentWithPitchCompare,
Chris@771 44 SungNoteContourAlignment,
Chris@767 45 TransformDrivenDTWAlignment,
Chris@767 46 ExternalProgramAlignment,
Chris@767 47
Chris@767 48 LastAlignmentType = ExternalProgramAlignment
Chris@767 49 };
Chris@767 50
Chris@776 51 /**
Chris@776 52 * Convert an alignment type to a stable machine-readable string.
Chris@776 53 */
Chris@767 54 static QString getAlignmentTypeTag(AlignmentType type);
Chris@776 55
Chris@776 56 /**
Chris@776 57 * Convert an alignment type back from a stable machine-readable
Chris@776 58 * string.
Chris@776 59 */
Chris@767 60 static AlignmentType getAlignmentTypeForTag(QString tag);
Chris@767 61
Chris@776 62 /**
Chris@776 63 * Get the currently set alignment preference from the global
Chris@776 64 * application settings. If the returned preference is
Chris@776 65 * TransformDrivenDTWAlignment or ExternalProgramAlignment, then
Chris@776 66 * it will also be necessary to query
Chris@776 67 * getPreferredAlignmentTransform() or
Chris@776 68 * getPreferredAlignmentProgram() respectively in order to get the
Chris@776 69 * information needed to perform an alignment.
Chris@776 70 */
Chris@776 71 static AlignmentType getAlignmentPreference();
Chris@776 72
Chris@776 73 /**
Chris@776 74 * Set the alignment preference to the global application
Chris@776 75 * settings. If the preference is TransformDrivenDTWAlignment or
Chris@776 76 * ExternalProgramAlignment, you may also wish to call
Chris@776 77 * setPreferredAlignmentTransform() or
Chris@776 78 * setPreferredAlignmentProgram() respectively.
Chris@776 79 */
Chris@776 80 static void setAlignmentPreference(AlignmentType type);
Chris@776 81
Chris@776 82 /**
Chris@785 83 * Set the default alignment preference. That is, if no alignment
Chris@785 84 * preference has been set by the user yet, set it to this.
Chris@785 85 */
Chris@785 86 static void setDefaultAlignmentPreference(AlignmentType type);
Chris@785 87
Chris@785 88 /**
Chris@776 89 * Get the external program associated with the
Chris@776 90 * ExternalProgramAlignment type, if any is set (an empty string
Chris@776 91 * otherwise). Note that this will return a value if any has ever
Chris@776 92 * been set, regardless of whether ExternalProgramAlignment is the
Chris@776 93 * currently chosen alignment type or not.
Chris@776 94 */
Chris@776 95 static QString getPreferredAlignmentProgram();
Chris@776 96
Chris@776 97 /**
Chris@776 98 * Set the external program associated with the
Chris@776 99 * ExternalProgramAlignment type. It is not necessary for the
Chris@776 100 * current preferred alignment type actually to be
Chris@776 101 * ExternalProgramAlignment in order to change this setting. No
Chris@776 102 * validation is carried out on the argument - we don't verify
Chris@776 103 * that it actually is the path of a program, or anything else.
Chris@776 104 */
Chris@776 105 static void setPreferredAlignmentProgram(QString program);
Chris@776 106
Chris@776 107 /**
Chris@776 108 * Get the transform associated with the
Chris@776 109 * TransformDrivenDTWAlignment type, if any is set (a default
Chris@776 110 * constructed Transform otherwise). Note that this will return a
Chris@776 111 * value if any has ever been set, regardless of whether
Chris@776 112 * TransformDrivenDTWAlignment is the currently chosen alignment
Chris@776 113 * type or not.
Chris@776 114 */
Chris@776 115 static Transform getPreferredAlignmentTransform();
Chris@776 116
Chris@776 117 /**
Chris@776 118 * Set the transform associated with the
Chris@776 119 * TransformDrivenDTWAlignment type. It is not necessary for the
Chris@776 120 * current preferred alignment type actually to be
Chris@776 121 * TransformDrivenDTWAlignment in order to change this setting.
Chris@776 122 */
Chris@776 123 static void setPreferredAlignmentTransform(Transform transform);
Chris@781 124
Chris@781 125 /**
Chris@781 126 * Return true if subsequence alignment is preferred. In this case
Chris@781 127 * the toAlign model is aligned to the best-matching subsequence
Chris@781 128 * of the reference model rather than to the whole reference. This
Chris@781 129 * is only possible for the true built-in alignment types - it's
Chris@781 130 * meaningless for linear or trimmed linear alignment, and for
Chris@781 131 * external program alignment. The default is false.
Chris@781 132 */
Chris@781 133 static bool getUseSubsequenceAlignment();
Chris@781 134
Chris@781 135 /**
Chris@781 136 * Set whether subsequence alignment is to be preferred.
Chris@781 137 */
Chris@781 138 static void setUseSubsequenceAlignment(bool subsequence);
Chris@767 139
Chris@423 140 /**
Chris@423 141 * Align the "other" model to the reference, attaching an
Chris@423 142 * AlignmentModel to it. Alignment is carried out by the method
Chris@776 143 * configured in the user preferences (see
Chris@776 144 * getAlignmentPreference() etc) and is done asynchronously.
Chris@423 145 *
Chris@761 146 * Any errors are reported by firing the alignmentFailed
Chris@761 147 * signal. Note that the signal may be fired during the call to
Chris@761 148 * this function, if the aligner fails to start at all.
Chris@761 149 *
Chris@761 150 * If alignment starts successfully, then an AlignmentModel has
Chris@670 151 * been constructed and attached to the toAlign model, and you can
Chris@670 152 * query that model to discover the alignment progress, eventual
Chris@761 153 * outcome, and also (separately from the alignmentFailed signal
Chris@761 154 * here) any error message generated during alignment.
Chris@670 155 *
Chris@423 156 * A single Align object may carry out many simultanous alignment
Chris@423 157 * calls -- you do not need to create a new Align object each
Chris@423 158 * time, nor to wait for an alignment to be complete before
Chris@423 159 * starting a new one.
Chris@423 160 *
Chris@423 161 * The Align object must survive after this call, for at least as
Chris@428 162 * long as the alignment takes. The usual expectation is that the
Chris@428 163 * Align object will simply share the process or document
Chris@428 164 * lifespan.
Chris@423 165 */
Chris@761 166 void alignModel(Document *doc,
Chris@683 167 ModelId reference,
Chris@761 168 ModelId toAlign);
Chris@420 169
Chris@428 170 /**
Chris@761 171 * As alignModel, except that the alignment does not begin
Chris@761 172 * immediately, but is instead placed behind an event callback
Chris@761 173 * with a small delay. Useful to avoid an unresponsive GUI when
Chris@761 174 * firing off alignments while doing something else as well. Any
Chris@761 175 * error is reported by firing the alignmentFailed signal.
Chris@761 176 *
Chris@761 177 * Scheduled alignments are not queued or serialised - many could
Chris@761 178 * happen at once. They are just delayed a little for UI
Chris@761 179 * responsiveness.
Chris@761 180 */
Chris@761 181 void scheduleAlignment(Document *doc,
Chris@761 182 ModelId reference,
Chris@761 183 ModelId toAlign);
Chris@761 184
Chris@761 185 /**
Chris@776 186 * Return true if the preferred alignment facility is available
Chris@776 187 * (relevant plugin installed, etc).
Chris@428 188 */
Chris@428 189 static bool canAlign();
Chris@428 190
Chris@428 191 signals:
Chris@428 192 /**
Chris@428 193 * Emitted when an alignment is successfully completed. The
Chris@428 194 * reference and other models can be queried from the alignment
Chris@428 195 * model.
Chris@428 196 */
Chris@683 197 void alignmentComplete(ModelId alignmentModel); // an AlignmentModel
Chris@428 198
Chris@761 199 /**
Chris@761 200 * Emitted when an alignment fails. The model is the toAlign model
Chris@761 201 * that was passed to the call to alignModel or scheduleAlignment.
Chris@761 202 */
Chris@761 203 void alignmentFailed(ModelId toAlign, QString errorText);
Chris@761 204
Chris@423 205 private slots:
Chris@753 206 void alignerComplete(ModelId alignmentModel); // an AlignmentModel
Chris@761 207 void alignerFailed(ModelId toAlign, QString errorText);
Chris@423 208
Chris@420 209 private:
Chris@670 210 QMutex m_mutex;
Chris@671 211
Chris@753 212 // maps toAlign -> aligner for ongoing alignment - note that
Chris@753 213 // although we can calculate alignments with different references,
Chris@753 214 // we can only have one alignment on any given toAlign model, so
Chris@753 215 // we don't key this on the whole (reference, toAlign) pair
Chris@753 216 std::map<ModelId, std::shared_ptr<Aligner>> m_aligners;
Chris@671 217
Chris@767 218 bool addAligner(Document *doc, ModelId reference, ModelId toAlign);
Chris@761 219 void removeAligner(QObject *);
Chris@420 220 };
Chris@420 221
Chris@420 222 #endif
Chris@420 223