Mercurial > hg > svapp
comparison align/ExternalProgramAligner.cpp @ 761:6429a164b7e1 pitch-align
Schedule alignments with a small delay to avoid too much UI unresponsiveness. Also overhaul error reporting to use signals throughout.
author | Chris Cannam |
---|---|
date | Wed, 06 May 2020 11:45:27 +0100 |
parents | 32654e402f8b |
children | a316cb6fed81 |
comparison
equal
deleted
inserted
replaced
757:f32df46d0c84 | 761:6429a164b7e1 |
---|---|
47 { | 47 { |
48 QFileInfo file(program); | 48 QFileInfo file(program); |
49 return file.exists() && file.isExecutable(); | 49 return file.exists() && file.isExecutable(); |
50 } | 50 } |
51 | 51 |
52 bool | 52 void |
53 ExternalProgramAligner::begin(QString &error) | 53 ExternalProgramAligner::begin() |
54 { | 54 { |
55 // Run an external program, passing to it paths to the main | 55 // Run an external program, passing to it paths to the main |
56 // model's audio file and the new model's audio file. It returns | 56 // model's audio file and the new model's audio file. It returns |
57 // the path in CSV form through stdout. | 57 // the path in CSV form through stdout. |
58 | 58 |
59 auto reference = ModelById::getAs<ReadOnlyWaveFileModel>(m_reference); | 59 auto reference = ModelById::getAs<ReadOnlyWaveFileModel>(m_reference); |
60 auto other = ModelById::getAs<ReadOnlyWaveFileModel>(m_toAlign); | 60 auto other = ModelById::getAs<ReadOnlyWaveFileModel>(m_toAlign); |
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 false; | 63 return; |
64 } | 64 } |
65 | 65 |
66 while (!reference->isReady(nullptr) || !other->isReady(nullptr)) { | 66 while (!reference->isReady(nullptr) || !other->isReady(nullptr)) { |
67 qApp->processEvents(); | 67 qApp->processEvents(); |
68 } | 68 } |
76 if (otherPath == "") { | 76 if (otherPath == "") { |
77 otherPath = FileSource(other->getLocation()).getLocalFilename(); | 77 otherPath = FileSource(other->getLocation()).getLocalFilename(); |
78 } | 78 } |
79 | 79 |
80 if (refPath == "" || otherPath == "") { | 80 if (refPath == "" || otherPath == "") { |
81 error = "Failed to find local filepath for wave-file model"; | 81 emit failed(m_toAlign, |
82 return false; | 82 tr("Failed to find local filepath for wave-file model")); |
83 return; | |
83 } | 84 } |
84 | 85 |
85 auto alignmentModel = | 86 auto alignmentModel = |
86 std::make_shared<AlignmentModel>(m_reference, m_toAlign, ModelId()); | 87 std::make_shared<AlignmentModel>(m_reference, m_toAlign, ModelId()); |
87 | 88 |
111 bool success = m_process->waitForStarted(); | 112 bool success = m_process->waitForStarted(); |
112 | 113 |
113 if (!success) { | 114 if (!success) { |
114 | 115 |
115 SVCERR << "ERROR: ExternalProgramAligner: Program did not start" << endl; | 116 SVCERR << "ERROR: ExternalProgramAligner: Program did not start" << endl; |
116 error = "Alignment program \"" + m_program + "\" did not start"; | 117 emit failed(m_toAlign, |
118 tr("Alignment program \"%1\" did not start") | |
119 .arg(m_program)); | |
117 | 120 |
118 other->setAlignment({}); | 121 other->setAlignment({}); |
119 ModelById::release(m_alignmentModel); | 122 ModelById::release(m_alignmentModel); |
120 delete m_process; | 123 delete m_process; |
121 m_process = nullptr; | 124 m_process = nullptr; |
122 | 125 |
123 } else { | 126 } else { |
124 m_document->addNonDerivedModel(m_alignmentModel); | 127 m_document->addNonDerivedModel(m_alignmentModel); |
125 } | 128 } |
126 | |
127 return success; | |
128 } | 129 } |
129 | 130 |
130 void | 131 void |
131 ExternalProgramAligner::programFinished(int exitCode, QProcess::ExitStatus status) | 132 ExternalProgramAligner::programFinished(int exitCode, QProcess::ExitStatus status) |
132 { | 133 { |
167 | 168 |
168 CSVFileReader reader(process, format, alignmentModel->getSampleRate()); | 169 CSVFileReader reader(process, format, alignmentModel->getSampleRate()); |
169 if (!reader.isOK()) { | 170 if (!reader.isOK()) { |
170 SVCERR << "ERROR: ExternalProgramAligner: Failed to parse output" | 171 SVCERR << "ERROR: ExternalProgramAligner: Failed to parse output" |
171 << endl; | 172 << endl; |
172 alignmentModel->setError | 173 QString error = tr("Failed to parse output of program: %1") |
173 (QString("Failed to parse output of program: %1") | 174 .arg(reader.getError()); |
174 .arg(reader.getError())); | 175 alignmentModel->setError(error); |
176 emit failed(m_toAlign, error); | |
175 goto done; | 177 goto done; |
176 } | 178 } |
177 | 179 |
178 //!!! to use ById? | 180 //!!! to use ById? |
179 | 181 |
182 SparseTimeValueModel *path = | 184 SparseTimeValueModel *path = |
183 qobject_cast<SparseTimeValueModel *>(csvOutput); | 185 qobject_cast<SparseTimeValueModel *>(csvOutput); |
184 if (!path) { | 186 if (!path) { |
185 SVCERR << "ERROR: ExternalProgramAligner: Output did not convert to sparse time-value model" | 187 SVCERR << "ERROR: ExternalProgramAligner: Output did not convert to sparse time-value model" |
186 << endl; | 188 << endl; |
187 alignmentModel->setError | 189 QString error = |
188 ("Output of program did not produce sparse time-value model"); | 190 tr("Output of alignment program was not in the proper format"); |
191 alignmentModel->setError(error); | |
189 delete csvOutput; | 192 delete csvOutput; |
193 emit failed(m_toAlign, error); | |
190 goto done; | 194 goto done; |
191 } | 195 } |
192 | 196 |
193 if (path->isEmpty()) { | 197 if (path->isEmpty()) { |
194 SVCERR << "ERROR: ExternalProgramAligner: Output contained no mappings" | 198 SVCERR << "ERROR: ExternalProgramAligner: Output contained no mappings" |
195 << endl; | 199 << endl; |
196 alignmentModel->setError | 200 QString error = |
197 ("Output of alignment program contained no mappings"); | 201 tr("Output of alignment program contained no mappings"); |
202 alignmentModel->setError(error); | |
198 delete path; | 203 delete path; |
204 emit failed(m_toAlign, error); | |
199 goto done; | 205 goto done; |
200 } | 206 } |
201 | 207 |
202 SVCERR << "ExternalProgramAligner: Setting alignment path (" | 208 SVCERR << "ExternalProgramAligner: Setting alignment path (" |
203 << path->getEventCount() << " point(s))" << endl; | 209 << path->getEventCount() << " point(s))" << endl; |
212 | 218 |
213 } else { | 219 } else { |
214 SVCERR << "ERROR: ExternalProgramAligner: Aligner program " | 220 SVCERR << "ERROR: ExternalProgramAligner: Aligner program " |
215 << "failed: exit code " << exitCode << ", status " << status | 221 << "failed: exit code " << exitCode << ", status " << status |
216 << endl; | 222 << endl; |
217 alignmentModel->setError | 223 QString error = tr("Aligner process returned non-zero exit status"); |
218 ("Aligner process returned non-zero exit status"); | 224 alignmentModel->setError(error); |
225 emit failed(m_toAlign, error); | |
219 } | 226 } |
220 | 227 |
221 done: | 228 done: |
222 delete m_process; | 229 delete m_process; |
223 m_process = nullptr; | 230 m_process = nullptr; |