annotate align/Align.h @ 771:1d6cca5a5621 pitch-align

Allow use of proper sparse models (i.e. retaining event time info) in alignment; use this to switch to note alignment, which is what we have most recently been doing in the external program. Not currently producing correct results, though
author Chris Cannam
date Fri, 29 May 2020 17:39:02 +0100
parents dd742e566e60
children 32e66fcc4cb7
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@423 26 class AlignmentModel;
Chris@664 27 class Document;
Chris@420 28
Chris@423 29 class Align : public QObject
Chris@420 30 {
Chris@423 31 Q_OBJECT
Chris@423 32
Chris@420 33 public:
Chris@670 34 Align() { }
Chris@420 35
Chris@767 36 enum AlignmentType {
Chris@767 37 NoAlignment,
Chris@767 38 LinearAlignment,
Chris@767 39 TrimmedLinearAlignment,
Chris@767 40 MATCHAlignment,
Chris@767 41 MATCHAlignmentWithPitchCompare,
Chris@771 42 SungNoteContourAlignment,
Chris@767 43 TransformDrivenDTWAlignment,
Chris@767 44 ExternalProgramAlignment,
Chris@767 45
Chris@767 46 LastAlignmentType = ExternalProgramAlignment
Chris@767 47 };
Chris@767 48
Chris@767 49 static QString getAlignmentTypeTag(AlignmentType type);
Chris@767 50 static AlignmentType getAlignmentTypeForTag(QString tag);
Chris@767 51
Chris@767 52 static AlignmentType getAlignmentPreference(QString &additionalData);
Chris@767 53 static void setAlignmentPreference(AlignmentType type,
Chris@767 54 QString additionalData = "");
Chris@767 55
Chris@423 56 /**
Chris@423 57 * Align the "other" model to the reference, attaching an
Chris@423 58 * AlignmentModel to it. Alignment is carried out by the method
Chris@423 59 * configured in the user preferences (either a plugin transform
Chris@423 60 * or an external process) and is done asynchronously.
Chris@423 61 *
Chris@761 62 * Any errors are reported by firing the alignmentFailed
Chris@761 63 * signal. Note that the signal may be fired during the call to
Chris@761 64 * this function, if the aligner fails to start at all.
Chris@761 65 *
Chris@761 66 * If alignment starts successfully, then an AlignmentModel has
Chris@670 67 * been constructed and attached to the toAlign model, and you can
Chris@670 68 * query that model to discover the alignment progress, eventual
Chris@761 69 * outcome, and also (separately from the alignmentFailed signal
Chris@761 70 * here) any error message generated during alignment.
Chris@670 71 *
Chris@423 72 * A single Align object may carry out many simultanous alignment
Chris@423 73 * calls -- you do not need to create a new Align object each
Chris@423 74 * time, nor to wait for an alignment to be complete before
Chris@423 75 * starting a new one.
Chris@423 76 *
Chris@423 77 * The Align object must survive after this call, for at least as
Chris@428 78 * long as the alignment takes. The usual expectation is that the
Chris@428 79 * Align object will simply share the process or document
Chris@428 80 * lifespan.
Chris@423 81 */
Chris@761 82 void alignModel(Document *doc,
Chris@683 83 ModelId reference,
Chris@761 84 ModelId toAlign);
Chris@420 85
Chris@428 86 /**
Chris@761 87 * As alignModel, except that the alignment does not begin
Chris@761 88 * immediately, but is instead placed behind an event callback
Chris@761 89 * with a small delay. Useful to avoid an unresponsive GUI when
Chris@761 90 * firing off alignments while doing something else as well. Any
Chris@761 91 * error is reported by firing the alignmentFailed signal.
Chris@761 92 *
Chris@761 93 * Scheduled alignments are not queued or serialised - many could
Chris@761 94 * happen at once. They are just delayed a little for UI
Chris@761 95 * responsiveness.
Chris@761 96 */
Chris@761 97 void scheduleAlignment(Document *doc,
Chris@761 98 ModelId reference,
Chris@761 99 ModelId toAlign);
Chris@761 100
Chris@761 101 /**
Chris@428 102 * Return true if the alignment facility is available (relevant
Chris@428 103 * plugin installed, etc).
Chris@428 104 */
Chris@428 105 static bool canAlign();
Chris@428 106
Chris@767 107 //!!! + check whether specific alignment types are available
Chris@767 108
Chris@428 109 signals:
Chris@428 110 /**
Chris@428 111 * Emitted when an alignment is successfully completed. The
Chris@428 112 * reference and other models can be queried from the alignment
Chris@428 113 * model.
Chris@428 114 */
Chris@683 115 void alignmentComplete(ModelId alignmentModel); // an AlignmentModel
Chris@428 116
Chris@761 117 /**
Chris@761 118 * Emitted when an alignment fails. The model is the toAlign model
Chris@761 119 * that was passed to the call to alignModel or scheduleAlignment.
Chris@761 120 */
Chris@761 121 void alignmentFailed(ModelId toAlign, QString errorText);
Chris@761 122
Chris@423 123 private slots:
Chris@753 124 void alignerComplete(ModelId alignmentModel); // an AlignmentModel
Chris@761 125 void alignerFailed(ModelId toAlign, QString errorText);
Chris@423 126
Chris@420 127 private:
Chris@670 128 QMutex m_mutex;
Chris@671 129
Chris@753 130 // maps toAlign -> aligner for ongoing alignment - note that
Chris@753 131 // although we can calculate alignments with different references,
Chris@753 132 // we can only have one alignment on any given toAlign model, so
Chris@753 133 // we don't key this on the whole (reference, toAlign) pair
Chris@753 134 std::map<ModelId, std::shared_ptr<Aligner>> m_aligners;
Chris@671 135
Chris@767 136 bool addAligner(Document *doc, ModelId reference, ModelId toAlign);
Chris@761 137 void removeAligner(QObject *);
Chris@420 138 };
Chris@420 139
Chris@420 140 #endif
Chris@420 141