Mercurial > hg > svapp
comparison align/ExternalProgramAligner.cpp @ 778:83a7b10b7415
Merge from branch pitch-align
author | Chris Cannam |
---|---|
date | Fri, 26 Jun 2020 13:48:52 +0100 |
parents | 699b5b130ea2 |
children | 5de2b710cfae |
comparison
equal
deleted
inserted
replaced
774:7bded7599874 | 778:83a7b10b7415 |
---|---|
37 { | 37 { |
38 } | 38 } |
39 | 39 |
40 ExternalProgramAligner::~ExternalProgramAligner() | 40 ExternalProgramAligner::~ExternalProgramAligner() |
41 { | 41 { |
42 if (m_process) { | |
43 disconnect(m_process, nullptr, this, nullptr); | |
44 } | |
45 | |
42 delete m_process; | 46 delete m_process; |
43 } | 47 } |
44 | 48 |
45 bool | 49 bool |
46 ExternalProgramAligner::isAvailable(QString program) | 50 ExternalProgramAligner::isAvailable(QString program) |
61 if (!reference || !other) { | 65 if (!reference || !other) { |
62 SVCERR << "ERROR: ExternalProgramAligner: Can't align non-read-only models via program (no local filename available)" << endl; | 66 SVCERR << "ERROR: ExternalProgramAligner: Can't align non-read-only models via program (no local filename available)" << endl; |
63 return; | 67 return; |
64 } | 68 } |
65 | 69 |
70 if (m_program == "") { | |
71 emit failed(m_toAlign, tr("No external program specified")); | |
72 return; | |
73 } | |
74 | |
66 while (!reference->isReady(nullptr) || !other->isReady(nullptr)) { | 75 while (!reference->isReady(nullptr) || !other->isReady(nullptr)) { |
67 qApp->processEvents(); | 76 qApp->processEvents(); |
68 } | 77 } |
69 | 78 |
70 QString refPath = reference->getLocalFilename(); | 79 QString refPath = reference->getLocalFilename(); |
112 bool success = m_process->waitForStarted(); | 121 bool success = m_process->waitForStarted(); |
113 | 122 |
114 if (!success) { | 123 if (!success) { |
115 | 124 |
116 SVCERR << "ERROR: ExternalProgramAligner: Program did not start" << endl; | 125 SVCERR << "ERROR: ExternalProgramAligner: Program did not start" << endl; |
117 emit failed(m_toAlign, | 126 |
118 tr("Alignment program \"%1\" did not start") | |
119 .arg(m_program)); | |
120 | |
121 other->setAlignment({}); | 127 other->setAlignment({}); |
122 ModelById::release(m_alignmentModel); | 128 ModelById::release(m_alignmentModel); |
123 delete m_process; | 129 delete m_process; |
124 m_process = nullptr; | 130 m_process = nullptr; |
131 | |
132 emit failed(m_toAlign, | |
133 tr("Alignment program \"%1\" did not start") | |
134 .arg(m_program)); | |
125 | 135 |
126 } else { | 136 } else { |
137 alignmentModel->setCompletion(10); | |
127 m_document->addNonDerivedModel(m_alignmentModel); | 138 m_document->addNonDerivedModel(m_alignmentModel); |
128 } | 139 } |
129 } | 140 } |
130 | 141 |
131 void | 142 void |
132 ExternalProgramAligner::programFinished(int exitCode, QProcess::ExitStatus status) | 143 ExternalProgramAligner::programFinished(int exitCode, |
144 QProcess::ExitStatus status) | |
133 { | 145 { |
134 SVCERR << "ExternalProgramAligner::programFinished" << endl; | 146 SVCERR << "ExternalProgramAligner::programFinished" << endl; |
135 | 147 |
136 QProcess *process = qobject_cast<QProcess *>(sender()); | 148 QProcess *process = qobject_cast<QProcess *>(sender()); |
137 | 149 |
145 if (!alignmentModel) { | 157 if (!alignmentModel) { |
146 SVCERR << "ExternalProgramAligner: AlignmentModel no longer exists" | 158 SVCERR << "ExternalProgramAligner: AlignmentModel no longer exists" |
147 << endl; | 159 << endl; |
148 return; | 160 return; |
149 } | 161 } |
162 | |
163 QString errorText; | |
150 | 164 |
151 if (exitCode == 0 && status == 0) { | 165 if (exitCode == 0 && status == 0) { |
152 | 166 |
153 CSVFormat format; | 167 CSVFormat format; |
154 format.setModelType(CSVFormat::TwoDimensionalModel); | 168 format.setModelType(CSVFormat::TwoDimensionalModel); |
168 | 182 |
169 CSVFileReader reader(process, format, alignmentModel->getSampleRate()); | 183 CSVFileReader reader(process, format, alignmentModel->getSampleRate()); |
170 if (!reader.isOK()) { | 184 if (!reader.isOK()) { |
171 SVCERR << "ERROR: ExternalProgramAligner: Failed to parse output" | 185 SVCERR << "ERROR: ExternalProgramAligner: Failed to parse output" |
172 << endl; | 186 << endl; |
173 QString error = tr("Failed to parse output of program: %1") | 187 errorText = tr("Failed to parse output of program: %1") |
174 .arg(reader.getError()); | 188 .arg(reader.getError()); |
175 alignmentModel->setError(error); | 189 alignmentModel->setError(errorText); |
176 emit failed(m_toAlign, error); | |
177 goto done; | 190 goto done; |
178 } | 191 } |
179 | 192 |
180 //!!! to use ById? | 193 //!!! to use ById? |
181 | 194 |
184 SparseTimeValueModel *path = | 197 SparseTimeValueModel *path = |
185 qobject_cast<SparseTimeValueModel *>(csvOutput); | 198 qobject_cast<SparseTimeValueModel *>(csvOutput); |
186 if (!path) { | 199 if (!path) { |
187 SVCERR << "ERROR: ExternalProgramAligner: Output did not convert to sparse time-value model" | 200 SVCERR << "ERROR: ExternalProgramAligner: Output did not convert to sparse time-value model" |
188 << endl; | 201 << endl; |
189 QString error = | 202 errorText = |
190 tr("Output of alignment program was not in the proper format"); | 203 tr("Output of alignment program was not in the proper format"); |
191 alignmentModel->setError(error); | 204 alignmentModel->setError(errorText); |
192 delete csvOutput; | 205 delete csvOutput; |
193 emit failed(m_toAlign, error); | |
194 goto done; | 206 goto done; |
195 } | 207 } |
196 | 208 |
197 if (path->isEmpty()) { | 209 if (path->isEmpty()) { |
198 SVCERR << "ERROR: ExternalProgramAligner: Output contained no mappings" | 210 SVCERR << "ERROR: ExternalProgramAligner: Output contained no mappings" |
199 << endl; | 211 << endl; |
200 QString error = | 212 errorText = |
201 tr("Output of alignment program contained no mappings"); | 213 tr("Output of alignment program contained no mappings"); |
202 alignmentModel->setError(error); | 214 alignmentModel->setError(errorText); |
203 delete path; | 215 delete path; |
204 emit failed(m_toAlign, error); | |
205 goto done; | 216 goto done; |
206 } | 217 } |
207 | 218 |
208 SVCERR << "ExternalProgramAligner: Setting alignment path (" | 219 SVCERR << "ExternalProgramAligner: Setting alignment path (" |
209 << path->getEventCount() << " point(s))" << endl; | 220 << path->getEventCount() << " point(s))" << endl; |
210 | 221 |
211 auto pathId = | 222 auto pathId = |
212 ModelById::add(std::shared_ptr<SparseTimeValueModel>(path)); | 223 ModelById::add(std::shared_ptr<SparseTimeValueModel>(path)); |
213 alignmentModel->setPathFrom(pathId); | 224 alignmentModel->setPathFrom(pathId); |
214 | 225 alignmentModel->setCompletion(100); |
215 emit complete(m_alignmentModel); | |
216 | 226 |
217 ModelById::release(pathId); | 227 ModelById::release(pathId); |
218 | 228 |
219 } else { | 229 } else { |
220 SVCERR << "ERROR: ExternalProgramAligner: Aligner program " | 230 SVCERR << "ERROR: ExternalProgramAligner: Aligner program " |
221 << "failed: exit code " << exitCode << ", status " << status | 231 << "failed: exit code " << exitCode << ", status " << status |
222 << endl; | 232 << endl; |
223 QString error = tr("Aligner process returned non-zero exit status"); | 233 errorText = tr("Aligner process returned non-zero exit status"); |
224 alignmentModel->setError(error); | 234 alignmentModel->setError(errorText); |
225 emit failed(m_toAlign, error); | |
226 } | 235 } |
227 | 236 |
228 done: | 237 done: |
229 delete m_process; | 238 delete m_process; |
230 m_process = nullptr; | 239 m_process = nullptr; |
231 } | 240 |
241 // "This should be emitted as the last thing the aligner does, as | |
242 // the recipient may delete the aligner during the call." | |
243 if (errorText == "") { | |
244 emit complete(m_alignmentModel); | |
245 } else { | |
246 emit failed(m_toAlign, errorText); | |
247 } | |
248 } |