diff options
| -rw-r--r-- | GUI/GUI/GUI/Config.cpp | 161 | ||||
| -rw-r--r-- | GUI/GUI/GUI/Config.h | 53 | ||||
| -rw-r--r-- | GUI/GUI/GUI/Frame.cpp | 115 | ||||
| -rw-r--r-- | GUI/GUI/GUI/GUI.vcxproj | 1 | ||||
| -rw-r--r-- | GUI/GUI/GUI/GUI.vcxproj.filters | 3 | ||||
| -rw-r--r-- | GUI/GUI/GUI/Logging.h | 20 | ||||
| -rw-r--r-- | GUI/GUI/GUI/PythonWrapper.cpp | 55 | ||||
| -rw-r--r-- | GUI/GUI/GUI/PythonWrapper.h | 9 | ||||
| -rw-r--r-- | GUI/GUI/GUI/Util.h | 20 |
9 files changed, 302 insertions, 135 deletions
diff --git a/GUI/GUI/GUI/Config.cpp b/GUI/GUI/GUI/Config.cpp index 0436f3b..9ce498a 100644 --- a/GUI/GUI/GUI/Config.cpp +++ b/GUI/GUI/GUI/Config.cpp @@ -4,42 +4,17 @@ #include <wx/wx.h>
#endif
-#include "Config.h"
-
#define RYML_SINGLE_HDR_DEFINE_NOW
#include "ryml.h"
+#include "Config.h"
+
#include <fstream>
#include <memory>
#include <string>
-TranscriptionAppConfig::TranscriptionAppConfig()
- : microphone("index"),
- language("english"),
- model("base.en"),
- chars_per_sync("20"),
- bytes_per_char("1"),
- rows("4"),
- cols("48"),
- window_duration("15"),
- enable_local_beep(true),
- use_cpu(false)
-{}
-
-bool TranscriptionAppConfig::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["chars_per_sync"] << ryml::to_substr(chars_per_sync);
- root["bytes_per_char"] << ryml::to_substr(bytes_per_char);
- root["rows"] << ryml::to_substr(rows);
- root["cols"] << ryml::to_substr(cols);
- root["window_duration"] << ryml::to_substr(window_duration);
- root["enable_local_beep"] << enable_local_beep;
- root["use_cpu"] << use_cpu;
+bool Config::Serialize(const std::filesystem::path& path,
+ const ryml::Tree* const t) {
// 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.
@@ -75,7 +50,8 @@ bool TranscriptionAppConfig::Serialize(const std::filesystem::path& path) { return true;
}
-bool TranscriptionAppConfig::Deserialize(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;
@@ -87,19 +63,124 @@ bool TranscriptionAppConfig::Deserialize(const std::filesystem::path& path) { return false;
}
- ryml::Tree t = ryml::parse_in_place(ryml::to_substr(yaml_buf.data()));
+ *t = ryml::parse_in_place(ryml::to_substr(yaml_buf.data()));
+ return true;
+}
+
+TranscriptionAppConfig::TranscriptionAppConfig()
+ : microphone("index"),
+ language("english"),
+ model("base.en"),
+ chars_per_sync("20"),
+ bytes_per_char("1"),
+ rows("4"),
+ cols("48"),
+ window_duration("15"),
+ enable_local_beep(true),
+ use_cpu(false)
+{}
+
+bool TranscriptionAppConfig::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["chars_per_sync"] << ryml::to_substr(chars_per_sync);
+ root["bytes_per_char"] << ryml::to_substr(bytes_per_char);
+ root["rows"] << ryml::to_substr(rows);
+ root["cols"] << ryml::to_substr(cols);
+ root["window_duration"] << ryml::to_substr(window_duration);
+ root["enable_local_beep"] << enable_local_beep;
+ root["use_cpu"] << use_cpu;
+
+ return Config::Serialize(path, &t);
+}
+
+bool TranscriptionAppConfig::Deserialize(const std::filesystem::path& path) {
+ std::error_code err;
+ if (!std::filesystem::exists(path, err)) {
+ *this = TranscriptionAppConfig();
+ return true;
+ }
+
+ ryml::Tree t{};
+ if (!Config::Deserialize(path, &t)) {
+ wxLogError("Deserialization failed at %s", path.string());
+ return false;
+ }
+
ryml::ConstNodeRef root = t.rootref();
TranscriptionAppConfig c;
- root["microphone"] >> c.microphone;
- root["language"] >> c.language;
- root["model"] >> c.model;
- root["chars_per_sync"] >> c.chars_per_sync;
- root["bytes_per_char"] >> c.bytes_per_char;
- root["rows"] >> c.rows;
- root["cols"] >> c.cols;
- root["window_duration"] >> c.window_duration;
- root["enable_local_beep"] >> c.enable_local_beep;
+ root.get_if("microphone", &c.microphone);
+ root.get_if("language", &c.language);
+ root.get_if("model", &c.model);
+ 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("window_duration", &c.window_duration);
+ root.get_if("enable_local_beep", &c.enable_local_beep);
+ root.get_if("use_cpu", &c.use_cpu);
*this = std::move(c);
return true;
}
+
+UnityAppConfig::UnityAppConfig()
+ : assets_path(),
+ fx_path(),
+ params_path(),
+ menu_path(),
+ chars_per_sync(20),
+ bytes_per_char(1),
+ rows(4),
+ cols(48)
+{}
+
+bool UnityAppConfig::Serialize(const std::filesystem::path& path) {
+ ryml::Tree t;
+ ryml::NodeRef root = t.rootref();
+ root |= ryml::MAP;
+ 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["chars_per_sync"] << chars_per_sync;
+ root["bytes_per_char"] << bytes_per_char;
+ root["rows"] << rows;
+ root["cols"] << cols;
+
+ return Config::Serialize(path, &t);
+}
+
+bool UnityAppConfig::Deserialize(const std::filesystem::path& path) {
+ std::error_code err;
+ if (!std::filesystem::exists(path, err)) {
+ *this = UnityAppConfig();
+ return true;
+ }
+
+ ryml::Tree t;
+ if (!Config::Deserialize(path, &t)) {
+ return false;
+ }
+
+ ryml::ConstNodeRef root = t.rootref();
+ UnityAppConfig c;
+
+ 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);
+
+ *this = std::move(c);
+ return true;
+}
+
diff --git a/GUI/GUI/GUI/Config.h b/GUI/GUI/GUI/Config.h index e142773..985380b 100644 --- a/GUI/GUI/GUI/Config.h +++ b/GUI/GUI/GUI/Config.h @@ -1,14 +1,37 @@ #pragma once
+#include "ryml.h"
+
#include <filesystem>
-class TranscriptionAppConfig {
+// Represents a disk-backed configuration. Knows how to save to disk
+// (Serialize) and restore from disk (Deserialize).
+class Config {
public:
+ virtual ~Config() {}
+
+ virtual bool Serialize(const std::filesystem::path& path) = 0;
+
+ virtual bool Deserialize(const std::filesystem::path& path) = 0;
+
+protected:
+ virtual bool Serialize(const std::filesystem::path& path,
+ const ryml::Tree* t);
+
+ virtual bool Deserialize(const std::filesystem::path& path,
+ ryml::Tree* t);
+};
+
+// Represents the configurable fields for the transcription app.
+class TranscriptionAppConfig : public Config {
+public:
+ virtual ~TranscriptionAppConfig() {}
+
TranscriptionAppConfig();
- bool Serialize(const std::filesystem::path& path);
+ bool Serialize(const std::filesystem::path& path) override;
- bool Deserialize(const std::filesystem::path& path);
+ bool Deserialize(const std::filesystem::path& path) override;
// The default path at which configs are serialized.
static constexpr char kConfigPath[] = "Resources/transcription_app_config.yml";
@@ -24,3 +47,27 @@ public: bool enable_local_beep;
bool use_cpu;
};
+
+// Represents the configurable fields for the Unity app.
+class UnityAppConfig : public Config {
+public:
+ virtual ~UnityAppConfig() {}
+
+ UnityAppConfig();
+
+ bool Serialize(const std::filesystem::path& path) override;
+
+ bool Deserialize(const std::filesystem::path& path) override;
+
+ // The default path at which configs are serialized.
+ static constexpr char kConfigPath[] = "Resources/unity_app_config.yml";
+
+ std::string assets_path;
+ std::string fx_path;
+ std::string params_path;
+ std::string menu_path;
+ int chars_per_sync;
+ int bytes_per_char;
+ int rows;
+ int cols;
+};
diff --git a/GUI/GUI/GUI/Frame.cpp b/GUI/GUI/GUI/Frame.cpp index 6c1f356..f26cbec 100644 --- a/GUI/GUI/GUI/Frame.cpp +++ b/GUI/GUI/GUI/Frame.cpp @@ -251,8 +251,11 @@ Frame::Frame() py_app_(nullptr),
py_app_drain_(this, ID_PY_APP_DRAIN)
{
- TranscriptionAppConfig c;
- c.Deserialize(TranscriptionAppConfig::kConfigPath);
+ TranscriptionAppConfig py_c;
+ py_c.Deserialize(TranscriptionAppConfig::kConfigPath);
+
+ UnityAppConfig unity_c;
+ unity_c.Deserialize(UnityAppConfig::kConfigPath);
auto* main_panel = new wxPanel(this, ID_MAIN_PANEL);
main_panel_ = main_panel;
@@ -301,7 +304,7 @@ Frame::Frame() {
auto* py_app_mic = new wxChoice(py_app_config_panel_pairs, ID_PY_APP_MIC, wxDefaultPosition,
wxDefaultSize, kNumMicChoices, kMicChoices);
- int mic_idx = GetDropdownChoiceIndex(kMicChoices, kNumMicChoices, c.microphone, kMicDefault);
+ int mic_idx = GetDropdownChoiceIndex(kMicChoices, kNumMicChoices, py_c.microphone, kMicDefault);
py_app_mic->SetSelection(mic_idx);
py_app_mic->SetToolTip(
"Select which microphone to listen to when "
@@ -311,7 +314,7 @@ Frame::Frame() auto* py_app_lang = new wxChoice(py_app_config_panel_pairs, ID_PY_APP_LANG, wxDefaultPosition,
wxDefaultSize, kNumLangChoices, kLangChoices);
- int lang_idx = GetDropdownChoiceIndex(kLangChoices, kNumLangChoices, c.language, kLangDefault);
+ int lang_idx = GetDropdownChoiceIndex(kLangChoices, kNumLangChoices, py_c.language, kLangDefault);
py_app_lang->SetSelection(lang_idx);
py_app_lang->SetToolTip("Select which language you will "
"speak in. It will be transcribed into that language. "
@@ -323,7 +326,7 @@ Frame::Frame() auto* py_app_model = new wxChoice(py_app_config_panel_pairs, ID_PY_APP_MODEL, wxDefaultPosition,
wxDefaultSize, kNumModelChoices, kModelChoices);
- int model_idx = GetDropdownChoiceIndex(kModelChoices, kNumModelChoices, c.model, kModelDefault);
+ int model_idx = GetDropdownChoiceIndex(kModelChoices, kNumModelChoices, py_c.model, kModelDefault);
py_app_model->SetSelection(model_idx);
py_app_model->SetToolTip("Select which version of "
"the transcription model to use. 'base' is a good "
@@ -336,7 +339,7 @@ Frame::Frame() auto* py_app_chars_per_sync = new wxChoice(py_app_config_panel_pairs,
ID_PY_APP_CHARS_PER_SYNC, wxDefaultPosition,
wxDefaultSize, kNumCharsPerSync, kCharsPerSync);
- int chars_idx = GetDropdownChoiceIndex(kCharsPerSync, kNumCharsPerSync, c.chars_per_sync, kCharsDefault);
+ int chars_idx = GetDropdownChoiceIndex(kCharsPerSync, kNumCharsPerSync, py_c.chars_per_sync, kCharsDefault);
py_app_chars_per_sync->SetSelection(chars_idx);
py_app_chars_per_sync->SetToolTip(
"VRChat syncs avatar parameters roughly 5 times per "
@@ -348,7 +351,7 @@ Frame::Frame() auto* py_app_bytes_per_char = new wxChoice(py_app_config_panel_pairs,
ID_PY_APP_BYTES_PER_CHAR, wxDefaultPosition,
wxDefaultSize, kNumBytesPerChar, kBytesPerChar);
- int bytes_idx = GetDropdownChoiceIndex(kBytesPerChar, kNumBytesPerChar, c.bytes_per_char, kBytesDefault);
+ int bytes_idx = GetDropdownChoiceIndex(kBytesPerChar, kNumBytesPerChar, py_c.bytes_per_char, kBytesDefault);
py_app_bytes_per_char->SetSelection(bytes_idx);
py_app_bytes_per_char->SetToolTip(
"If you speak a language that uses non-ASCII "
@@ -356,21 +359,21 @@ Frame::Frame() py_app_bytes_per_char_ = py_app_bytes_per_char;
auto* py_app_rows = new wxTextCtrl(py_app_config_panel_pairs,
- ID_PY_APP_ROWS, c.rows,
+ ID_PY_APP_ROWS, py_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, c.cols,
+ ID_PY_APP_COLS, py_c.cols,
wxDefaultPosition, wxDefaultSize, /*style=*/0);
py_app_cols->SetToolTip(
"The number of columns on the text box.");
py_app_cols_ = py_app_cols;
auto* py_app_window_duration = new wxTextCtrl(py_app_config_panel_pairs,
- ID_PY_APP_WINDOW_DURATION, c.window_duration,
+ ID_PY_APP_WINDOW_DURATION, py_c.window_duration,
wxDefaultPosition, wxDefaultSize, /*style=*/0);
py_app_window_duration->SetToolTip(
"This controls how long the slice of audio that "
@@ -411,7 +414,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(c.enable_local_beep);
+ py_app_enable_local_beep->SetValue(py_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. "
@@ -421,7 +424,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(c.use_cpu);
+ py_app_use_cpu->SetValue(py_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 "
@@ -468,19 +471,19 @@ Frame::Frame() auto* unity_assets_file_picker = new wxDirPickerCtrl(
unity_config_panel_pairs,
ID_UNITY_ASSETS_FILE_PICKER,
- /*path=*/wxEmptyString,
+ /*path=*/unity_c.assets_path,
/*message=*/"Unity Assets folder"
);
unity_assets_file_picker->SetToolTip(
"The path to the Assets folder for your avatar's "
"Unity project. Example:\n"
- "C:\\Users\\yum\\unity\\kumadan\\Assets");
+ "py_c:\\Users\\yum\\unity\\kumadan\\Assets");
unity_assets_file_picker_ = unity_assets_file_picker;
auto* unity_animator_file_picker = new wxFilePickerCtrl(
unity_config_panel_pairs,
ID_UNITY_ANIMATOR_FILE_PICKER,
- /*path=*/wxEmptyString,
+ /*path=*/unity_c.fx_path,
/*message=*/"FX controller path",
/*wildcard=*/wxFileSelectorDefaultWildcardStr,
/*pos=*/wxDefaultPosition,
@@ -489,13 +492,13 @@ Frame::Frame() unity_animator_file_picker->SetToolTip(
"The path to your avatar's FX layer. You can find "
"this in your avatar descriptor. Example:\n"
- "C:\\Users\\yum\\unity\\kumadan\\Assets\\kumadan_fx.controller");
+ "py_c:\\Users\\yum\\unity\\kumadan\\Assets\\kumadan_fx.controller");
unity_animator_file_picker_ = unity_animator_file_picker;
auto* unity_parameters_file_picker = new wxFilePickerCtrl(
unity_config_panel_pairs,
ID_UNITY_PARAMETERS_FILE_PICKER,
- /*path=*/wxEmptyString,
+ /*path=*/unity_c.params_path,
/*message=*/"Avatar parameters path",
/*wildcard=*/wxFileSelectorDefaultWildcardStr,
/*pos=*/wxDefaultPosition,
@@ -504,13 +507,13 @@ Frame::Frame() unity_parameters_file_picker->SetToolTip(
"The path to your avatar's parameters. You can find "
"this in your avatar descriptor. Example:\n"
- "C:\\Users\\yum\\unity\\kumadan\\Assets\\kumadan_parameters.asset");
+ "py_c:\\Users\\yum\\unity\\kumadan\\Assets\\kumadan_parameters.asset");
unity_parameters_file_picker_ = unity_parameters_file_picker;
auto* unity_menu_file_picker = new wxFilePickerCtrl(
unity_config_panel_pairs,
ID_UNITY_MENU_FILE_PICKER,
- /*path=*/wxEmptyString,
+ /*path=*/unity_c.menu_path,
/*message=*/"Avatar menu path",
/*wildcard=*/wxFileSelectorDefaultWildcardStr,
/*pos=*/wxDefaultPosition,
@@ -519,7 +522,7 @@ Frame::Frame() unity_menu_file_picker->SetToolTip(
"The path to your avatar's menu. You can find "
"this in your avatar descriptor. Example:\n"
- "C:\\Users\\yum\\unity\\kumadan\\Assets\\kumadan_menu.asset");
+ "py_c:\\Users\\yum\\unity\\kumadan\\Assets\\kumadan_menu.asset");
unity_menu_file_picker_ = unity_menu_file_picker;
auto* unity_animator_generated_dir = new wxTextCtrl(unity_config_panel_pairs,
@@ -574,7 +577,9 @@ Frame::Frame() auto* unity_chars_per_sync = new wxChoice(unity_config_panel_pairs,
ID_UNITY_CHARS_PER_SYNC, wxDefaultPosition,
wxDefaultSize, kNumCharsPerSync, kCharsPerSync);
- unity_chars_per_sync->SetSelection(kCharsDefault);
+ int chars_idx = GetDropdownChoiceIndex(kCharsPerSync, kNumCharsPerSync,
+ std::to_string(unity_c.chars_per_sync), kCharsDefault);
+ unity_chars_per_sync->SetSelection(chars_idx);
unity_chars_per_sync->SetToolTip(
"VRChat syncs avatar parameters roughly 5 times per "
"second. We use this to send text to the box. By "
@@ -585,21 +590,23 @@ Frame::Frame() auto* unity_bytes_per_char = new wxChoice(unity_config_panel_pairs,
ID_UNITY_BYTES_PER_CHAR, wxDefaultPosition,
wxDefaultSize, kNumBytesPerChar, kBytesPerChar);
- unity_bytes_per_char->SetSelection(kBytesDefault);
+ int bytes_idx = GetDropdownChoiceIndex(kBytesPerChar,
+ kNumBytesPerChar, std::to_string(unity_c.bytes_per_char), kBytesDefault);
+ unity_bytes_per_char->SetSelection(bytes_idx);
unity_bytes_per_char->SetToolTip(
"If you speak a language that uses non-ASCII "
"characters (i.e. not English), set this to 2.");
unity_bytes_per_char_ = unity_bytes_per_char;
auto* unity_rows = new wxTextCtrl(unity_config_panel_pairs,
- ID_UNITY_ROWS, /*value=*/"4",
+ ID_UNITY_ROWS, std::to_string(unity_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, /*value=*/"48",
+ ID_UNITY_COLS, std::to_string(unity_c.cols),
wxDefaultPosition, wxDefaultSize, /*style=*/0);
unity_cols->SetToolTip(
"The number of columns on the text box.");
@@ -797,22 +804,26 @@ void Frame::OnGenerateFX(wxCommandEvent& event) if (chars_per_sync_idx == wxNOT_FOUND) {
chars_per_sync_idx = kCharsDefault;
}
- std::string chars_per_sync = kCharsPerSync[chars_per_sync_idx].ToStdString();
+ std::string chars_per_sync_str = kCharsPerSync[chars_per_sync_idx].ToStdString();
int bytes_per_char_idx = unity_bytes_per_char_->GetSelection();
if (bytes_per_char_idx == wxNOT_FOUND) {
bytes_per_char_idx = kBytesDefault;
}
- std::string bytes_per_char = kBytesPerChar[bytes_per_char_idx].ToStdString();
+ std::string bytes_per_char_str = kBytesPerChar[bytes_per_char_idx].ToStdString();
std::string rows_str = unity_rows_->GetValue().ToStdString();
std::string cols_str = unity_cols_->GetValue().ToStdString();
- int rows, cols;
+ int rows, cols, bytes_per_char, chars_per_sync;
try {
rows = std::stoi(rows_str);
cols = std::stoi(cols_str);
+ bytes_per_char = std::stoi(bytes_per_char_str);
+ chars_per_sync = std::stoi(chars_per_sync_str);
}
catch (const std::invalid_argument&) {
- Log(unity_out_, "Could not parse rows \"{}\" or cols \"{}\" as an integer\n", rows_str, cols_str);
+ Log(unity_out_, "Could not parse rows \"{}\", cols \"{}\", bytes per "
+ "char \"{}\", or chars per sync \"{}\" as an integer\n",
+ rows_str, cols_str, bytes_per_char_str, chars_per_sync_str);
return;
}
catch (const std::out_of_range&) {
@@ -820,20 +831,24 @@ void Frame::OnGenerateFX(wxCommandEvent& event) return;
}
+ UnityAppConfig unity_c;
+ unity_c.assets_path = unity_assets_path.string();
+ unity_c.fx_path = unity_animator_path.string();
+ unity_c.params_path = unity_parameters_path.string();
+ unity_c.menu_path = unity_menu_path.string();
+ unity_c.bytes_per_char = chars_per_sync;
+ unity_c.chars_per_sync = chars_per_sync;
+ unity_c.rows = rows;
+ unity_c.cols = cols;
+ unity_c.Serialize(UnityAppConfig::kConfigPath);
+
std::string out;
if (!PythonWrapper::GenerateAnimator(
- unity_assets_path,
- unity_animator_path,
- unity_parameters_path,
- unity_menu_path,
+ unity_c,
unity_animator_generated_dir,
unity_animator_generated_name,
unity_parameters_generated_name,
unity_menu_generated_name,
- chars_per_sync,
- bytes_per_char,
- rows,
- cols,
unity_out_)) {
wxLogError("Failed to generate animator:\n%s\n", out.c_str());
}
@@ -952,20 +967,20 @@ void Frame::OnAppStart(wxCommandEvent& event) { return;
}
- TranscriptionAppConfig c;
- c.microphone = kMicChoices[which_mic].ToStdString();
- c.language = kLangChoices[which_lang].ToStdString();
- c.model = kModelChoices[which_model].ToStdString();
- c.chars_per_sync = kCharsPerSync[chars_per_sync_idx].ToStdString();
- c.bytes_per_char = kBytesPerChar[bytes_per_char_idx].ToStdString();
- c.rows = std::to_string(rows);
- c.cols = std::to_string(cols);
- c.window_duration = std::to_string(window_duration);
- c.enable_local_beep = enable_local_beep;
- c.use_cpu = use_cpu;
- c.Serialize(TranscriptionAppConfig::kConfigPath);
-
- wxProcess* p = PythonWrapper::StartApp(std::move(cb), c);
+ TranscriptionAppConfig py_c;
+ py_c.microphone = kMicChoices[which_mic].ToStdString();
+ py_c.language = kLangChoices[which_lang].ToStdString();
+ py_c.model = kModelChoices[which_model].ToStdString();
+ py_c.chars_per_sync = kCharsPerSync[chars_per_sync_idx].ToStdString();
+ py_c.bytes_per_char = kBytesPerChar[bytes_per_char_idx].ToStdString();
+ py_c.rows = std::to_string(rows);
+ py_c.cols = std::to_string(cols);
+ py_c.window_duration = std::to_string(window_duration);
+ py_c.enable_local_beep = enable_local_beep;
+ py_c.use_cpu = use_cpu;
+ py_c.Serialize(TranscriptionAppConfig::kConfigPath);
+
+ wxProcess* p = PythonWrapper::StartApp(std::move(cb), py_c);
if (!p) {
Log(transcribe_out_, "Failed to launch transcription engine\n");
return;
diff --git a/GUI/GUI/GUI/GUI.vcxproj b/GUI/GUI/GUI/GUI.vcxproj index cbe3a92..23f3d88 100644 --- a/GUI/GUI/GUI/GUI.vcxproj +++ b/GUI/GUI/GUI/GUI.vcxproj @@ -155,6 +155,7 @@ <ClInclude Include="resource.h" />
<ClInclude Include="ryml.h" />
<ClInclude Include="ScopeGuard.h" />
+ <ClInclude Include="Util.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="GUI.rc" />
diff --git a/GUI/GUI/GUI/GUI.vcxproj.filters b/GUI/GUI/GUI/GUI.vcxproj.filters index 3fa31c7..2798d1e 100644 --- a/GUI/GUI/GUI/GUI.vcxproj.filters +++ b/GUI/GUI/GUI/GUI.vcxproj.filters @@ -59,6 +59,9 @@ <ClInclude Include="Config.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="Util.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="GUI.rc">
diff --git a/GUI/GUI/GUI/Logging.h b/GUI/GUI/GUI/Logging.h index 6c1bf16..9fb88fd 100644 --- a/GUI/GUI/GUI/Logging.h +++ b/GUI/GUI/GUI/Logging.h @@ -13,6 +13,26 @@ #include <string_view>
namespace Logging {
+
+#if 0
+ class Log {
+ public:
+ static Log& Get() {
+ static Log l;
+ return l;
+ }
+
+ bool Write(const std::string& text);
+
+ private:
+ Log() {}
+
+ bool Open(const std::string& path);
+
+ int fd_;
+ };
+#endif
+
// Remove personally identifying information (PII) from str.
//
// For example, this translates "C:/Users/foo/Desktop" to "C:/Users/*****/Desktop".
diff --git a/GUI/GUI/GUI/PythonWrapper.cpp b/GUI/GUI/GUI/PythonWrapper.cpp index 0c43fa4..5581739 100644 --- a/GUI/GUI/GUI/PythonWrapper.cpp +++ b/GUI/GUI/GUI/PythonWrapper.cpp @@ -1,5 +1,6 @@ #include "Logging.h" #include "PythonWrapper.h" +#include "Util.h" #include "Config.h" @@ -162,26 +163,12 @@ wxProcess* PythonWrapper::StartApp( std::move(exit_callback)); } -// Wrap the filesystem path in quotes, escaping intermediate quotes with \\. -std::string Quote(const std::filesystem::path& p) { - std::ostringstream oss; - oss << std::quoted(p.string()); - return oss.str(); -} - bool PythonWrapper::GenerateAnimator( - const std::filesystem::path& unity_assets_path, - const std::filesystem::path& unity_animator_path, - const std::filesystem::path& unity_parameters_path, - const std::filesystem::path& unity_menu_path, + const UnityAppConfig& config, const std::string& unity_animator_generated_dir, const std::string& unity_animator_generated_name, const std::string& unity_parameters_generated_name, const std::string& unity_menu_generated_name, - const std::string& chars_per_sync, - const std::string& bytes_per_char, - const int rows, - const int cols, wxTextCtrl* out) { // Python script locations std::string libunity_path = "Resources/Scripts/libunity.py"; @@ -194,7 +181,7 @@ bool PythonWrapper::GenerateAnimator( // Generated directory locations std::filesystem::path tastt_generated_dir_path = - std::filesystem::path(unity_assets_path) / unity_animator_generated_dir; + std::filesystem::path(config.assets_path) / unity_animator_generated_dir; std::filesystem::path guid_map_path = tastt_generated_dir_path / "guid.map"; std::filesystem::path tastt_animations_path = @@ -222,13 +209,13 @@ bool PythonWrapper::GenerateAnimator( tastt_generated_dir_path / unity_animator_generated_name; { - Log(out, "Generating shader for {}x{} board...", rows, cols); + Log(out, "Generating shader for {}x{} board...", config.rows, config.cols); std::string py_stdout, py_stderr; if (InvokeWithArgs({ generate_shader_path, - "--bytes_per_char", bytes_per_char, - "--rows", std::to_string(rows), - "--cols", std::to_string(cols), + "--bytes_per_char", std::to_string(config.bytes_per_char), + "--rows", std::to_string(config.rows), + "--cols", std::to_string(config.cols), "--shader_template", shader_template_path, "--shader_path", shader_path }, &py_stdout, &py_stderr)) { @@ -312,7 +299,7 @@ bool PythonWrapper::GenerateAnimator( Log(out, "Generating guid.map... "); std::string py_stdout, py_stderr; if (PythonWrapper::InvokeWithArgs({ libunity_path, "guid_map", - "--project_root", Quote(unity_assets_path), + "--project_root", Quote(config.assets_path), "--save_to", Quote(guid_map_path), }, &py_stdout, &py_stderr)) { Log(out, "success!\n"); @@ -337,10 +324,10 @@ bool PythonWrapper::GenerateAnimator( if (InvokeWithArgs({ libtastt_path, "gen_anims", "--gen_anim_dir", Quote(tastt_animations_path), "--guid_map", Quote(guid_map_path), - "--chars_per_sync", chars_per_sync, - "--bytes_per_char", bytes_per_char, - "--rows", std::to_string(rows), - "--cols", std::to_string(cols)}, + "--chars_per_sync", std::to_string(config.chars_per_sync), + "--bytes_per_char", std::to_string(config.bytes_per_char), + "--rows", std::to_string(config.rows), + "--cols", std::to_string(config.cols)}, &py_stdout, &py_stderr)) { Log(out, "success!\n"); Log(out, py_stdout.c_str()); @@ -365,10 +352,10 @@ bool PythonWrapper::GenerateAnimator( "--fx_dest", Quote(tastt_fx0_path), "--gen_anim_dir", Quote(tastt_animations_path), "--guid_map", Quote(guid_map_path), - "--chars_per_sync", chars_per_sync, - "--bytes_per_char", bytes_per_char, - "--rows", std::to_string(rows), - "--cols", std::to_string(cols)}, + "--chars_per_sync", std::to_string(config.chars_per_sync), + "--bytes_per_char", std::to_string(config.bytes_per_char), + "--rows", std::to_string(config.rows), + "--cols", std::to_string(config.cols)}, &py_stdout, &py_stderr)) { Log(out, "success!\n"); Log(out, py_stdout.c_str()); @@ -415,7 +402,7 @@ bool PythonWrapper::GenerateAnimator( Log(out, "Merging with user animator... "); std::string py_stdout, py_stderr; if (InvokeWithArgs({ libunity_path, "merge", - "--fx0", Quote(unity_animator_path), + "--fx0", Quote(config.fx_path), "--fx1", Quote(tastt_fx1_path), "--fx_dest", Quote(tastt_fx2_path), }, &py_stdout, &py_stderr)) { @@ -464,10 +451,10 @@ bool PythonWrapper::GenerateAnimator( Log(out, "Generating avatar parameters... "); std::string py_stdout, py_stderr; if (InvokeWithArgs({ generate_params_path, - "--old_params", Quote(unity_parameters_path), + "--old_params", Quote(config.params_path), "--new_params", Quote(tastt_params_path), - "--chars_per_sync", chars_per_sync, - "--bytes_per_char", bytes_per_char }, + "--chars_per_sync", std::to_string(config.chars_per_sync), + "--bytes_per_char", std::to_string(config.bytes_per_char) }, &py_stdout, &py_stderr)) { Log(out, "success!\n"); Log(out, py_stdout.c_str()); @@ -490,7 +477,7 @@ bool PythonWrapper::GenerateAnimator( std::string py_stdout, py_stderr; // No idea why, but inlining this into `InvokeWithArgs` confuses the compiler. std::vector<std::string> args = { generate_menu_path, - "--old_menu", Quote(unity_menu_path), + "--old_menu", Quote(config.menu_path), "--new_menu", Quote(tastt_menu_path), }; if (InvokeWithArgs( std::move(args), &py_stdout, &py_stderr)) { diff --git a/GUI/GUI/GUI/PythonWrapper.h b/GUI/GUI/GUI/PythonWrapper.h index 38b35d4..c28a1f1 100644 --- a/GUI/GUI/GUI/PythonWrapper.h +++ b/GUI/GUI/GUI/PythonWrapper.h @@ -55,18 +55,11 @@ namespace PythonWrapper const TranscriptionAppConfig& config); bool GenerateAnimator( - const std::filesystem::path& unity_assets_path, - const std::filesystem::path& unity_animator_path, - const std::filesystem::path& unity_parameters_path, - const std::filesystem::path& unity_menu_path, + const UnityAppConfig& config, const std::string& unity_animator_generated_dir, const std::string& unity_animator_generated_name, const std::string& unity_parameters_generated_name, const std::string& unity_menu_generated_name, - const std::string& chars_per_sync, - const std::string& bytes_per_char, - int rows, - int cols, wxTextCtrl* out); }; diff --git a/GUI/GUI/GUI/Util.h b/GUI/GUI/GUI/Util.h new file mode 100644 index 0000000..594972e --- /dev/null +++ b/GUI/GUI/GUI/Util.h @@ -0,0 +1,20 @@ +#pragma once
+
+#include <filesystem>
+#include <string>
+
+// Wrap the filesystem path in quotes, escaping intermediate quotes with \\.
+inline std::string Quote(const std::filesystem::path& p) {
+ std::ostringstream oss;
+ oss << std::quoted(p.string());
+ return oss.str();
+}
+
+inline std::string Unquote(const std::string& s) {
+ std::istringstream iss(s);
+
+ std::string result;
+ iss >> quoted(result);
+
+ return result;
+}
|
