diff options
| -rw-r--r-- | Designs/config_parser_design.md | 55 | ||||
| -rw-r--r-- | GUI/GUI/GUI/Config.cpp | 199 | ||||
| -rw-r--r-- | GUI/GUI/GUI/Config.h | 18 | ||||
| -rw-r--r-- | GUI/GUI/GUI/ConfigMarshal.h | 131 | ||||
| -rw-r--r-- | GUI/GUI/GUI/Frame.cpp | 231 | ||||
| -rw-r--r-- | GUI/GUI/GUI/Frame.h | 3 | ||||
| -rw-r--r-- | GUI/GUI/GUI/GUI.vcxproj | 2 | ||||
| -rw-r--r-- | GUI/GUI/GUI/GUI.vcxproj.filters | 6 | ||||
| -rw-r--r-- | GUI/GUI/GUI/Logging.cpp | 7 | ||||
| -rw-r--r-- | GUI/GUI/GUI/WhisperCPP.cpp | 4 | ||||
| -rw-r--r-- | GUI/Libraries/fetch.ps1 | 16 |
11 files changed, 423 insertions, 249 deletions
diff --git a/Designs/config_parser_design.md b/Designs/config_parser_design.md new file mode 100644 index 0000000..84d160a --- /dev/null +++ b/Designs/config_parser_design.md @@ -0,0 +1,55 @@ +RYML has decided to stop working and I don't want to spend any more time trying +to figure out why. + +Let's make a parser that implements the small subset of YAML that +Config.{h,cpp} rely on. + +Config needs to serialize the following types: + +* std::string +* bool +* int + +Bool will be serialized like ints, with additional requirements on +deserialization. + +Serialization looks like this: +``` +ConfigMarshall cm(out_); +cm.Append("microphone", microphone_); // string +cm.Append("rows", rows_); // int +cm.Append("use_cpu", use_cpu_); // bool +cm.Write("config.yml"); +``` + +Deserialization looks like this: +``` +ConfigMarshall cm(out_); +cm.Load("config.yml"); +cm.Get("microphone", microphone_); // string +cm.Get("rows", rows_); // int +cm.Get("use_cpu", use_cpu_); // bool +``` + +Interface: +``` +class ConfigMarshal { +public: + ConfigMarshall(wxTextCtrl *out); + + bool Save(const std::filesystem::path& path); + bool Load(const std::filesystem::path& path); + + template <typename T> + bool Append(const std::string& key, const T& value); + + template <typename T> + bool Get(const std::string& key, T& value); + +private: + std::map<std::string, std::string> kv_str_; + std::map<std::string, int> kv_int_; + std::map<std::string, bool> kv_bool_; +} +``` + diff --git a/GUI/GUI/GUI/Config.cpp b/GUI/GUI/GUI/Config.cpp index 1a5f6de..6ef8bbd 100644 --- a/GUI/GUI/GUI/Config.cpp +++ b/GUI/GUI/GUI/Config.cpp @@ -4,45 +4,49 @@ #include <wx/wx.h>
#endif
-#define RYML_SINGLE_HDR_DEFINE_NOW
-#include "ryml.h"
-
#include "Config.h"
+#include "ConfigMarshal.h"
+#include "Logging.h"
#include <fstream>
#include <memory>
#include <string>
+using ::Logging::Log;
+
bool Config::Serialize(const std::filesystem::path& path,
- const ryml::Tree* const t) {
+ const ConfigMarshal& cm) {
+ // If there's an old config, delete it.
+ struct stat tmpstat;
+ if (stat(path.string().c_str(), &tmpstat) == 0) {
+ if (::_unlink(path.string().c_str())) {
+ Log(out_, "Failed to delete old config at {}: {}\n",
+ path.string().c_str(), strerror(errno));
+ return false;
+ }
+ }
// Write the config to a tmp file. If we crash in the middle of this, it
// doesn't matter, since the next process will just overwrite it.
std::filesystem::path tmp_path = path;
- tmp_path += ".tmp";
- FILE* fp = fopen(tmp_path.string().c_str(), "wb");
- if (!fp) {
- wxLogError("Failed to open %s: %s", path.string().c_str(), strerror(errno));
- return false;
- }
- ryml::emit_yaml(t, fp); // For now we assume this didn't fail.
- fclose(fp);
- fp = nullptr;
- // If there's an old config, delete it.
- struct stat tmpstat;
- if (stat(path.string().c_str(), &tmpstat) == 0) {
- if (::_unlink(path.string().c_str())) {
- wxLogError("Failed to delete old config at %s: %s", path.string().c_str(),
- strerror(errno));
+ if (stat(tmp_path.string().c_str(), &tmpstat) == 0) {
+ if (::_unlink(tmp_path.string().c_str())) {
+ Log(out_, "Failed to delete old tmp config at {}: {}\n",
+ tmp_path.string().c_str(), strerror(errno));
return false;
}
}
+ if (!cm.Save(tmp_path)) {
+ Log(out_, "Failed to save config to {}\n", tmp_path.string());
+ return false;
+ }
+
// File renames within the same filesystem are atomic, so there's no risk
// of leaving a corrupt file on disk.
if (rename(tmp_path.string().c_str(), path.string().c_str()) != 0) {
- wxLogError("Failed to save config to %s: %s", path.string().c_str(),
+ Log(out_, "Failed to save config to {}: {}\n", path.string().c_str(),
strerror(errno));
return false;
}
@@ -51,24 +55,14 @@ bool Config::Serialize(const std::filesystem::path& path, }
bool Config::Deserialize(const std::filesystem::path& path,
- ryml::Tree* t) {
- std::ifstream file(path, std::ios::binary | std::ios::ate);
- if (!file.is_open()) {
- return false;
- }
- std::streamsize size = file.tellg();
- file.seekg(0, std::ios::beg);
- std::vector<char> yaml_buf(size);
- if (!file.read(yaml_buf.data(), size)) {
- return false;
- }
-
- *t = ryml::parse_in_place(ryml::to_substr(yaml_buf.data()));
- return true;
+ ConfigMarshal& cm) {
+ return cm.Load(path);
}
-AppConfig::AppConfig()
- : microphone("index"),
+AppConfig::AppConfig(wxTextCtrl *out)
+ : Config(out),
+
+ microphone("index"),
language("english"),
model("base.en"),
button("left joystick"),
@@ -99,84 +93,83 @@ AppConfig::AppConfig() {}
bool AppConfig::Serialize(const std::filesystem::path& path) {
- ryml::Tree t;
- ryml::NodeRef root = t.rootref();
- root |= ryml::MAP;
- root["microphone"] << ryml::to_substr(microphone);
- root["language"] << ryml::to_substr(language);
- root["model"] << ryml::to_substr(model);
- root["button"] << ryml::to_substr(button);
- root["window_duration"] << ryml::to_substr(window_duration);
-
- root["enable_local_beep"] << enable_local_beep;
- root["use_cpu"] << use_cpu;
- root["use_builtin"] << use_builtin;
-
- root["chars_per_sync"] << chars_per_sync;
- root["bytes_per_char"] << bytes_per_char;
- root["rows"] << rows;
- root["cols"] << cols;
-
- root["assets_path"] << ryml::to_substr(assets_path);
- root["fx_path"] << ryml::to_substr(fx_path);
- root["params_path"] << ryml::to_substr(params_path);
- root["menu_path"] << ryml::to_substr(menu_path);
- root["clear_osc"] << clear_osc;
-
- root["whisper_model"] << whisper_model;
- root["whisper_mic"] << whisper_mic;
-
- root["browser_src_port"] << browser_src_port;
- root["whisper_enable_builtin"] << whisper_enable_builtin;
- root["whisper_enable_custom"] << whisper_enable_custom;
- root["whisper_enable_browser_src"] << whisper_enable_browser_src;
-
- return Config::Serialize(path, &t);
+ ConfigMarshal cm(out_);
+
+ cm.Set("microphone", microphone);
+ cm.Set("language", language);
+ cm.Set("model", model);
+ cm.Set("button", button);
+ cm.Set("window_duration", window_duration);
+
+ cm.Set("enable_local_beep", enable_local_beep);
+ cm.Set("use_cpu", use_cpu);
+ cm.Set("use_builtin", use_builtin);
+
+ cm.Set("chars_per_sync", chars_per_sync);
+ cm.Set("bytes_per_char", bytes_per_char);
+ cm.Set("rows", rows);
+ cm.Set("cols", cols);
+
+ cm.Set("assets_path", assets_path);
+ cm.Set("fx_path", fx_path);
+ cm.Set("params_path", params_path);
+ cm.Set("menu_path", menu_path);
+ cm.Set("clear_osc", clear_osc);
+
+ cm.Set("whisper_model", whisper_model);
+ cm.Set("whisper_mic", whisper_mic);
+
+ cm.Set("browser_src_port", browser_src_port);
+ cm.Set("whisper_enable_builtin", whisper_enable_builtin);
+ cm.Set("whisper_enable_custom", whisper_enable_custom);
+ cm.Set("whisper_enable_browser_src", whisper_enable_browser_src);
+
+ return Config::Serialize(path, cm);
}
bool AppConfig::Deserialize(const std::filesystem::path& path) {
std::error_code err;
if (!std::filesystem::exists(path, err)) {
- *this = AppConfig();
+ *this = AppConfig(out_);
+ Log(out_, "Cannot deserialize config at path {}: Does not exist!\n", path.string());
return true;
}
- ryml::Tree t{};
- if (!Config::Deserialize(path, &t)) {
- wxLogError("Deserialization failed at %s", path.string());
+ ConfigMarshal cm(out_);
+ if (!Config::Deserialize(path, cm)) {
+ Log(out_, "Deserialization failed at {}\n", path.string());
return false;
}
- ryml::ConstNodeRef root = t.rootref();
- AppConfig c;
- root.get_if("microphone", &c.microphone);
- root.get_if("language", &c.language);
- root.get_if("model", &c.model);
- root.get_if("button", &c.button);
- root.get_if("window_duration", &c.window_duration);
-
- root.get_if("enable_local_beep", &c.enable_local_beep);
- root.get_if("use_cpu", &c.use_cpu);
- root.get_if("use_builtin", &c.use_builtin);
-
- root.get_if("chars_per_sync", &c.chars_per_sync);
- root.get_if("bytes_per_char", &c.bytes_per_char);
- root.get_if("rows", &c.rows);
- root.get_if("cols", &c.cols);
-
- root.get_if("assets_path", &c.assets_path);
- root.get_if("fx_path", &c.fx_path);
- root.get_if("params_path", &c.params_path);
- root.get_if("menu_path", &c.menu_path);
- root.get_if("clear_osc", &c.clear_osc);
-
- root.get_if("whisper_model", &c.whisper_model);
- root.get_if("whisper_mic", &c.whisper_mic);
-
- root.get_if("browser_src_port", &c.browser_src_port);
- root.get_if("whisper_enable_builtin", &c.whisper_enable_builtin);
- root.get_if("whisper_enable_custom", &c.whisper_enable_custom);
- root.get_if("whisper_enable_browser_src", &c.whisper_enable_browser_src);
+ AppConfig c(out_);
+ cm.Get("microphone", c.microphone);
+ cm.Get("language", c.language);
+ cm.Get("model", c.model);
+ cm.Get("button", c.button);
+ cm.Get("window_duration", c.window_duration);
+
+ cm.Get("enable_local_beep", c.enable_local_beep);
+ cm.Get("use_cpu", c.use_cpu);
+ cm.Get("use_builtin", c.use_builtin);
+
+ cm.Get("chars_per_sync", c.chars_per_sync);
+ cm.Get("bytes_per_char", c.bytes_per_char);
+ cm.Get("rows", c.rows);
+ cm.Get("cols", c.cols);
+
+ cm.Get("assets_path", c.assets_path);
+ cm.Get("fx_path", c.fx_path);
+ cm.Get("params_path", c.params_path);
+ cm.Get("menu_path", c.menu_path);
+ cm.Get("clear_osc", c.clear_osc);
+
+ cm.Get("whisper_model", c.whisper_model);
+ cm.Get("whisper_mic", c.whisper_mic);
+
+ cm.Get("browser_src_port", c.browser_src_port);
+ cm.Get("whisper_enable_builtin", c.whisper_enable_builtin);
+ cm.Get("whisper_enable_custom", c.whisper_enable_custom);
+ cm.Get("whisper_enable_browser_src", c.whisper_enable_browser_src);
*this = std::move(c);
return true;
diff --git a/GUI/GUI/GUI/Config.h b/GUI/GUI/GUI/Config.h index bf5bfb0..14dcc58 100644 --- a/GUI/GUI/GUI/Config.h +++ b/GUI/GUI/GUI/Config.h @@ -1,6 +1,12 @@ #pragma once
-#include "ryml.h"
+#include <wx/wxprec.h>
+
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+
+#include "ConfigMarshal.h"
#include <filesystem>
@@ -8,6 +14,8 @@ // (Serialize) and restore from disk (Deserialize).
class Config {
public:
+ Config(wxTextCtrl* out) : out_(out) {}
+
virtual ~Config() {}
virtual bool Serialize(const std::filesystem::path& path) = 0;
@@ -16,10 +24,12 @@ public: protected:
virtual bool Serialize(const std::filesystem::path& path,
- const ryml::Tree* t);
+ const ConfigMarshal& cm);
virtual bool Deserialize(const std::filesystem::path& path,
- ryml::Tree* t);
+ ConfigMarshal& cm);
+
+ wxTextCtrl* out_;
};
// Represents the configurable fields for the GUI. Used by both the
@@ -28,7 +38,7 @@ class AppConfig : public Config { public:
virtual ~AppConfig() {}
- AppConfig();
+ AppConfig(wxTextCtrl* out);
bool Serialize(const std::filesystem::path& path) override;
diff --git a/GUI/GUI/GUI/ConfigMarshal.h b/GUI/GUI/GUI/ConfigMarshal.h new file mode 100644 index 0000000..a2f17f9 --- /dev/null +++ b/GUI/GUI/GUI/ConfigMarshal.h @@ -0,0 +1,131 @@ +#pragma once
+
+#include <wx/wxprec.h>
+
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+
+#include "Logging.h"
+
+#include <filesystem>
+#include <fstream>
+#include <map>
+#include <sstream>
+#include <string>
+#include <type_traits>
+
+class ConfigMarshal
+{
+public:
+ ConfigMarshal(wxTextCtrl* const out)
+ : out_(out)
+ {}
+
+ bool Save(const std::filesystem::path& path) const {
+ std::ostringstream oss;
+ for (const auto& [k, v] : kv_str_) {
+ oss << k << ": " << v << std::endl;
+ }
+ for (const auto& [k, v] : kv_int_) {
+ oss << k << ": " << std::to_string(v) << std::endl;
+ }
+
+ std::ofstream ofs(path.string());
+ ofs << oss.str();
+ ofs.close();
+
+ return true;
+ }
+
+ bool Load(const std::filesystem::path& path) {
+ std::ifstream ifs(path.string());
+ std::string line;
+ while (std::getline(ifs, line)) {
+ int n_words = 0;
+
+ std::string delim = ": ";
+ size_t delim_pos = line.find(delim, 0);
+ if (delim_pos == std::string::npos) {
+ Logging::Log(out_, "Invalid config file: line {} has no delimiter\n", line);
+ return false;
+ }
+ std::string key = line.substr(0, delim_pos);
+ std::string val = line.substr(delim_pos + delim.length());
+
+ try {
+ size_t pos;
+ int val_i = std::stoi(val, &pos);
+ if (pos == val.length()) {
+ // The entire value is an int -> interpret as an int. Corollary: users
+ // can't store ints as strings!
+ kv_int_[key] = val_i;
+ continue;
+ }
+ }
+ catch (const std::invalid_argument&) {}
+ catch (const std::out_of_range&) {}
+
+ kv_str_[key] = val;
+ }
+ return true;
+ }
+
+ template <typename T>
+ bool Set(const std::string& key, const T& value) {
+ if constexpr (std::is_same_v<T, std::string>) {
+ kv_str_[key] = value;
+ return true;
+ }
+ if constexpr (std::is_same_v<T, int> || std::is_same_v<T, bool>) {
+ kv_int_[key] = static_cast<int>(value);
+ return true;
+ }
+ Logging::Log(out_, "ConfigMarshal unsupported type: {}\n", typeid(T).name());
+ return false;
+ }
+
+ template <typename T>
+ bool Get(const std::string& key, T& value) const {
+ if constexpr (std::is_same_v<T, std::string>) {
+ auto iter = kv_str_.find(key);
+ if (iter == kv_str_.end()) {
+ // Edge case: string may be represented entirely as an int, so
+ // it was parsed out as an int.
+ auto iter = kv_int_.find(key);
+ if (iter == kv_int_.end()) {
+ Logging::Log(out_, "Config contains no field named `{}`\n", key);
+ return false;
+ }
+ value = std::to_string(iter->second);
+ return true;
+ }
+ value = iter->second;
+ return true;
+ }
+ if constexpr (std::is_same_v<T, int> || std::is_same_v<T, bool>) {
+ auto iter = kv_int_.find(key);
+ if (iter == kv_int_.end()) {
+ Logging::Log(out_, "Config contains no field named `{}`\n", key);
+ return false;
+ }
+ if constexpr (std::is_same_v<T, bool>) {
+ if (iter->second < 0 || iter->second > 1) {
+ Logging::Log(out_, "Config field {} is out of boolean range: {}\n", key, iter->second);
+ return false;
+ }
+ }
+ value = static_cast<T>(iter->second);
+ return true;
+ }
+ Logging::Log(out_, "ConfigMarshal unsupported type: {}\n", typeid(T).name());
+ return false;
+ }
+
+
+private:
+ wxTextCtrl* out_;
+
+ std::map<std::string, std::string> kv_str_;
+ std::map<std::string, int> kv_int_;
+};
diff --git a/GUI/GUI/GUI/Frame.cpp b/GUI/GUI/GUI/Frame.cpp index 01b3140..de99bdc 100644 --- a/GUI/GUI/GUI/Frame.cpp +++ b/GUI/GUI/GUI/Frame.cpp @@ -82,7 +82,6 @@ namespace { ID_WHISPER_BUTTON,
ID_WHISPER_ROWS,
ID_WHISPER_COLS,
- ID_WHISPER_WINDOW_DURATION,
ID_WHISPER_BROWSER_SRC_PORT,
ID_WHISPER_ENABLE_LOCAL_BEEP,
ID_WHISPER_USE_CPU,
@@ -331,7 +330,7 @@ Frame::Frame() env_proc_(nullptr),
py_app_drain_(this, ID_PY_APP_DRAIN)
{
- app_c_.Deserialize(AppConfig::kConfigPath);
+ app_c_ = std::make_unique<AppConfig>(nullptr);
auto* main_panel = new wxPanel(this, ID_MAIN_PANEL);
main_panel_ = main_panel;
@@ -340,12 +339,12 @@ Frame::Frame() {
auto* navbar_button_transcribe = new wxButton(navbar,
ID_NAVBAR_BUTTON_TRANSCRIBE, "Transcription (PY)");
+ auto* navbar_button_whisper = new wxButton(navbar,
+ ID_NAVBAR_BUTTON_WHISPER, "Transcription (CPP)");
auto* navbar_button_unity = new wxButton(navbar,
ID_NAVBAR_BUTTON_UNITY, "Unity");
auto* navbar_button_debug = new wxButton(navbar,
ID_NAVBAR_BUTTON_DEBUG, "Debug");
- auto* navbar_button_whisper = new wxButton(navbar,
- ID_NAVBAR_BUTTON_WHISPER, "Transcription (CPP)");
auto* sizer = new wxBoxSizer(wxVERTICAL);
navbar->SetSizer(sizer);
@@ -455,14 +454,14 @@ Frame::Frame() py_app_button_ = py_app_button;
auto* py_app_rows = new wxTextCtrl(py_app_config_panel_pairs,
- ID_PY_APP_ROWS, std::to_string(app_c_.rows),
+ ID_PY_APP_ROWS, std::to_string(app_c_->rows),
wxDefaultPosition, wxDefaultSize, /*style=*/0);
py_app_rows->SetToolTip(
"The number of rows on the text box.");
py_app_rows_ = py_app_rows;
auto* py_app_cols = new wxTextCtrl(py_app_config_panel_pairs,
- ID_PY_APP_COLS, std::to_string(app_c_.cols),
+ ID_PY_APP_COLS, std::to_string(app_c_->cols),
wxDefaultPosition, wxDefaultSize, /*style=*/0);
py_app_cols->SetToolTip(
"The number of columns on the text box.");
@@ -470,7 +469,7 @@ Frame::Frame() auto* py_app_window_duration = new wxTextCtrl(
py_app_config_panel_pairs, ID_PY_APP_WINDOW_DURATION,
- app_c_.window_duration, wxDefaultPosition,
+ app_c_->window_duration, wxDefaultPosition,
wxDefaultSize, /*style=*/0);
py_app_window_duration->SetToolTip(
"This controls how long the slice of audio that "
@@ -532,7 +531,7 @@ Frame::Frame() auto* py_app_enable_local_beep = new wxCheckBox(py_config_panel,
ID_PY_APP_ENABLE_LOCAL_BEEP, "Enable local beep");
- py_app_enable_local_beep->SetValue(app_c_.enable_local_beep);
+ py_app_enable_local_beep->SetValue(app_c_->enable_local_beep);
py_app_enable_local_beep->SetToolTip(
"By default, TaSTT will play a sound (audible only to "
"you) when it begins transcription and when it stops. "
@@ -542,7 +541,7 @@ Frame::Frame() auto* py_app_use_cpu = new wxCheckBox(py_config_panel,
ID_PY_APP_USE_CPU, "Use CPU");
- py_app_use_cpu->SetValue(app_c_.use_cpu);
+ py_app_use_cpu->SetValue(app_c_->use_cpu);
py_app_use_cpu->SetToolTip(
"If checked, the transcription engine will run on your "
"CPU instead of your GPU. This is typically much slower "
@@ -553,7 +552,7 @@ Frame::Frame() auto* py_app_use_builtin = new wxCheckBox(py_config_panel,
ID_PY_APP_USE_BUILTIN, "Use built-in chatbox");
- py_app_use_builtin->SetValue(app_c_.use_builtin);
+ py_app_use_builtin->SetValue(app_c_->use_builtin);
py_app_use_builtin->SetToolTip(
"If checked, text will be sent to the built-in text box "
"instead of one attached to the current avatar."
@@ -613,7 +612,7 @@ Frame::Frame() auto* unity_assets_file_picker = new wxDirPickerCtrl(
unity_config_panel_pairs,
ID_UNITY_ASSETS_FILE_PICKER,
- /*path=*/app_c_.assets_path,
+ /*path=*/app_c_->assets_path,
/*message=*/"Unity Assets folder"
);
unity_assets_file_picker->SetToolTip(
@@ -625,7 +624,7 @@ Frame::Frame() auto* unity_animator_file_picker = new wxFilePickerCtrl(
unity_config_panel_pairs,
ID_UNITY_ANIMATOR_FILE_PICKER,
- /*path=*/app_c_.fx_path,
+ /*path=*/app_c_->fx_path,
/*message=*/"FX controller path",
/*wildcard=*/wxFileSelectorDefaultWildcardStr,
/*pos=*/wxDefaultPosition,
@@ -640,7 +639,7 @@ Frame::Frame() auto* unity_parameters_file_picker = new wxFilePickerCtrl(
unity_config_panel_pairs,
ID_UNITY_PARAMETERS_FILE_PICKER,
- /*path=*/app_c_.params_path,
+ /*path=*/app_c_->params_path,
/*message=*/"Avatar parameters path",
/*wildcard=*/wxFileSelectorDefaultWildcardStr,
/*pos=*/wxDefaultPosition,
@@ -656,7 +655,7 @@ Frame::Frame() auto* unity_menu_file_picker = new wxFilePickerCtrl(
unity_config_panel_pairs,
ID_UNITY_MENU_FILE_PICKER,
- /*path=*/app_c_.menu_path,
+ /*path=*/app_c_->menu_path,
/*message=*/"Avatar menu path",
/*wildcard=*/wxFileSelectorDefaultWildcardStr,
/*pos=*/wxDefaultPosition,
@@ -745,14 +744,14 @@ Frame::Frame() unity_bytes_per_char_ = unity_bytes_per_char;
auto* unity_rows = new wxTextCtrl(unity_config_panel_pairs,
- ID_UNITY_ROWS, std::to_string(app_c_.rows),
+ ID_UNITY_ROWS, std::to_string(app_c_->rows),
wxDefaultPosition, wxDefaultSize, /*style=*/0);
unity_rows->SetToolTip(
"The number of rows on the text box.");
unity_rows_ = unity_rows;
auto* unity_cols = new wxTextCtrl(unity_config_panel_pairs,
- ID_UNITY_COLS, std::to_string(app_c_.cols),
+ ID_UNITY_COLS, std::to_string(app_c_->cols),
wxDefaultPosition, wxDefaultSize, /*style=*/0);
unity_cols->SetToolTip(
"The number of columns on the text box.");
@@ -816,7 +815,7 @@ Frame::Frame() auto* clear_osc = new wxCheckBox(unity_config_panel,
ID_UNITY_CLEAR_OSC, "Clear OSC configs");
- clear_osc->SetValue(app_c_.clear_osc);
+ clear_osc->SetValue(app_c_->clear_osc);
clear_osc->SetToolTip(
"If checked, VRChat's OSC configs will be cleared. "
"VRC SDK has a bug where parameters added to an "
@@ -925,35 +924,22 @@ Frame::Frame() whisper_button_ = whisper_button;
auto* whisper_rows = new wxTextCtrl(whisper_config_panel_pairs,
- ID_WHISPER_ROWS, std::to_string(app_c_.rows),
+ ID_WHISPER_ROWS, std::to_string(app_c_->rows),
wxDefaultPosition, wxDefaultSize, /*style=*/0);
whisper_rows->SetToolTip(
"The number of rows on the text box.");
whisper_rows_ = whisper_rows;
auto* whisper_cols = new wxTextCtrl(whisper_config_panel_pairs,
- ID_WHISPER_COLS, std::to_string(app_c_.cols),
+ ID_WHISPER_COLS, std::to_string(app_c_->cols),
wxDefaultPosition, wxDefaultSize, /*style=*/0);
whisper_cols->SetToolTip(
"The number of columns on the text box.");
whisper_cols_ = whisper_cols;
- auto* whisper_window_duration = new wxTextCtrl(
- whisper_config_panel_pairs, ID_WHISPER_WINDOW_DURATION,
- app_c_.window_duration, wxDefaultPosition,
- wxDefaultSize, /*style=*/0);
- whisper_window_duration->SetToolTip(
- "This controls how long the slice of audio that "
- "we feed the transcription algorithm is, in seconds. "
- "Shorter values (as low as 10 seconds) can be whisperd "
- "more quickly, but are less accurate. Longer values "
- "(as high as 28 seconds) take longer to whisper, "
- "but are far more accurate.");
- whisper_window_duration_ = whisper_window_duration;
-
auto* whisper_browser_src_port = new wxTextCtrl(
whisper_config_panel_pairs, ID_WHISPER_BROWSER_SRC_PORT,
- std::to_string(app_c_.browser_src_port), wxDefaultPosition,
+ std::to_string(app_c_->browser_src_port), wxDefaultPosition,
wxDefaultSize, /*style=*/0);
whisper_browser_src_port->SetToolTip(
"This is the port that the browser source is hosted "
@@ -1005,11 +991,6 @@ Frame::Frame() /*flags=*/wxEXPAND);
sizer->Add(new wxStaticText(whisper_config_panel_pairs,
- wxID_ANY, /*label=*/"Window duration (s):"));
- sizer->Add(whisper_window_duration, /*proportion=*/0,
- /*flags=*/wxEXPAND);
-
- sizer->Add(new wxStaticText(whisper_config_panel_pairs,
wxID_ANY, /*label=*/"Browser source port:"));
sizer->Add(whisper_browser_src_port, /*proportion=*/0,
/*flags=*/wxEXPAND);
@@ -1017,7 +998,7 @@ Frame::Frame() auto* whisper_enable_local_beep = new wxCheckBox(whisper_config_panel,
ID_WHISPER_ENABLE_LOCAL_BEEP, "Enable local beep");
- whisper_enable_local_beep->SetValue(app_c_.enable_local_beep);
+ whisper_enable_local_beep->SetValue(app_c_->enable_local_beep);
whisper_enable_local_beep->SetToolTip(
"By default, TaSTT will play a sound (audible only to "
"you) when it begins transcription and when it stops. "
@@ -1027,7 +1008,7 @@ Frame::Frame() auto* whisper_use_cpu = new wxCheckBox(whisper_config_panel,
ID_WHISPER_USE_CPU, "Use CPU");
- whisper_use_cpu->SetValue(app_c_.use_cpu);
+ whisper_use_cpu->SetValue(app_c_->use_cpu);
whisper_use_cpu->SetToolTip(
"If checked, the transcription engine will run on your "
"CPU instead of your GPU. This is typically much slower "
@@ -1038,7 +1019,7 @@ Frame::Frame() auto* whisper_enable_builtin = new wxCheckBox(whisper_config_panel,
ID_WHISPER_ENABLE_BUILTIN, "Send to built-in chatbox");
- whisper_enable_builtin->SetValue(app_c_.whisper_enable_builtin);
+ whisper_enable_builtin->SetValue(app_c_->whisper_enable_builtin);
whisper_enable_builtin->SetToolTip(
"If checked, text will be sent to the built-in text box."
);
@@ -1046,7 +1027,7 @@ Frame::Frame() auto* whisper_enable_custom = new wxCheckBox(whisper_config_panel,
ID_WHISPER_ENABLE_CUSTOM, "Send to custom chatbox");
- whisper_enable_custom->SetValue(app_c_.whisper_enable_custom);
+ whisper_enable_custom->SetValue(app_c_->whisper_enable_custom);
whisper_enable_custom->SetToolTip(
"If checked, text will be sent to the custom text box."
);
@@ -1054,7 +1035,7 @@ Frame::Frame() auto* whisper_enable_browser_src = new wxCheckBox(whisper_config_panel,
ID_WHISPER_ENABLE_BROWSER_SRC, "Send to browser source");
- whisper_enable_browser_src->SetValue(app_c_.whisper_enable_browser_src);
+ whisper_enable_browser_src->SetValue(app_c_->whisper_enable_browser_src);
whisper_enable_browser_src->SetToolTip(
"If checked, text will be sent to a browser source. If "
"you're not using TaSTT to stream, you can ignore this option.");
@@ -1199,6 +1180,11 @@ Frame::Frame() sizer->Add(whisper_panel, /*proportion=*/1, /*flags=*/wxEXPAND);
}
+ // Now that transcribe_out_ has been created, we can deserialize.
+ app_c_ = std::make_unique<AppConfig>(transcribe_out_);
+ Log(transcribe_out_, "Deserializing config\n");
+ app_c_->Deserialize(AppConfig::kConfigPath);
+
Bind(wxEVT_CLOSE_WINDOW, &Frame::OnExit, this, wxID_EXIT);
Bind(wxEVT_BUTTON, &Frame::OnNavbarTranscribe, this,
ID_NAVBAR_BUTTON_TRANSCRIBE);
@@ -1251,47 +1237,47 @@ void Frame::ApplyConfigToInputFields() // Transcription panel
auto* py_app_mic = static_cast<wxChoice*>(FindWindowById(ID_PY_APP_MIC));
int mic_idx = GetDropdownChoiceIndex(kMicChoices,
- kNumMicChoices, app_c_.microphone, kMicDefault);
+ kNumMicChoices, app_c_->microphone, kMicDefault);
py_app_mic->SetSelection(mic_idx);
auto* py_app_lang = static_cast<wxChoice*>(FindWindowById(ID_PY_APP_LANG));
int lang_idx = GetDropdownChoiceIndex(kLangChoices,
- kNumLangChoices, app_c_.language, kLangDefault);
+ kNumLangChoices, app_c_->language, kLangDefault);
py_app_lang->SetSelection(lang_idx);
auto* py_app_model = static_cast<wxChoice*>(FindWindowById(ID_PY_APP_MODEL));
int model_idx = GetDropdownChoiceIndex(kModelChoices,
- kNumModelChoices, app_c_.model, kModelDefault);
+ kNumModelChoices, app_c_->model, kModelDefault);
py_app_model->SetSelection(model_idx);
auto* py_app_button = static_cast<wxChoice*>(FindWindowById(ID_PY_APP_BUTTON));
int button_idx = GetDropdownChoiceIndex(kButton,
- kNumButtons, app_c_.button, kButtonDefault);
+ kNumButtons, app_c_->button, kButtonDefault);
py_app_button->SetSelection(button_idx);
auto* py_app_chars_per_sync = static_cast<wxChoice*>(FindWindowById(ID_PY_APP_CHARS_PER_SYNC));
int chars_idx = GetDropdownChoiceIndex(kCharsPerSync,
- kNumCharsPerSync, std::to_string(app_c_.chars_per_sync),
+ kNumCharsPerSync, std::to_string(app_c_->chars_per_sync),
kCharsDefault);
py_app_chars_per_sync->SetSelection(chars_idx);
auto* py_app_bytes_per_char = static_cast<wxChoice*>(FindWindowById(ID_PY_APP_BYTES_PER_CHAR));
int bytes_idx = GetDropdownChoiceIndex(kBytesPerChar,
- kNumBytesPerChar, std::to_string(app_c_.bytes_per_char),
+ kNumBytesPerChar, std::to_string(app_c_->bytes_per_char),
kBytesDefault);
py_app_bytes_per_char->SetSelection(bytes_idx);
auto* py_app_rows = static_cast<wxTextCtrl*>(FindWindowById(ID_PY_APP_ROWS));
py_app_rows->Clear();
- py_app_rows->AppendText(std::to_string(app_c_.rows));
+ py_app_rows->AppendText(std::to_string(app_c_->rows));
auto* py_app_cols = static_cast<wxTextCtrl*>(FindWindowById(ID_PY_APP_COLS));
py_app_cols->Clear();
- py_app_cols->AppendText(std::to_string(app_c_.cols));
+ py_app_cols->AppendText(std::to_string(app_c_->cols));
// Whisper panel
auto* whisper_mic = static_cast<wxChoice*>(FindWindowById(ID_WHISPER_MIC));
- int whisper_mic_idx = app_c_.whisper_mic;
+ int whisper_mic_idx = app_c_->whisper_mic;
whisper_mic->SetSelection(whisper_mic_idx);
auto* whisper_lang = static_cast<wxChoice*>(FindWindowById(ID_WHISPER_LANG));
@@ -1299,7 +1285,7 @@ void Frame::ApplyConfigToInputFields() auto* whisper_model = static_cast<wxChoice*>(FindWindowById(ID_WHISPER_MODEL));
int whisper_model_idx = GetDropdownChoiceIndex(kWhisperModelChoices,
- kNumWhisperModelChoices, app_c_.whisper_model, kWhisperModelDefault);
+ kNumWhisperModelChoices, app_c_->whisper_model, kWhisperModelDefault);
whisper_model->SetSelection(whisper_model_idx);
auto* whisper_button = static_cast<wxChoice*>(FindWindowById(ID_WHISPER_BUTTON));
@@ -1313,11 +1299,30 @@ void Frame::ApplyConfigToInputFields() auto* whisper_rows = static_cast<wxTextCtrl*>(FindWindowById(ID_WHISPER_ROWS));
whisper_rows->Clear();
- whisper_rows->AppendText(std::to_string(app_c_.rows));
+ whisper_rows->AppendText(std::to_string(app_c_->rows));
auto* whisper_cols = static_cast<wxTextCtrl*>(FindWindowById(ID_WHISPER_COLS));
whisper_cols->Clear();
- whisper_cols->AppendText(std::to_string(app_c_.cols));
+ whisper_cols->AppendText(std::to_string(app_c_->cols));
+
+ auto* whisper_browser_src_port = static_cast<wxTextCtrl*>(FindWindowById(ID_WHISPER_BROWSER_SRC_PORT));
+ whisper_browser_src_port->Clear();
+ whisper_browser_src_port->AppendText(std::to_string(app_c_->browser_src_port));
+
+ auto* whisper_enable_local_beep = static_cast<wxCheckBox*>(FindWindowById(ID_WHISPER_ENABLE_LOCAL_BEEP));
+ whisper_enable_local_beep->SetValue(app_c_->enable_local_beep);
+
+ auto* whisper_use_cpu = static_cast<wxCheckBox*>(FindWindowById(ID_WHISPER_USE_CPU));
+ whisper_use_cpu->SetValue(app_c_->use_cpu);
+
+ auto* whisper_enable_builtin = static_cast<wxCheckBox*>(FindWindowById(ID_WHISPER_ENABLE_BUILTIN));
+ whisper_enable_builtin->SetValue(app_c_->whisper_enable_builtin);
+
+ auto* whisper_enable_custom = static_cast<wxCheckBox*>(FindWindowById(ID_WHISPER_ENABLE_CUSTOM));
+ whisper_enable_custom->SetValue(app_c_->whisper_enable_custom);
+
+ auto* whisper_enable_browser_src = static_cast<wxCheckBox*>(FindWindowById(ID_WHISPER_ENABLE_BROWSER_SRC));
+ whisper_enable_browser_src->SetValue(app_c_->whisper_enable_browser_src);
// Unity panel
auto* unity_chars_per_sync = static_cast<wxChoice*>(FindWindowById(ID_UNITY_CHARS_PER_SYNC));
@@ -1328,11 +1333,11 @@ void Frame::ApplyConfigToInputFields() auto* unity_rows = static_cast<wxTextCtrl*>(FindWindowById(ID_UNITY_ROWS));
unity_rows->Clear();
- unity_rows->AppendText(std::to_string(app_c_.rows));
+ unity_rows->AppendText(std::to_string(app_c_->rows));
auto* unity_cols = static_cast<wxTextCtrl*>(FindWindowById(ID_UNITY_COLS));
unity_cols->Clear();
- unity_cols->AppendText(std::to_string(app_c_.cols));
+ unity_cols->AppendText(std::to_string(app_c_->cols));
}
void Frame::PopulateDynamicInputFields()
@@ -1555,20 +1560,20 @@ void Frame::OnGenerateFX(wxCommandEvent& event) return;
}
- app_c_.assets_path = unity_assets_path.string();
- app_c_.fx_path = unity_animator_path.string();
- app_c_.params_path = unity_parameters_path.string();
- app_c_.menu_path = unity_menu_path.string();
- app_c_.bytes_per_char = bytes_per_char;
- app_c_.chars_per_sync = chars_per_sync;
- app_c_.rows = rows;
- app_c_.cols = cols;
- app_c_.clear_osc = unity_clear_osc_->GetValue();
- app_c_.Serialize(AppConfig::kConfigPath);
+ app_c_->assets_path = unity_assets_path.string();
+ app_c_->fx_path = unity_animator_path.string();
+ app_c_->params_path = unity_parameters_path.string();
+ app_c_->menu_path = unity_menu_path.string();
+ app_c_->bytes_per_char = bytes_per_char;
+ app_c_->chars_per_sync = chars_per_sync;
+ app_c_->rows = rows;
+ app_c_->cols = cols;
+ app_c_->clear_osc = unity_clear_osc_->GetValue();
+ app_c_->Serialize(AppConfig::kConfigPath);
std::string out;
if (!PythonWrapper::GenerateAnimator(
- app_c_,
+ *app_c_,
unity_animator_generated_dir,
unity_animator_generated_name,
unity_parameters_generated_name,
@@ -1860,26 +1865,26 @@ void Frame::OnAppStart(wxCommandEvent& event) { return;
}
- app_c_.microphone = kMicChoices[which_mic].ToStdString();
- app_c_.language = kLangChoices[which_lang].ToStdString();
- app_c_.model = kModelChoices[which_model].ToStdString();
- app_c_.chars_per_sync = chars_per_sync;
- app_c_.bytes_per_char = bytes_per_char;
- app_c_.button = kButton[button_idx].ToStdString();
- app_c_.rows = rows;
- app_c_.cols = cols;
- app_c_.window_duration = std::to_string(window_duration);
- app_c_.enable_local_beep = enable_local_beep;
- app_c_.use_cpu = use_cpu;
- app_c_.use_builtin = use_builtin;
- app_c_.Serialize(AppConfig::kConfigPath);
+ app_c_->microphone = kMicChoices[which_mic].ToStdString();
+ app_c_->language = kLangChoices[which_lang].ToStdString();
+ app_c_->model = kModelChoices[which_model].ToStdString();
+ app_c_->chars_per_sync = chars_per_sync;
+ app_c_->bytes_per_char = bytes_per_char;
+ app_c_->button = kButton[button_idx].ToStdString();
+ app_c_->rows = rows;
+ app_c_->cols = cols;
+ app_c_->window_duration = std::to_string(window_duration);
+ app_c_->enable_local_beep = enable_local_beep;
+ app_c_->use_cpu = use_cpu;
+ app_c_->use_builtin = use_builtin;
+ app_c_->Serialize(AppConfig::kConfigPath);
auto cb = [&](wxProcess* proc, int ret) -> void {
Log(transcribe_out_, "Transcription engine exited with code {}\n", ret);
DrainAsyncOutput(proc, transcribe_out_);
return;
};
- wxProcess* p = PythonWrapper::StartApp(std::move(cb), app_c_);
+ wxProcess* p = PythonWrapper::StartApp(std::move(cb), *app_c_);
if (!p) {
Log(transcribe_out_, "Failed to launch transcription engine\n");
return;
@@ -1967,46 +1972,37 @@ void Frame::OnWhisperStart(wxCommandEvent& event) { kCharsPerSync[chars_per_sync_idx].ToStdString();
std::string bytes_per_char_str =
kBytesPerChar[bytes_per_char_idx].ToStdString();
- std::string window_duration_str =
- whisper_window_duration_->GetValue().ToStdString();
std::string browser_src_port_str =
whisper_browser_src_port_->GetValue().ToStdString();
- int rows, cols, chars_per_sync, bytes_per_char, window_duration, browser_src_port;
+ int rows, cols, chars_per_sync, bytes_per_char, browser_src_port;
try {
rows = std::stoi(rows_str);
cols = std::stoi(cols_str);
chars_per_sync = std::stoi(chars_per_sync_str);
bytes_per_char = std::stoi(bytes_per_char_str);
- window_duration = std::stoi(window_duration_str);
browser_src_port = std::stoi(browser_src_port_str);
}
catch (const std::invalid_argument&) {
Log(whisper_out_, "Could not parse rows \"{}\", cols \"{}\", chars "
- "per sync \"{}\", bytes per char \"{}\" or window duration \"{}\" "
+ "per sync \"{}\", or bytes per char \"{}\" "
"as an integer\n", rows_str, cols_str, chars_per_sync_str,
- bytes_per_char_str, window_duration_str);
+ bytes_per_char_str);
return;
}
catch (const std::out_of_range&) {
Log(whisper_out_, "Rows \"{}\", cols \"{}\", chars per sync "
- "\"{}\", bytes per char \"{}\" or window duration \"{}\" are out "
+ "\"{}\", or bytes per char \"{}\" are out "
"of range\n", rows_str, cols_str, chars_per_sync_str,
- bytes_per_char_str, window_duration_str);
+ bytes_per_char_str);
return;
}
const int max_rows = 10;
const int max_cols = 240;
- const int min_window_duration_s = 10;
- const int max_window_duration_s = 28;
if (rows < 0 || rows > max_rows ||
- cols < 0 || cols > max_cols ||
- window_duration < min_window_duration_s ||
- window_duration > max_window_duration_s) {
- Log(whisper_out_, "Rows not on [{},{}] or cols not on [{},{}] or "
- "window_duration not on [{},{}]\n",
+ cols < 0 || cols > max_cols) {
+ Log(whisper_out_, "Rows not on [{},{}] or cols not on [{},{}]\n",
0, max_rows,
- 0, max_cols,
- min_window_duration_s, max_window_duration_s);
+ 0, max_cols);
return;
}
@@ -2018,27 +2014,26 @@ void Frame::OnWhisperStart(wxCommandEvent& event) { return;
}
- app_c_.whisper_mic = which_mic;
- app_c_.language = kLangChoices[which_lang].ToStdString();
- app_c_.whisper_model = kWhisperModelChoices[which_model].ToStdString();
- app_c_.chars_per_sync = chars_per_sync;
- app_c_.bytes_per_char = bytes_per_char;
- app_c_.button = kButton[button_idx].ToStdString();
- app_c_.rows = rows;
- app_c_.cols = cols;
- app_c_.window_duration = std::to_string(window_duration);
- app_c_.enable_local_beep = enable_local_beep;
- app_c_.use_cpu = use_cpu;
- app_c_.browser_src_port = browser_src_port;
- app_c_.whisper_enable_browser_src = whisper_enable_browser_src_->GetValue();
- app_c_.whisper_enable_builtin = whisper_enable_builtin_->GetValue();
- app_c_.whisper_enable_custom = whisper_enable_custom_->GetValue();
- app_c_.Serialize(AppConfig::kConfigPath);
-
- whisper_->Start(app_c_);
+ app_c_->whisper_mic = which_mic;
+ app_c_->language = kLangChoices[which_lang].ToStdString();
+ app_c_->whisper_model = kWhisperModelChoices[which_model].ToStdString();
+ app_c_->chars_per_sync = chars_per_sync;
+ app_c_->bytes_per_char = bytes_per_char;
+ app_c_->button = kButton[button_idx].ToStdString();
+ app_c_->rows = rows;
+ app_c_->cols = cols;
+ app_c_->enable_local_beep = enable_local_beep;
+ app_c_->use_cpu = use_cpu;
+ app_c_->browser_src_port = browser_src_port;
+ app_c_->whisper_enable_browser_src = whisper_enable_browser_src_->GetValue();
+ app_c_->whisper_enable_builtin = whisper_enable_builtin_->GetValue();
+ app_c_->whisper_enable_custom = whisper_enable_custom_->GetValue();
+ app_c_->Serialize(AppConfig::kConfigPath);
+
+ whisper_->Start(*app_c_);
if (whisper_enable_browser_src_->GetValue()) {
Log(whisper_out_, "Frame launching browser src\n");
- whisper_->StartBrowserSource(app_c_);
+ whisper_->StartBrowserSource(*app_c_);
}
}
diff --git a/GUI/GUI/GUI/Frame.h b/GUI/GUI/GUI/Frame.h index 7da65a3..4aa6a72 100644 --- a/GUI/GUI/GUI/Frame.h +++ b/GUI/GUI/GUI/Frame.h @@ -43,7 +43,6 @@ private: wxTextCtrl* unity_cols_;
wxTextCtrl* whisper_rows_;
wxTextCtrl* whisper_cols_;
- wxTextCtrl* whisper_window_duration_;
wxTextCtrl* whisper_browser_src_port_;
wxDirPickerCtrl* unity_assets_file_picker_;
@@ -84,7 +83,7 @@ private: wxProcess* whisper_app_;
wxTimer whisper_app_drain_;
- AppConfig app_c_;
+ std::unique_ptr<AppConfig> app_c_;
std::unique_ptr<WhisperCPP> whisper_;
diff --git a/GUI/GUI/GUI/GUI.vcxproj b/GUI/GUI/GUI/GUI.vcxproj index f683c4a..6976c31 100644 --- a/GUI/GUI/GUI/GUI.vcxproj +++ b/GUI/GUI/GUI/GUI.vcxproj @@ -167,13 +167,13 @@ <ClInclude Include="App.h" />
<ClInclude Include="BrowserSource.h" />
<ClInclude Include="Config.h" />
+ <ClInclude Include="ConfigMarshal.h" />
<ClInclude Include="Frame.h" />
<ClInclude Include="HTTPMapper.h" />
<ClInclude Include="HTTPParser.h" />
<ClInclude Include="Logging.h" />
<ClInclude Include="PythonWrapper.h" />
<ClInclude Include="resource.h" />
- <ClInclude Include="ryml.h" />
<ClInclude Include="ScopeGuard.h" />
<ClInclude Include="Transcript.h" />
<ClInclude Include="Util.h" />
diff --git a/GUI/GUI/GUI/GUI.vcxproj.filters b/GUI/GUI/GUI/GUI.vcxproj.filters index 49b2a85..6a41329 100644 --- a/GUI/GUI/GUI/GUI.vcxproj.filters +++ b/GUI/GUI/GUI/GUI.vcxproj.filters @@ -74,9 +74,6 @@ <ClInclude Include="Logging.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="ryml.h">
- <Filter>Header Files</Filter>
- </ClInclude>
<ClInclude Include="Config.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -104,6 +101,9 @@ <ClInclude Include="HTTPParser.h">
<Filter>WebServer</Filter>
</ClInclude>
+ <ClInclude Include="ConfigMarshal.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="GUI.rc">
diff --git a/GUI/GUI/GUI/Logging.cpp b/GUI/GUI/GUI/Logging.cpp index f799e31..5741341 100644 --- a/GUI/GUI/GUI/Logging.cpp +++ b/GUI/GUI/GUI/Logging.cpp @@ -35,7 +35,12 @@ void Logging::ThreadLogger::Drain() std::ofstream log_ofs("Resources/log.txt", std::ios_base::app);
for (const auto& [frame, messages] : messages_) {
for (const auto& message : messages) {
- frame->AppendText(message);
+ if (frame) {
+ frame->AppendText(message);
+ }
+ else {
+ wxLogError("%s", message);
+ }
log_ofs << message;
}
}
diff --git a/GUI/GUI/GUI/WhisperCPP.cpp b/GUI/GUI/GUI/WhisperCPP.cpp index 6028e26..a82dc59 100644 --- a/GUI/GUI/GUI/WhisperCPP.cpp +++ b/GUI/GUI/GUI/WhisperCPP.cpp @@ -327,6 +327,7 @@ void WhisperCPP::Start(const AppConfig& c) { const sSegment* const segments = results->getSegments();
const sToken* const tokens = results->getTokens();
const int s0 = length.countSegments - n_new;
+ int n_tok = 0;
for (int i = s0; i < length.countSegments; i++) {
const sSegment& seg = segments[i];
bool is_metadata = false;
@@ -350,11 +351,12 @@ void WhisperCPP::Start(const AppConfig& c) { if (word_iter != banned_words.end()) {
continue;
}
+ ++n_tok;
Log(app->out_, "{}", tok.text);
app->transcript_.Append(tok.text);
}
}
- if (n_new) {
+ if (n_tok) {
Log(app->out_, "\n");
}
diff --git a/GUI/Libraries/fetch.ps1 b/GUI/Libraries/fetch.ps1 index 22b088b..ac9ccd5 100644 --- a/GUI/Libraries/fetch.ps1 +++ b/GUI/Libraries/fetch.ps1 @@ -31,22 +31,6 @@ if (-Not (Test-Path wx)) { popd > $null } -# RAPIDYAML -if ((Test-Path rapidyaml) -And ($overwrite)) { - rm -Recurse rapidyaml -} - -if (-Not (Test-Path rapidyaml)) { - git clone https://github.com/biojppm/rapidyaml - pushd rapidyaml > $null - git checkout v0.5.0 - git submodule update --init --recursive - - python3 tools/amalgamate.py ryml.h - cp ryml.h ../../GUI/GUI/ryml.h - popd -} - if ((Test-Path whisper) -And ($overwrite)) { rm -Recurse whisper } |
