From 11a29ddef695d1cfa94f366c5736b8fe9b12e799 Mon Sep 17 00:00:00 2001 From: Daniel Wolf Date: Wed, 2 Jan 2019 13:22:03 +0100 Subject: [PATCH 1/6] Split progress code --- rhubarb/CMakeLists.txt | 2 + rhubarb/src/audio/processing.cpp | 1 + rhubarb/src/audio/processing.h | 2 +- rhubarb/src/audio/voiceActivityDetection.h | 2 +- rhubarb/src/lib/rhubarbLib.h | 2 +- rhubarb/src/recognition/Recognizer.h | 2 +- rhubarb/src/recognition/pocketSphinxTools.h | 2 +- rhubarb/src/tools/ProgressBar.cpp | 41 ------------------- rhubarb/src/tools/ProgressBar.h | 39 +----------------- rhubarb/src/tools/parallel.h | 3 +- rhubarb/src/tools/progress.cpp | 45 +++++++++++++++++++++ rhubarb/src/tools/progress.h | 39 ++++++++++++++++++ 12 files changed, 95 insertions(+), 85 deletions(-) create mode 100644 rhubarb/src/tools/progress.cpp create mode 100644 rhubarb/src/tools/progress.h diff --git a/rhubarb/CMakeLists.txt b/rhubarb/CMakeLists.txt index 0fef2b7..0c0fd8c 100644 --- a/rhubarb/CMakeLists.txt +++ b/rhubarb/CMakeLists.txt @@ -467,6 +467,8 @@ add_library(rhubarb-tools src/tools/parallel.h src/tools/platformTools.cpp src/tools/platformTools.h + src/tools/progress.cpp + src/tools/progress.h src/tools/ProgressBar.cpp src/tools/ProgressBar.h src/tools/stringTools.cpp diff --git a/rhubarb/src/audio/processing.cpp b/rhubarb/src/audio/processing.cpp index 39cc8db..316efd7 100644 --- a/rhubarb/src/audio/processing.cpp +++ b/rhubarb/src/audio/processing.cpp @@ -1,4 +1,5 @@ #include "processing.h" +#include using std::function; using std::vector; diff --git a/rhubarb/src/audio/processing.h b/rhubarb/src/audio/processing.h index 8ece651..dc09c56 100644 --- a/rhubarb/src/audio/processing.h +++ b/rhubarb/src/audio/processing.h @@ -3,7 +3,7 @@ #include #include #include "AudioClip.h" -#include "tools/ProgressBar.h" +#include "tools/progress.h" void process16bitAudioClip(const AudioClip& audioClip, std::function&)> processBuffer, size_t bufferCapacity, ProgressSink& progressSink); void process16bitAudioClip(const AudioClip& audioClip, std::function&)> processBuffer, ProgressSink& progressSink); diff --git a/rhubarb/src/audio/voiceActivityDetection.h b/rhubarb/src/audio/voiceActivityDetection.h index 7820680..0e5bcb9 100644 --- a/rhubarb/src/audio/voiceActivityDetection.h +++ b/rhubarb/src/audio/voiceActivityDetection.h @@ -1,6 +1,6 @@ #pragma once #include "AudioClip.h" #include "time/BoundedTimeline.h" -#include "tools/ProgressBar.h" +#include "tools/progress.h" JoiningBoundedTimeline detectVoiceActivity(const AudioClip& audioClip, int maxThreadCount, ProgressSink& progressSink); diff --git a/rhubarb/src/lib/rhubarbLib.h b/rhubarb/src/lib/rhubarbLib.h index ca40a06..ae841a6 100644 --- a/rhubarb/src/lib/rhubarbLib.h +++ b/rhubarb/src/lib/rhubarbLib.h @@ -3,7 +3,7 @@ #include "core/Shape.h" #include "time/ContinuousTimeline.h" #include "audio/AudioClip.h" -#include "tools/ProgressBar.h" +#include "tools/progress.h" #include #include "animation/targetShapeSet.h" #include "recognition/Recognizer.h" diff --git a/rhubarb/src/recognition/Recognizer.h b/rhubarb/src/recognition/Recognizer.h index 05c445d..0903680 100644 --- a/rhubarb/src/recognition/Recognizer.h +++ b/rhubarb/src/recognition/Recognizer.h @@ -2,7 +2,7 @@ #include "audio/AudioClip.h" #include "core/Phone.h" -#include "tools/ProgressBar.h" +#include "tools/progress.h" #include "time/BoundedTimeline.h" class Recognizer { diff --git a/rhubarb/src/recognition/pocketSphinxTools.h b/rhubarb/src/recognition/pocketSphinxTools.h index 568ccbe..9a72199 100644 --- a/rhubarb/src/recognition/pocketSphinxTools.h +++ b/rhubarb/src/recognition/pocketSphinxTools.h @@ -3,7 +3,7 @@ #include "time/BoundedTimeline.h" #include "core/Phone.h" #include "audio/AudioClip.h" -#include "tools/ProgressBar.h" +#include "tools/progress.h" #include extern "C" { diff --git a/rhubarb/src/tools/ProgressBar.cpp b/rhubarb/src/tools/ProgressBar.cpp index 404a6b8..a436e69 100644 --- a/rhubarb/src/tools/ProgressBar.cpp +++ b/rhubarb/src/tools/ProgressBar.cpp @@ -3,52 +3,11 @@ #include #include #include -#include #include #include using std::string; -ProgressForwarder::ProgressForwarder(std::function callback) : - callback(callback) -{} - -void ProgressForwarder::reportProgress(double value) { - callback(value); -} - -ProgressMerger::ProgressMerger(ProgressSink& sink) : - sink(sink) -{} - -ProgressSink& ProgressMerger::addSink(double weight) { - std::lock_guard lock(mutex); - - totalWeight += weight; - int sinkIndex = weightedValues.size(); - weightedValues.push_back(0); - forwarders.push_back(ProgressForwarder([weight, sinkIndex, this](double progress) { - weightedValues[sinkIndex] = progress * weight; - report(); - })); - return forwarders.back(); -} - -void ProgressMerger::report() { - std::lock_guard lock(mutex); - - if (totalWeight != 0) { - double weightedSum = 0; - for (double weightedValue : weightedValues) { - weightedSum += weightedValue; - } - double progress = weightedSum / totalWeight; - sink.reportProgress(progress); - } else { - sink.reportProgress(0); - } -} - ProgressBar::ProgressBar(std::ostream& stream) : stream(stream) { diff --git a/rhubarb/src/tools/ProgressBar.h b/rhubarb/src/tools/ProgressBar.h index 0c005c7..7e5bd8f 100644 --- a/rhubarb/src/tools/ProgressBar.h +++ b/rhubarb/src/tools/ProgressBar.h @@ -2,45 +2,8 @@ #include #include -#include -#include -#include -#include -#include #include - -class ProgressSink { -public: - virtual ~ProgressSink() {} - virtual void reportProgress(double value) = 0; -}; - -class NullProgressSink : public ProgressSink { -public: - void reportProgress(double) override {} -}; - -class ProgressForwarder : public ProgressSink { -public: - ProgressForwarder(std::function callback); - void reportProgress(double value) override; -private: - std::function callback; -}; - -class ProgressMerger { -public: - ProgressMerger(ProgressSink& sink); - ProgressSink& addSink(double weight); -private: - void report(); - - ProgressSink& sink; - std::mutex mutex; - double totalWeight = 0; - std::list forwarders; - std::vector weightedValues; -}; +#include "progress.h" class ProgressBar : public ProgressSink { public: diff --git a/rhubarb/src/tools/parallel.h b/rhubarb/src/tools/parallel.h index cca4164..de8c5d5 100644 --- a/rhubarb/src/tools/parallel.h +++ b/rhubarb/src/tools/parallel.h @@ -1,7 +1,8 @@ #pragma once #include -#include "ProgressBar.h" +#include +#include "progress.h" #include template diff --git a/rhubarb/src/tools/progress.cpp b/rhubarb/src/tools/progress.cpp new file mode 100644 index 0000000..34c5848 --- /dev/null +++ b/rhubarb/src/tools/progress.cpp @@ -0,0 +1,45 @@ +#include "progress.h" + +#include + +using std::string; + +ProgressForwarder::ProgressForwarder(std::function callback) : + callback(callback) +{} + +void ProgressForwarder::reportProgress(double value) { + callback(value); +} + +ProgressMerger::ProgressMerger(ProgressSink& sink) : + sink(sink) +{} + +ProgressSink& ProgressMerger::addSink(double weight) { + std::lock_guard lock(mutex); + + totalWeight += weight; + int sinkIndex = weightedValues.size(); + weightedValues.push_back(0); + forwarders.push_back(ProgressForwarder([weight, sinkIndex, this](double progress) { + weightedValues[sinkIndex] = progress * weight; + report(); + })); + return forwarders.back(); +} + +void ProgressMerger::report() { + std::lock_guard lock(mutex); + + if (totalWeight != 0) { + double weightedSum = 0; + for (double weightedValue : weightedValues) { + weightedSum += weightedValue; + } + double progress = weightedSum / totalWeight; + sink.reportProgress(progress); + } else { + sink.reportProgress(0); + } +} diff --git a/rhubarb/src/tools/progress.h b/rhubarb/src/tools/progress.h new file mode 100644 index 0000000..23f4965 --- /dev/null +++ b/rhubarb/src/tools/progress.h @@ -0,0 +1,39 @@ +#pragma once + +#include +#include +#include +#include + +class ProgressSink { +public: + virtual ~ProgressSink() {} + virtual void reportProgress(double value) = 0; +}; + +class NullProgressSink : public ProgressSink { +public: + void reportProgress(double) override {} +}; + +class ProgressForwarder : public ProgressSink { +public: + ProgressForwarder(std::function callback); + void reportProgress(double value) override; +private: + std::function callback; +}; + +class ProgressMerger { +public: + ProgressMerger(ProgressSink& sink); + ProgressSink& addSink(double weight); +private: + void report(); + + ProgressSink& sink; + std::mutex mutex; + double totalWeight = 0; + std::list forwarders; + std::vector weightedValues; +}; From d0c9a294e9ef798d905ffc1c8fbd982fd574a84b Mon Sep 17 00:00:00 2001 From: Daniel Wolf Date: Wed, 2 Jan 2019 14:29:19 +0100 Subject: [PATCH 2/6] Correctly print final progress when ProgressBar is destructed Fixes issue #46 --- rhubarb/src/tools/ProgressBar.cpp | 49 +++++++++++++++++++------------ rhubarb/src/tools/ProgressBar.h | 4 ++- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/rhubarb/src/tools/ProgressBar.cpp b/rhubarb/src/tools/ProgressBar.cpp index a436e69..5ba39d2 100644 --- a/rhubarb/src/tools/ProgressBar.cpp +++ b/rhubarb/src/tools/ProgressBar.cpp @@ -8,9 +8,21 @@ using std::string; -ProgressBar::ProgressBar(std::ostream& stream) : +double sanitizeProgress(double progress) { + // Make sure value is in [0..1] range + return std::isnan(progress) + ? 0.0 + : boost::algorithm::clamp(progress, 0.0, 1.0); +} + +ProgressBar::ProgressBar(double progress) : + ProgressBar(std::cerr, progress) +{} + +ProgressBar::ProgressBar(std::ostream& stream, double progress) : stream(stream) { + currentProgress = sanitizeProgress(progress); updateLoopFuture = std::async(std::launch::async, &ProgressBar::updateLoop, this); } @@ -20,37 +32,38 @@ ProgressBar::~ProgressBar() { } void ProgressBar::reportProgress(double value) { - // Make sure value is in [0..1] range - value = boost::algorithm::clamp(value, 0.0, 1.0); - if (std::isnan(value)) { - value = 0.0; - } - - currentProgress = value; + currentProgress = sanitizeProgress(value); } void ProgressBar::updateLoop() { - const int blockCount = 20; const std::chrono::milliseconds animationInterval(1000 / 8); - const string animation = "|/-\\"; while (!done) { - int progressBlockCount = static_cast(currentProgress * blockCount); - int percent = static_cast(currentProgress * 100); - string text = fmt::format("[{0}{1}] {2:3}% {3}", - string(progressBlockCount, '#'), string(blockCount - progressBlockCount, '-'), - percent, - animation[animationIndex++ % animation.size()]); - updateText(text); - + update(); std::this_thread::sleep_for(animationInterval); } if (clearOnDestruction) { updateText(""); + } else { + update(); } } +void ProgressBar::update() { + const int blockCount = 20; + const string animation = "|/-\\"; + + int progressBlockCount = static_cast(currentProgress * blockCount); + const double epsilon = 0.0001; + int percent = static_cast(currentProgress * 100 + epsilon); + string text = fmt::format("[{0}{1}] {2:3}% {3}", + string(progressBlockCount, '#'), string(blockCount - progressBlockCount, '-'), + percent, + animation[animationIndex++ % animation.size()]); + updateText(text); +} + void ProgressBar::updateText(const string& text) { // Get length of common portion int commonPrefixLength = 0; diff --git a/rhubarb/src/tools/ProgressBar.h b/rhubarb/src/tools/ProgressBar.h index 7e5bd8f..2c58509 100644 --- a/rhubarb/src/tools/ProgressBar.h +++ b/rhubarb/src/tools/ProgressBar.h @@ -7,7 +7,8 @@ class ProgressBar : public ProgressSink { public: - ProgressBar(std::ostream& stream = std::cerr); + explicit ProgressBar(double progress = 0.0); + ProgressBar(std::ostream& stream, double progress = 0.0); ~ProgressBar(); void reportProgress(double value) override; @@ -21,6 +22,7 @@ public: private: void updateLoop(); + void update(); void updateText(const std::string& text); std::future updateLoopFuture; From e325917abe3c23d370c4397344766d6eba75e150 Mon Sep 17 00:00:00 2001 From: Daniel Wolf Date: Wed, 2 Jan 2019 14:26:38 +0100 Subject: [PATCH 3/6] Preserve progress when continuing console output --- rhubarb/src/rhubarb/sinks.cpp | 6 ++++-- rhubarb/src/rhubarb/sinks.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/rhubarb/src/rhubarb/sinks.cpp b/rhubarb/src/rhubarb/sinks.cpp index 07dadbe..3b2e1b2 100644 --- a/rhubarb/src/rhubarb/sinks.cpp +++ b/rhubarb/src/rhubarb/sinks.cpp @@ -16,6 +16,7 @@ using boost::optional; NiceStderrSink::NiceStderrSink(Level minLevel) : minLevel(minLevel), + progress(0.0), innerSink(make_shared(make_shared())) {} @@ -26,7 +27,8 @@ void NiceStderrSink::receive(const logging::Entry& entry) { startProgressIndication(); } else if (const ProgressEntry* progressEntry = dynamic_cast(&entry)) { assert(progressBar); - progressBar->reportProgress(progressEntry->getProgress()); + progress = progressEntry->getProgress(); + progressBar->reportProgress(progress); } else if (dynamic_cast(&entry)) { interruptProgressIndication(); std::cerr << "Done." << std::endl; @@ -54,7 +56,7 @@ void NiceStderrSink::interruptProgressIndication() { void NiceStderrSink::resumeProgressIndication() { std::cerr << "Progress (cont'd): "; - progressBar = boost::in_place(); + progressBar = boost::in_place(progress); progressBar->setClearOnDestruction(false); } diff --git a/rhubarb/src/rhubarb/sinks.h b/rhubarb/src/rhubarb/sinks.h index 5e053db..9bf47e3 100644 --- a/rhubarb/src/rhubarb/sinks.h +++ b/rhubarb/src/rhubarb/sinks.h @@ -17,6 +17,7 @@ private: void resumeProgressIndication(); logging::Level minLevel; + double progress; boost::optional progressBar; std::shared_ptr innerSink; }; From 3189fc8976382d211bbd95dadc34dde919641efe Mon Sep 17 00:00:00 2001 From: Daniel Wolf Date: Wed, 2 Jan 2019 14:27:49 +0100 Subject: [PATCH 4/6] Don't clear away last progress bar --- rhubarb/src/rhubarb/sinks.cpp | 2 -- rhubarb/src/tools/ProgressBar.h | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/rhubarb/src/rhubarb/sinks.cpp b/rhubarb/src/rhubarb/sinks.cpp index 3b2e1b2..ef62778 100644 --- a/rhubarb/src/rhubarb/sinks.cpp +++ b/rhubarb/src/rhubarb/sinks.cpp @@ -46,7 +46,6 @@ void NiceStderrSink::receive(const logging::Entry& entry) { void NiceStderrSink::startProgressIndication() { std::cerr << "Progress: "; progressBar = boost::in_place(); - progressBar->setClearOnDestruction(false); } void NiceStderrSink::interruptProgressIndication() { @@ -57,7 +56,6 @@ void NiceStderrSink::interruptProgressIndication() { void NiceStderrSink::resumeProgressIndication() { std::cerr << "Progress (cont'd): "; progressBar = boost::in_place(progress); - progressBar->setClearOnDestruction(false); } QuietStderrSink::QuietStderrSink(Level minLevel) : diff --git a/rhubarb/src/tools/ProgressBar.h b/rhubarb/src/tools/ProgressBar.h index 2c58509..2dd5f7a 100644 --- a/rhubarb/src/tools/ProgressBar.h +++ b/rhubarb/src/tools/ProgressBar.h @@ -32,5 +32,5 @@ private: std::ostream& stream; std::string currentText; int animationIndex = 0; - bool clearOnDestruction = true; + bool clearOnDestruction = false; }; From e87ccc88167895dba6805ea2b031be771eceecfd Mon Sep 17 00:00:00 2001 From: Daniel Wolf Date: Wed, 2 Jan 2019 14:38:53 +0100 Subject: [PATCH 5/6] Hide progress spinner when ProgressBar gets destructed --- rhubarb/src/tools/ProgressBar.cpp | 10 +++++++--- rhubarb/src/tools/ProgressBar.h | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/rhubarb/src/tools/ProgressBar.cpp b/rhubarb/src/tools/ProgressBar.cpp index 5ba39d2..4f913d7 100644 --- a/rhubarb/src/tools/ProgressBar.cpp +++ b/rhubarb/src/tools/ProgressBar.cpp @@ -46,21 +46,25 @@ void ProgressBar::updateLoop() { if (clearOnDestruction) { updateText(""); } else { - update(); + update(false); } } -void ProgressBar::update() { +void ProgressBar::update(bool showSpinner) { const int blockCount = 20; const string animation = "|/-\\"; int progressBlockCount = static_cast(currentProgress * blockCount); const double epsilon = 0.0001; int percent = static_cast(currentProgress * 100 + epsilon); + const string spinner = showSpinner + ? string(1, animation[animationIndex++ % animation.size()]) + : ""; string text = fmt::format("[{0}{1}] {2:3}% {3}", string(progressBlockCount, '#'), string(blockCount - progressBlockCount, '-'), percent, - animation[animationIndex++ % animation.size()]); + spinner + ); updateText(text); } diff --git a/rhubarb/src/tools/ProgressBar.h b/rhubarb/src/tools/ProgressBar.h index 2dd5f7a..347b330 100644 --- a/rhubarb/src/tools/ProgressBar.h +++ b/rhubarb/src/tools/ProgressBar.h @@ -22,7 +22,7 @@ public: private: void updateLoop(); - void update(); + void update(bool showSpinner = true); void updateText(const std::string& text); std::future updateLoopFuture; From 1d04b01654c7db29d84be0b7bc931a2d9a5a6f7b Mon Sep 17 00:00:00 2001 From: Daniel Wolf Date: Wed, 2 Jan 2019 14:52:07 +0100 Subject: [PATCH 6/6] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c466bc4..d4e388b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased * **Added** basic support for non-English recordings through phonetic recognition ([issue #45](https://github.com/DanielSWolf/rhubarb-lip-sync/issues/45)). +* **Fixed** a bug that prevented the progress bar from reaching 100% ([issue #48](https://github.com/DanielSWolf/rhubarb-lip-sync/issues/48)). ## Version 1.8.0