summaryrefslogtreecommitdiffstats
path: root/GUI
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2023-02-26 17:50:02 -0800
committeryum <yum.food.vr@gmail.com>2023-02-26 17:50:02 -0800
commit61681895c14923f20dbd21aa821f4d2be8f7635d (patch)
tree3b1a856668399d352535a32fd1fcbee9901e09f5 /GUI
parentd0d5eedb4e6c56d81ae2135a50212f2091ee65d7 (diff)
CPP implementation refinements
* Pip install, dependency install, and model download can be gracefully interrupted and resume later. * Mic list was pointing at freed memory. Fix this by copying into the heap with std::unique_ptr()s. Mic list in CPP panel is much more reliable now.
Diffstat (limited to 'GUI')
-rw-r--r--GUI/GUI/GUI/PythonWrapper.cpp10
-rw-r--r--GUI/GUI/GUI/PythonWrapper.h5
-rw-r--r--GUI/GUI/GUI/WhisperCPP.cpp49
-rw-r--r--GUI/GUI/GUI/WhisperCPP.h4
4 files changed, 45 insertions, 23 deletions
diff --git a/GUI/GUI/GUI/PythonWrapper.cpp b/GUI/GUI/GUI/PythonWrapper.cpp
index 05c3e48..55c7626 100644
--- a/GUI/GUI/GUI/PythonWrapper.cpp
+++ b/GUI/GUI/GUI/PythonWrapper.cpp
@@ -264,7 +264,7 @@ bool PythonWrapper::InvokeCommandWithArgs(const std::string& cmd,
}
}
if (!run_cb()) {
- return true;
+ return false;
}
std::ostringstream stdout_oss, stderr_oss;
@@ -379,14 +379,18 @@ bool PythonWrapper::InstallPip(std::string* out, std::string* err) {
return ret;
}
-bool PythonWrapper::InstallPip(const std::function<void(const std::string& out, const std::string& err)>&& out_cb) {
+bool PythonWrapper::InstallPip(
+ const std::function<void(const std::string& out, const std::string& err)>&& out_cb,
+ const std::function<void(std::string& in)>&& in_cb,
+ const std::function<bool()>&& run_cb) {
std::filesystem::path pip_flag = "Resources/Python/.pip_installed";
if (std::filesystem::exists(pip_flag)) {
return true;
}
std::string pip_path = "Resources/Python/get-pip.py";
- if (!InvokeWithArgs({ pip_path }, std::move(out_cb))) {
+ if (!InvokeWithArgs({ pip_path }, std::move(out_cb), std::move(in_cb),
+ std::move(run_cb))) {
return false;
}
diff --git a/GUI/GUI/GUI/PythonWrapper.h b/GUI/GUI/GUI/PythonWrapper.h
index f0591c1..edea0df 100644
--- a/GUI/GUI/GUI/PythonWrapper.h
+++ b/GUI/GUI/GUI/PythonWrapper.h
@@ -60,7 +60,10 @@ namespace PythonWrapper
std::string DumpMics();
// Execute get-pip.py.
- bool InstallPip(const std::function<void(const std::string& out, const std::string& err)>&& out_cb);
+ bool InstallPip(
+ const std::function<void(const std::string& out, const std::string& err)>&& out_cb,
+ const std::function<void(std::string& in)>&& in_cb = [](std::string&) {},
+ const std::function<bool()>&& run_cb = []() { return true; });
bool InstallPip(std::string* out, std::string* err = nullptr);
// TODO(yum) both StartApp and GenerateAnimator should be
diff --git a/GUI/GUI/GUI/WhisperCPP.cpp b/GUI/GUI/GUI/WhisperCPP.cpp
index b969494..3610901 100644
--- a/GUI/GUI/GUI/WhisperCPP.cpp
+++ b/GUI/GUI/GUI/WhisperCPP.cpp
@@ -113,14 +113,14 @@ bool WhisperCPP::GetMics(std::vector<std::string>& mics) {
return false;
}
- std::vector<sCaptureDevice> mics_raw;
+ std::vector<std::unique_ptr<sCaptureDevice>> mics_raw;
if (!GetMicsImpl(mics_raw)) {
return false;
}
mics.clear();
for (const auto& raw_mic : mics_raw) {
- mics.push_back(wcharToAsciiString(raw_mic.displayName));
+ mics.push_back(wcharToAsciiString(raw_mic->displayName));
}
return true;
@@ -132,7 +132,7 @@ bool WhisperCPP::OpenMic(const int idx, Whisper::iAudioCapture*& stream) {
return false;
}
- std::vector<sCaptureDevice> mics_raw;
+ std::vector<std::unique_ptr<sCaptureDevice>> mics_raw;
if (!GetMicsImpl(mics_raw)) {
return false;
}
@@ -144,11 +144,11 @@ bool WhisperCPP::OpenMic(const int idx, Whisper::iAudioCapture*& stream) {
Whisper::sCaptureParams params{};
stream = nullptr;
- HRESULT err = f_->openCaptureDevice(mics_raw[idx].endpoint, params,
+ HRESULT err = f_->openCaptureDevice(mics_raw[idx]->endpoint, params,
&stream);
if (FAILED(err)) {
Log(out_, "Failed to open mic with idx {} ({}): {}\n", idx,
- wcharToAsciiString(mics_raw[idx].displayName),
+ wcharToAsciiString(mics_raw[idx]->displayName),
hresultToString(err));
return false;
}
@@ -164,17 +164,20 @@ bool WhisperCPP::InstallDependencies() {
return true;
}
- std::function<void(const std::string&, const std::string& out_cb)> out_cb =
- [&](const std::string& out, const std::string& err) -> void {
+ auto out_cb = [&](const std::string& out, const std::string& err) -> void {
Log(out_, out);
Log(out_, err);
};
+ auto in_cb = [&](std::string& in) {};
+ auto run_cb = [&]() -> bool {
+ return run_transcription_;
+ };
bool ret = PythonWrapper::InvokeWithArgs({
"-u", // Unbuffered output
"-m pip",
"install",
"-r Resources/Scripts/whisper_requirements.txt",
- }, std::move(out_cb));
+ }, std::move(out_cb), std::move(in_cb), std::move(run_cb));
if (!ret) {
Log(out_, "Failed to install dependencies!\n");
@@ -194,15 +197,20 @@ bool WhisperCPP::DownloadModel(const std::string& model_name,
url_oss << "https://huggingface.co/datasets/ggerganov/whisper.cpp/resolve/main/";
url_oss << model_name;
Log(out_, "Model will be saved to {}\n", fs_path.lexically_normal().string());
- std::string py_stdout, py_stderr;
+ auto out_cb = [&](const std::string& out, const std::string& err) {
+ Log(out_, out);
+ Log(out_, err);
+ };
+ auto in_cb = [&](std::string& in) {};
+ auto run_cb = [&]() -> bool {
+ return run_transcription_;
+ };
bool ret = PythonWrapper::InvokeWithArgs({
"-u", // Unbuffered output
"-m wget",
url_oss.str(),
"-o", fs_path.string(),
- }, &py_stdout, &py_stderr);
- Log(out_, py_stdout);
- Log(out_, py_stderr);
+ }, std::move(out_cb), std::move(in_cb), std::move(run_cb));
if (!ret) {
Log(out_, "Failed to download model!\n");
return false;
@@ -260,13 +268,17 @@ void WhisperCPP::Start(const AppConfig& c) {
ScopeGuard mic_stream_cleanup([mic_stream]() { mic_stream->Release(); });
{
- std::function<void(const std::string&, const std::string& out_cb)> out_cb =
- [&](const std::string& out, const std::string& err) -> void {
+ auto out_cb = [&](const std::string& out, const std::string& err) -> void {
Log(out_, out);
Log(out_, err);
};
+ auto in_cb = [&](std::string& in) {};
+ auto run_cb = [&]() -> bool {
+ return run_transcription_;
+ };
Log(out_, "Installing pip\n");
- if (!PythonWrapper::InstallPip(std::move(out_cb))) {
+ if (!PythonWrapper::InstallPip(std::move(out_cb), std::move(in_cb),
+ std::move(run_cb))) {
Log(out_, "Failed to install pip!\n");
return;
}
@@ -327,6 +339,7 @@ void WhisperCPP::Start(const AppConfig& c) {
// entries (source: I heard it from someone once).
static const std::vector<std::string> banned_words{
" -",
+ " (static)",
};
const sSegment* const segments = results->getSegments();
@@ -518,11 +531,11 @@ void WhisperCPP::StopCustomChatbox() {
Log(out_, "Done!\n");
}
-bool WhisperCPP::GetMicsImpl(std::vector<sCaptureDevice>& mics) {
+bool WhisperCPP::GetMicsImpl(std::vector<std::unique_ptr<sCaptureDevice>>& mics) {
pfnFoundCaptureDevices dev_cb = [](int len, const sCaptureDevice* buf, void* pv)->HRESULT __stdcall {
- std::vector<sCaptureDevice>* mics = static_cast<std::vector<sCaptureDevice>*>(pv);
+ auto mics = static_cast<std::vector<std::unique_ptr<sCaptureDevice>>*>(pv);
for (int i = 0; i < len; i++) {
- mics->push_back(buf[i]);
+ mics->push_back(std::make_unique<sCaptureDevice>(buf[i]));
}
return S_OK;
};
diff --git a/GUI/GUI/GUI/WhisperCPP.h b/GUI/GUI/GUI/WhisperCPP.h
index 1390e97..7b3f17d 100644
--- a/GUI/GUI/GUI/WhisperCPP.h
+++ b/GUI/GUI/GUI/WhisperCPP.h
@@ -18,6 +18,7 @@
#include <filesystem>
#include <functional>
#include <future>
+#include <memory>
#include <string>
#include <vector>
@@ -45,7 +46,8 @@ public:
void StopCustomChatbox();
private:
- bool GetMicsImpl(std::vector<Whisper::sCaptureDevice>& mics);
+ bool GetMicsImpl(
+ std::vector<std::unique_ptr<Whisper::sCaptureDevice>>& mics);
wxTextCtrl* out_;
Whisper::iMediaFoundation* f_;