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@420
|
15 #include "Align.h"
|
Chris@753
|
16 #include "TransformAligner.h"
|
Chris@753
|
17 #include "ExternalProgramAligner.h"
|
Chris@744
|
18 #include "framework/Document.h"
|
Chris@420
|
19
|
Chris@422
|
20 #include <QSettings>
|
Chris@761
|
21 #include <QTimer>
|
Chris@422
|
22
|
Chris@761
|
23 void
|
Chris@753
|
24 Align::alignModel(Document *doc,
|
Chris@753
|
25 ModelId reference,
|
Chris@761
|
26 ModelId toAlign)
|
Chris@761
|
27 {
|
Chris@761
|
28 addAligner(doc, reference, toAlign);
|
Chris@761
|
29 m_aligners[toAlign]->begin();
|
Chris@761
|
30 }
|
Chris@761
|
31
|
Chris@761
|
32 void
|
Chris@761
|
33 Align::scheduleAlignment(Document *doc,
|
Chris@761
|
34 ModelId reference,
|
Chris@761
|
35 ModelId toAlign)
|
Chris@761
|
36 {
|
Chris@761
|
37 addAligner(doc, reference, toAlign);
|
Chris@761
|
38 int delay = 500 + 500 * int(m_aligners.size());
|
Chris@761
|
39 if (delay > 3500) {
|
Chris@761
|
40 delay = 3500;
|
Chris@761
|
41 }
|
Chris@761
|
42 SVCERR << "Align::scheduleAlignment: delaying " << delay << "ms" << endl;
|
Chris@761
|
43 QTimer::singleShot(delay, m_aligners[toAlign].get(), SLOT(begin()));
|
Chris@761
|
44 }
|
Chris@761
|
45
|
Chris@761
|
46 void
|
Chris@761
|
47 Align::addAligner(Document *doc,
|
Chris@761
|
48 ModelId reference,
|
Chris@761
|
49 ModelId toAlign)
|
Chris@753
|
50 {
|
Chris@753
|
51 bool useProgram;
|
Chris@753
|
52 QString program;
|
Chris@753
|
53 getAlignerPreference(useProgram, program);
|
Chris@753
|
54
|
Chris@753
|
55 std::shared_ptr<Aligner> aligner;
|
Chris@753
|
56
|
Chris@753
|
57 {
|
Chris@753
|
58 // Replace the aligner with a new one. This also stops any
|
Chris@753
|
59 // previously-running alignment, when the old entry is
|
Chris@753
|
60 // replaced and its aligner destroyed.
|
Chris@753
|
61
|
Chris@753
|
62 QMutexLocker locker(&m_mutex);
|
Chris@753
|
63
|
Chris@753
|
64 if (useProgram && (program != "")) {
|
Chris@753
|
65 m_aligners[toAlign] =
|
Chris@753
|
66 std::make_shared<ExternalProgramAligner>(doc,
|
Chris@753
|
67 reference,
|
Chris@753
|
68 toAlign,
|
Chris@753
|
69 program);
|
Chris@753
|
70 } else {
|
Chris@753
|
71 m_aligners[toAlign] =
|
Chris@753
|
72 std::make_shared<TransformAligner>(doc,
|
Chris@753
|
73 reference,
|
Chris@753
|
74 toAlign);
|
Chris@753
|
75 }
|
Chris@753
|
76
|
Chris@753
|
77 aligner = m_aligners[toAlign];
|
Chris@753
|
78 }
|
Chris@753
|
79
|
Chris@753
|
80 connect(aligner.get(), SIGNAL(complete(ModelId)),
|
Chris@753
|
81 this, SLOT(alignerComplete(ModelId)));
|
Chris@761
|
82
|
Chris@761
|
83 connect(aligner.get(), SIGNAL(failed(ModelId, QString)),
|
Chris@761
|
84 this, SLOT(alignerFailed(ModelId, QString)));
|
Chris@753
|
85 }
|
Chris@753
|
86
|
Chris@753
|
87 void
|
Chris@756
|
88 Align::getAlignerPreference(bool &useProgram, QString &program)
|
Chris@422
|
89 {
|
Chris@422
|
90 QSettings settings;
|
Chris@422
|
91 settings.beginGroup("Preferences");
|
Chris@753
|
92 useProgram = settings.value("use-external-alignment", false).toBool();
|
Chris@753
|
93 program = settings.value("external-alignment-program", "").toString();
|
Chris@422
|
94 settings.endGroup();
|
Chris@670
|
95 }
|
Chris@670
|
96
|
Chris@428
|
97 bool
|
Chris@428
|
98 Align::canAlign()
|
Chris@428
|
99 {
|
Chris@753
|
100 bool useProgram;
|
Chris@753
|
101 QString program;
|
Chris@753
|
102 getAlignerPreference(useProgram, program);
|
Chris@753
|
103
|
Chris@753
|
104 if (useProgram) {
|
Chris@753
|
105 return ExternalProgramAligner::isAvailable(program);
|
Chris@753
|
106 } else {
|
Chris@753
|
107 return TransformAligner::isAvailable();
|
Chris@753
|
108 }
|
Chris@428
|
109 }
|
Chris@428
|
110
|
Chris@702
|
111 void
|
Chris@753
|
112 Align::alignerComplete(ModelId alignmentModel)
|
Chris@702
|
113 {
|
Chris@761
|
114 removeAligner(sender());
|
Chris@761
|
115 emit alignmentComplete(alignmentModel);
|
Chris@761
|
116 }
|
Chris@761
|
117
|
Chris@761
|
118 void
|
Chris@761
|
119 Align::alignerFailed(ModelId toAlign, QString error)
|
Chris@761
|
120 {
|
Chris@761
|
121 removeAligner(sender());
|
Chris@761
|
122 emit alignmentFailed(toAlign, error);
|
Chris@761
|
123 }
|
Chris@761
|
124
|
Chris@761
|
125 void
|
Chris@761
|
126 Align::removeAligner(QObject *obj)
|
Chris@761
|
127 {
|
Chris@761
|
128 Aligner *aligner = qobject_cast<Aligner *>(obj);
|
Chris@753
|
129 if (!aligner) {
|
Chris@761
|
130 SVCERR << "ERROR: Align::removeAligner: Not an Aligner" << endl;
|
Chris@702
|
131 return;
|
Chris@702
|
132 }
|
Chris@702
|
133
|
Chris@761
|
134 QMutexLocker locker (&m_mutex);
|
Chris@702
|
135
|
Chris@761
|
136 for (auto p: m_aligners) {
|
Chris@761
|
137 if (aligner == p.second.get()) {
|
Chris@761
|
138 m_aligners.erase(p.first);
|
Chris@761
|
139 break;
|
Chris@702
|
140 }
|
Chris@702
|
141 }
|
Chris@761
|
142 }
|
Chris@702
|
143
|