comparison align/Align.cpp @ 763:da57ab54f0e8

Merge from branch pitch-align. Doesn't actually do pitch alignment here, but this is the groundwork.
author Chris Cannam
date Wed, 13 May 2020 14:10:47 +0100
parents 6429a164b7e1
children dd742e566e60
comparison
equal deleted inserted replaced
760:3a63f1f61bd6 763:da57ab54f0e8
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 Sonic Visualiser
5 An audio file viewer and annotation editor.
6 Centre for Digital Music, Queen Mary, University of London.
7
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version. See the file
12 COPYING included with this distribution for more information.
13 */
14
15 #include "Align.h"
16 #include "TransformAligner.h"
17 #include "ExternalProgramAligner.h"
18 #include "framework/Document.h"
19
20 #include <QSettings>
21 #include <QTimer>
22
23 void
24 Align::alignModel(Document *doc,
25 ModelId reference,
26 ModelId toAlign)
27 {
28 addAligner(doc, reference, toAlign);
29 m_aligners[toAlign]->begin();
30 }
31
32 void
33 Align::scheduleAlignment(Document *doc,
34 ModelId reference,
35 ModelId toAlign)
36 {
37 addAligner(doc, reference, toAlign);
38 int delay = 500 + 500 * int(m_aligners.size());
39 if (delay > 3500) {
40 delay = 3500;
41 }
42 SVCERR << "Align::scheduleAlignment: delaying " << delay << "ms" << endl;
43 QTimer::singleShot(delay, m_aligners[toAlign].get(), SLOT(begin()));
44 }
45
46 void
47 Align::addAligner(Document *doc,
48 ModelId reference,
49 ModelId toAlign)
50 {
51 bool useProgram;
52 QString program;
53 getAlignerPreference(useProgram, program);
54
55 std::shared_ptr<Aligner> aligner;
56
57 {
58 // Replace the aligner with a new one. This also stops any
59 // previously-running alignment, when the old entry is
60 // replaced and its aligner destroyed.
61
62 QMutexLocker locker(&m_mutex);
63
64 if (useProgram && (program != "")) {
65 m_aligners[toAlign] =
66 std::make_shared<ExternalProgramAligner>(doc,
67 reference,
68 toAlign,
69 program);
70 } else {
71 m_aligners[toAlign] =
72 std::make_shared<TransformAligner>(doc,
73 reference,
74 toAlign);
75 }
76
77 aligner = m_aligners[toAlign];
78 }
79
80 connect(aligner.get(), SIGNAL(complete(ModelId)),
81 this, SLOT(alignerComplete(ModelId)));
82
83 connect(aligner.get(), SIGNAL(failed(ModelId, QString)),
84 this, SLOT(alignerFailed(ModelId, QString)));
85 }
86
87 void
88 Align::getAlignerPreference(bool &useProgram, QString &program)
89 {
90 QSettings settings;
91 settings.beginGroup("Preferences");
92 useProgram = settings.value("use-external-alignment", false).toBool();
93 program = settings.value("external-alignment-program", "").toString();
94 settings.endGroup();
95 }
96
97 bool
98 Align::canAlign()
99 {
100 bool useProgram;
101 QString program;
102 getAlignerPreference(useProgram, program);
103
104 if (useProgram) {
105 return ExternalProgramAligner::isAvailable(program);
106 } else {
107 return TransformAligner::isAvailable();
108 }
109 }
110
111 void
112 Align::alignerComplete(ModelId alignmentModel)
113 {
114 removeAligner(sender());
115 emit alignmentComplete(alignmentModel);
116 }
117
118 void
119 Align::alignerFailed(ModelId toAlign, QString error)
120 {
121 removeAligner(sender());
122 emit alignmentFailed(toAlign, error);
123 }
124
125 void
126 Align::removeAligner(QObject *obj)
127 {
128 Aligner *aligner = qobject_cast<Aligner *>(obj);
129 if (!aligner) {
130 SVCERR << "ERROR: Align::removeAligner: Not an Aligner" << endl;
131 return;
132 }
133
134 QMutexLocker locker (&m_mutex);
135
136 for (auto p: m_aligners) {
137 if (aligner == p.second.get()) {
138 m_aligners.erase(p.first);
139 break;
140 }
141 }
142 }
143