# HG changeset patch # User Chris Cannam # Date 1590681876 -3600 # Node ID a316cb6fed814c17af8aac717a87594cdd085720 # Parent 1b1960009be6a6509c544873491f103ee2c30f35 Fixes to notification and completion in aligners diff -r 1b1960009be6 -r a316cb6fed81 align/Aligner.h --- a/align/Aligner.h Fri May 22 17:17:44 2020 +0100 +++ b/align/Aligner.h Thu May 28 17:04:36 2020 +0100 @@ -32,12 +32,16 @@ signals: /** * Emitted when alignment is successfully completed. The reference - * and toAlign models can be queried from the alignment model. + * and toAlign models can be queried from the alignment + * model. This should be emitted as the last thing the aligner + * does, as the recipient may delete the aligner during the call. */ void complete(ModelId alignmentModel); // an AlignmentModel /** - * Emitted when alignment fails. + * Emitted when alignment fails. This should be emitted as the + * last thing the aligner does, as the recipient may delete the + * aligner during the call. */ void failed(ModelId toAlign, QString errorText); // the toAlign model }; diff -r 1b1960009be6 -r a316cb6fed81 align/ExternalProgramAligner.cpp --- a/align/ExternalProgramAligner.cpp Fri May 22 17:17:44 2020 +0100 +++ b/align/ExternalProgramAligner.cpp Thu May 28 17:04:36 2020 +0100 @@ -63,6 +63,11 @@ return; } + if (m_program == "") { + emit failed(m_toAlign, tr("No external program specified")); + return; + } + while (!reference->isReady(nullptr) || !other->isReady(nullptr)) { qApp->processEvents(); } @@ -114,22 +119,25 @@ if (!success) { SVCERR << "ERROR: ExternalProgramAligner: Program did not start" << endl; + + other->setAlignment({}); + ModelById::release(m_alignmentModel); + delete m_process; + m_process = nullptr; + emit failed(m_toAlign, tr("Alignment program \"%1\" did not start") .arg(m_program)); - other->setAlignment({}); - ModelById::release(m_alignmentModel); - delete m_process; - m_process = nullptr; - } else { + alignmentModel->setCompletion(10); m_document->addNonDerivedModel(m_alignmentModel); } } void -ExternalProgramAligner::programFinished(int exitCode, QProcess::ExitStatus status) +ExternalProgramAligner::programFinished(int exitCode, + QProcess::ExitStatus status) { SVCERR << "ExternalProgramAligner::programFinished" << endl; @@ -147,6 +155,8 @@ << endl; return; } + + QString errorText; if (exitCode == 0 && status == 0) { @@ -170,10 +180,9 @@ if (!reader.isOK()) { SVCERR << "ERROR: ExternalProgramAligner: Failed to parse output" << endl; - QString error = tr("Failed to parse output of program: %1") + errorText = tr("Failed to parse output of program: %1") .arg(reader.getError()); - alignmentModel->setError(error); - emit failed(m_toAlign, error); + alignmentModel->setError(errorText); goto done; } @@ -186,22 +195,20 @@ if (!path) { SVCERR << "ERROR: ExternalProgramAligner: Output did not convert to sparse time-value model" << endl; - QString error = + errorText = tr("Output of alignment program was not in the proper format"); - alignmentModel->setError(error); + alignmentModel->setError(errorText); delete csvOutput; - emit failed(m_toAlign, error); goto done; } if (path->isEmpty()) { SVCERR << "ERROR: ExternalProgramAligner: Output contained no mappings" << endl; - QString error = + errorText = tr("Output of alignment program contained no mappings"); - alignmentModel->setError(error); + alignmentModel->setError(errorText); delete path; - emit failed(m_toAlign, error); goto done; } @@ -211,8 +218,7 @@ auto pathId = ModelById::add(std::shared_ptr(path)); alignmentModel->setPathFrom(pathId); - - emit complete(m_alignmentModel); + alignmentModel->setCompletion(100); ModelById::release(pathId); @@ -220,12 +226,19 @@ SVCERR << "ERROR: ExternalProgramAligner: Aligner program " << "failed: exit code " << exitCode << ", status " << status << endl; - QString error = tr("Aligner process returned non-zero exit status"); - alignmentModel->setError(error); - emit failed(m_toAlign, error); + errorText = tr("Aligner process returned non-zero exit status"); + alignmentModel->setError(errorText); } done: delete m_process; m_process = nullptr; + + // "This should be emitted as the last thing the aligner does, as + // the recipient may delete the aligner during the call." + if (errorText == "") { + emit complete(m_alignmentModel); + } else { + emit failed(m_toAlign, errorText); + } } diff -r 1b1960009be6 -r a316cb6fed81 align/TransformAligner.cpp --- a/align/TransformAligner.cpp Fri May 22 17:17:44 2020 +0100 +++ b/align/TransformAligner.cpp Thu May 28 17:04:36 2020 +0100 @@ -244,11 +244,8 @@ if (!done) { // This will be the completion the alignment model reports, - // before the alignment actually begins. It goes up from 0 to - // 99 (not 100!) and then back to 0 again when we start - // calculating the actual path in the following phase - int clamped = (completion == 100 ? 99 : completion); - alignmentModel->setCompletion(clamped); + // before the alignment actually begins + alignmentModel->setCompletion(completion / 2); return; } @@ -344,35 +341,55 @@ pathOutputModel->setCompletion(0); alignmentModel->setPathFrom(m_pathOutputModel); - connect(alignmentModel.get(), SIGNAL(completionChanged(ModelId)), + connect(pathOutputModel.get(), SIGNAL(completionChanged(ModelId)), this, SLOT(alignmentCompletionChanged(ModelId))); return true; } void -TransformAligner::alignmentCompletionChanged(ModelId alignmentModelId) +TransformAligner::alignmentCompletionChanged(ModelId pathOutputModelId) { - if (alignmentModelId != m_alignmentModel) { + if (pathOutputModelId != m_pathOutputModel) { SVCERR << "WARNING: TransformAligner::alignmentCompletionChanged: Model " - << alignmentModelId + << pathOutputModelId << " is not ours! (ours is " - << m_alignmentModel << ")" << endl; + << m_pathOutputModel << ")" << endl; return; } - auto alignmentModel = ModelById::getAs(m_alignmentModel); + auto pathOutputModel = + ModelById::getAs(m_pathOutputModel); + if (!pathOutputModel) { + SVCERR << "WARNING: TransformAligner::alignmentCompletionChanged: Path output model " + << m_pathOutputModel << " no longer exists" << endl; + return; + } + + int completion = 0; + bool done = pathOutputModel->isReady(&completion); - if (alignmentModel && alignmentModel->isReady()) { + if (m_withTuningDifference) { + if (auto alignmentModel = + ModelById::getAs(m_alignmentModel)) { + if (!done) { + int adjustedCompletion = 50 + completion/2; + if (adjustedCompletion > 99) { + adjustedCompletion = 99; + } + alignmentModel->setCompletion(adjustedCompletion); + } else { + alignmentModel->setCompletion(100); + } + } + } + if (done) { m_incomplete = false; ModelById::release(m_pathOutputModel); m_pathOutputModel = {}; - disconnect(alignmentModel.get(), - SIGNAL(completionChanged(ModelId)), - this, SLOT(alignmentCompletionChanged(ModelId))); emit complete(m_alignmentModel); } } diff -r 1b1960009be6 -r a316cb6fed81 align/TransformDTWAligner.cpp --- a/align/TransformDTWAligner.cpp Fri May 22 17:17:44 2020 +0100 +++ b/align/TransformDTWAligner.cpp Thu May 28 17:04:36 2020 +0100 @@ -241,7 +241,7 @@ } } - SVCERR << "TransformDTWAligner[" << this << "]: performAlignment: " + SVCERR << "TransformDTWAligner[" << this << "]: performAlignmentMagnitude: " << "Have " << s1.size() << " events from reference, " << s2.size() << " from toAlign" << endl; @@ -257,7 +257,7 @@ alignment = dtw.alignSeries(s1, s2); } - SVCERR << "TransformDTWAligner[" << this << "]: performAlignment: " + SVCERR << "TransformDTWAligner[" << this << "]: performAlignmentMagnitude: " << "DTW produced " << alignment.size() << " points:" << endl; for (int i = 0; i < alignment.size() && i < 100; ++i) { SVCERR << alignment[i] << " "; @@ -278,7 +278,7 @@ alignmentModel->setPath(path); - SVCERR << "TransformDTWAligner[" << this << "]: performAlignment: Done" + SVCERR << "TransformDTWAligner[" << this << "]: performAlignmentMagnitude: Done" << endl; m_incomplete = false; @@ -327,7 +327,7 @@ vector s2 = convertEvents(toAlignOutputSTVM->getAllEvents()); - SVCERR << "TransformDTWAligner[" << this << "]: performAlignment: " + SVCERR << "TransformDTWAligner[" << this << "]: performAlignmentRiseFall: " << "Have " << s1.size() << " events from reference, " << s2.size() << " from toAlign" << endl; @@ -344,7 +344,7 @@ alignment = dtw.alignSeries(s1, s2); } - SVCERR << "TransformDTWAligner[" << this << "]: performAlignment: " + SVCERR << "TransformDTWAligner[" << this << "]: performAlignmentRiseFall: " << "DTW produced " << alignment.size() << " points:" << endl; for (int i = 0; i < alignment.size() && i < 100; ++i) { SVCERR << alignment[i] << " "; @@ -365,7 +365,7 @@ alignmentModel->setPath(path); - SVCERR << "TransformDTWAligner[" << this << "]: performAlignment: Done" + SVCERR << "TransformDTWAligner[" << this << "]: performAlignmentRiseFall: Done" << endl; m_incomplete = false;