comparison align/ExternalProgramAligner.cpp @ 769:a316cb6fed81 pitch-align

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