diff options
| -rw-r--r-- | GUI/GUI/GUI/Frame.cpp | 60 | ||||
| -rw-r--r-- | GUI/GUI/GUI/Logging.cpp | 5 | ||||
| -rw-r--r-- | GUI/GUI/GUI/PythonWrapper.cpp | 65 | ||||
| -rw-r--r-- | GUI/GUI/GUI/PythonWrapper.h | 9 | ||||
| -rw-r--r-- | README.md | 5 | ||||
| -rw-r--r-- | Scripts/string_matcher.py | 10 | ||||
| -rw-r--r-- | Scripts/transcribe.py | 13 | ||||
| -rw-r--r-- | Shaders/TaSTT_template.shader | 3 |
8 files changed, 93 insertions, 77 deletions
diff --git a/GUI/GUI/GUI/Frame.cpp b/GUI/GUI/GUI/Frame.cpp index cfb2060..5fb8dd9 100644 --- a/GUI/GUI/GUI/Frame.cpp +++ b/GUI/GUI/GUI/Frame.cpp @@ -730,46 +730,40 @@ void Frame::OnDumpMics(wxCommandEvent& event) Log(transcribe_out_, "{}\n", PythonWrapper::DumpMics());
}
-#define DEBUG
+bool GetUserPath(const std::string& raw, std::filesystem::path& clean, const std::string& err_prefix = "", bool must_exist = true) {
+ clean = raw;
+ if (must_exist && !std::filesystem::exists(clean)) {
+ std::ostringstream oss;
+ oss << err_prefix << ": User-provided path does not exist at " << clean << std::endl;
+ wxLogError(oss.str().c_str());
+ return false;
+ }
+ return true;
+}
void Frame::OnGenerateFX(wxCommandEvent& event)
{
- std::filesystem::path unity_assets_path = unity_assets_file_picker_->GetPath().ToStdString();
-#ifndef DEBUG
- if (!std::filesystem::exists(unity_assets_path)) {
- std::ostringstream oss;
- oss << "Cannot generate FX layer: assets directory does not exist at " << unity_assets_path << std::endl;
- wxLogError(oss.str().c_str());
+ std::filesystem::path unity_assets_path;
+ if (!GetUserPath(unity_assets_file_picker_->GetPath().ToStdString(), unity_assets_path,
+ "Cannot generate FX layer: Failed to validate assets directory")) {
return;
}
-#endif
- std::filesystem::path unity_animator_path = unity_animator_file_picker_->GetPath().ToStdString();
-#ifndef DEBUG
- if (!std::filesystem::exists(unity_animator_path)) {
- std::ostringstream oss;
- oss << "Cannot generate FX layer: animator does not exist at " << unity_animator_path << std::endl;
- wxLogError(oss.str().c_str());
+ std::filesystem::path unity_animator_path;
+ if (!GetUserPath(unity_animator_file_picker_->GetPath().ToStdString(), unity_animator_path,
+ "Cannot generate FX layer: Failed to validate animator directory")) {
return;
}
-#endif
- std::filesystem::path unity_parameters_path = unity_parameters_file_picker_->GetPath().ToStdString();
-#ifndef DEBUG
- if (!std::filesystem::exists(unity_parameters_path)) {
- std::ostringstream oss;
- oss << "Cannot generate FX layer: parameters do not exist at " << unity_parameters_path << std::endl;
- wxLogError(oss.str().c_str());
+ std::filesystem::path unity_parameters_path;
+ if (!GetUserPath(unity_parameters_file_picker_->GetPath().ToStdString(), unity_parameters_path,
+ "Cannot generate FX layer: Failed to validate parameters directory")) {
return;
}
-#endif
- std::filesystem::path unity_menu_path = unity_menu_file_picker_->GetPath().ToStdString();
-#ifndef DEBUG
- if (!std::filesystem::exists(unity_menu_path)) {
- std::ostringstream oss;
- oss << "Cannot generate FX layer: menu does not exist at " << unity_menu_path << std::endl;
- wxLogError(oss.str().c_str());
+ std::filesystem::path unity_menu_path;
+ if (!GetUserPath(unity_menu_file_picker_->GetPath().ToStdString(), unity_menu_path,
+ "Cannot generate FX layer: Failed to validate menu directory")) {
return;
}
-#endif
+
std::string unity_animator_generated_dir = unity_animator_generated_dir_->GetLineText(0).ToStdString();
std::string unity_animator_generated_name = unity_animator_generated_name_->GetLineText(0).ToStdString();
std::string unity_parameters_generated_name = unity_parameters_generated_name_->GetLineText(0).ToStdString();
@@ -804,10 +798,10 @@ void Frame::OnGenerateFX(wxCommandEvent& event) std::string out;
if (!PythonWrapper::GenerateAnimator(
- unity_assets_path.string(),
- unity_animator_path.string(),
- unity_parameters_path.string(),
- unity_menu_path.string(),
+ unity_assets_path,
+ unity_animator_path,
+ unity_parameters_path,
+ unity_menu_path,
unity_animator_generated_dir,
unity_animator_generated_name,
unity_parameters_generated_name,
diff --git a/GUI/GUI/GUI/Logging.cpp b/GUI/GUI/GUI/Logging.cpp index 6727ba1..b9f3be4 100644 --- a/GUI/GUI/GUI/Logging.cpp +++ b/GUI/GUI/GUI/Logging.cpp @@ -6,12 +6,13 @@ std::string Logging::HidePII(const std::string&& str,
const std::string& replacement) {
try {
- std::regex c_users("(C:\\\\Users\\\\)[a-zA-Z0-9_]+");
+ std::regex c_users("(C:\\\\+Users\\\\+)[a-zA-Z0-9_ ]+");
std::string real_replacement = "$1" + replacement;
return std::regex_replace(str, c_users, real_replacement);
}
- catch (const std::regex_error& e) {
+ catch (const std::exception& e) {
wxLogFatalError(e.what());
}
wxLogFatalError("Unhandled regex error (HidePII)");
+ return ""; // Compiler thinks we can get here (we can't) and prints a warning.
}
diff --git a/GUI/GUI/GUI/PythonWrapper.cpp b/GUI/GUI/GUI/PythonWrapper.cpp index 81366e5..a38ee4a 100644 --- a/GUI/GUI/GUI/PythonWrapper.cpp +++ b/GUI/GUI/GUI/PythonWrapper.cpp @@ -163,11 +163,18 @@ 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::string& unity_assets_path, - const std::string& unity_animator_path, - const std::string& unity_parameters_path, - const std::string& unity_menu_path, + 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 std::string& unity_animator_generated_dir, const std::string& unity_animator_generated_name, const std::string& unity_parameters_generated_name, @@ -305,9 +312,9 @@ bool PythonWrapper::GenerateAnimator( { Log(out, "Generating guid.map... "); std::string py_stdout, py_stderr; - if (InvokeWithArgs({ libunity_path, "guid_map", - "--project_root", unity_assets_path, - "--save_to", guid_map_path.string() }, + if (PythonWrapper::InvokeWithArgs({ libunity_path, "guid_map", + "--project_root", Quote(unity_assets_path), + "--save_to", Quote(guid_map_path), }, &py_stdout, &py_stderr)) { Log(out, "success!\n"); Log(out, py_stdout.c_str()); @@ -329,8 +336,8 @@ bool PythonWrapper::GenerateAnimator( Log(out, "Generating animations... "); std::string py_stdout, py_stderr; if (InvokeWithArgs({ libtastt_path, "gen_anims", - "--gen_anim_dir", tastt_animations_path.string(), - "--guid_map", guid_map_path.string(), + "--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), @@ -356,9 +363,9 @@ bool PythonWrapper::GenerateAnimator( Log(out, "Generating FX layer... "); std::string py_stdout, py_stderr; if (InvokeWithArgs({ libtastt_path, "gen_fx", - "--fx_dest", tastt_fx0_path.string(), - "--gen_anim_dir", tastt_animations_path.string(), - "--guid_map", guid_map_path.string(), + "--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), @@ -384,10 +391,10 @@ bool PythonWrapper::GenerateAnimator( Log(out, "Adding enable/disable toggle... "); std::string py_stdout, py_stderr; if (InvokeWithArgs({ libunity_path, "add_toggle", - "--fx0", tastt_fx0_path.string(), - "--fx_dest", tastt_fx1_path.string(), - "--gen_anim_dir", tastt_animations_path.string(), - "--guid_map", guid_map_path.string() }, + "--fx0", Quote(tastt_fx0_path), + "--fx_dest", Quote(tastt_fx1_path), + "--gen_anim_dir", Quote(tastt_animations_path), + "--guid_map", Quote(guid_map_path), }, &py_stdout, &py_stderr)) { Log(out, "success!\n"); Log(out, py_stdout.c_str()); @@ -409,9 +416,9 @@ bool PythonWrapper::GenerateAnimator( Log(out, "Merging with user animator... "); std::string py_stdout, py_stderr; if (InvokeWithArgs({ libunity_path, "merge", - "--fx0", unity_animator_path, - "--fx1", tastt_fx1_path.string(), - "--fx_dest", tastt_fx2_path.string() }, + "--fx0", Quote(unity_animator_path), + "--fx1", Quote(tastt_fx1_path), + "--fx_dest", Quote(tastt_fx2_path), }, &py_stdout, &py_stderr)) { Log(out, "success!\n"); Log(out, py_stdout.c_str()); @@ -433,10 +440,10 @@ bool PythonWrapper::GenerateAnimator( Log(out, "Setting noop animations... "); std::string py_stdout, py_stderr; if (InvokeWithArgs({ libunity_path, "set_noop_anim", - "--fx0", tastt_fx2_path.string(), - "--fx_dest", tastt_animator_path.string(), - "--gen_anim_dir", tastt_animations_path.string(), - "--guid_map", guid_map_path.string() }, + "--fx0", Quote(tastt_fx2_path), + "--fx_dest", Quote(tastt_animator_path), + "--gen_anim_dir", Quote(tastt_animations_path), + "--guid_map", Quote(guid_map_path), }, &py_stdout, &py_stderr)) { Log(out, "success!\n"); Log(out, py_stdout.c_str()); @@ -458,8 +465,8 @@ bool PythonWrapper::GenerateAnimator( Log(out, "Generating avatar parameters... "); std::string py_stdout, py_stderr; if (InvokeWithArgs({ generate_params_path, - "--old_params", unity_parameters_path, - "--new_params", tastt_params_path.string(), + "--old_params", Quote(unity_parameters_path), + "--new_params", Quote(tastt_params_path), "--chars_per_sync", chars_per_sync, "--bytes_per_char", bytes_per_char }, &py_stdout, &py_stderr)) { @@ -482,9 +489,11 @@ bool PythonWrapper::GenerateAnimator( { Log(out, "Generating avatar menu... "); std::string py_stdout, py_stderr; - if (InvokeWithArgs({ generate_menu_path, - "--old_menu", unity_menu_path, - "--new_menu", tastt_menu_path.string()}, + // 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), + "--new_menu", Quote(tastt_menu_path), }; + if (InvokeWithArgs( std::move(args), &py_stdout, &py_stderr)) { Log(out, "success!\n"); Log(out, py_stdout.c_str()); diff --git a/GUI/GUI/GUI/PythonWrapper.h b/GUI/GUI/GUI/PythonWrapper.h index a60bdae..fed8e7b 100644 --- a/GUI/GUI/GUI/PythonWrapper.h +++ b/GUI/GUI/GUI/PythonWrapper.h @@ -8,6 +8,7 @@ #include <wx/process.h> +#include <filesystem> #include <string> #include <vector> @@ -56,10 +57,10 @@ namespace PythonWrapper ); bool GenerateAnimator( - const std::string& unity_assets_path, - const std::string& unity_animator_path, - const std::string& unity_parameters_path, - const std::string& unity_menu_path, + 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 std::string& unity_animator_generated_dir, const std::string& unity_animator_generated_name, const std::string& unity_parameters_generated_name, @@ -172,6 +172,11 @@ Contributions welcome. Send a pull request to this repository. checking transcriptions without having to see the board in game. 6. TTS. Multiple people have requested this. See if there are open source algorithms available; or, figure out how to integrate with + 7. Save UI input fields to config file. Persist across process exit. It's + annoying having to re-enter the config every time I use the STT. + 8. Customizable controller bindings. Someone mentioned they use left click + to unmute. Let's work around users, not make them change their existing + keybinds. 4. Optimization 1. ~~Utilize the avatar 3.0 SDK's ability to drive parameters to reduce the total # of parameters (and therefore OSC messages & sync events). Note diff --git a/Scripts/string_matcher.py b/Scripts/string_matcher.py index 686056c..26241f2 100644 --- a/Scripts/string_matcher.py +++ b/Scripts/string_matcher.py @@ -52,7 +52,8 @@ def matchSpaceDelimitedStrings(old_text: str, new_text: str, window_size = 4) -> def matchStrings(old_text: str, new_text: str, window_size = 3) -> str: if old_text == new_text: - print("STRING MATCH exception path 1") + if DEBUG: + print("STRING MATCH exception path 1") return old_text elif len(old_text) >= window_size and len(new_text) >= window_size: # Find the window where the cumulative string distance @@ -105,9 +106,10 @@ def matchStrings(old_text: str, new_text: str, window_size = 3) -> str: new_text[best_match_j:])) return old_prefix + new_text[best_match_j:] else: - print("STRING MATCH exception path 2") - print(" OLD: {}".format(old_text)) - print(" NEW: {}".format(new_text)) + if DEBUG: + print("STRING MATCH exception path 2") + print(" OLD: {}".format(old_text)) + print(" NEW: {}".format(new_text)) return new_text if __name__ == "__main__": diff --git a/Scripts/transcribe.py b/Scripts/transcribe.py index 4d36e53..7f07efe 100644 --- a/Scripts/transcribe.py +++ b/Scripts/transcribe.py @@ -88,7 +88,7 @@ class AudioState: def sleepInterruptible(self, dur_s, stride_ms = 5): dur_ms = dur_s * 1000.0 timeout = time.time() + dur_s - while self.audio_paused and time.time() < timeout: + while self.audio_paused and self.run_app and time.time() < timeout: time.sleep(stride_ms / 1000.0) def dumpMicDevices(): @@ -263,9 +263,14 @@ def transcribeAudio(audio_state, model, use_cpu: bool): audio_state.transcribe_no_change_count += 1 longer_sleep_dur = audio_state.transcribe_sleep_duration longer_sleep_dur += audio_state.transcribe_sleep_duration_min_s * (1.3**audio_state.transcribe_no_change_count) - audio_state.transcribe_sleep_duration = min( - audio_state.transcribe_sleep_duration_max_s, - longer_sleep_dur) + if audio_state.audio_paused: + audio_state.transcribe_sleep_duration = min( + 1000 * 1000, + longer_sleep_dur) + else: + audio_state.transcribe_sleep_duration = min( + audio_state.transcribe_sleep_duration_max_s, + longer_sleep_dur) text = transcribe(audio_state, model, audio_state.frames, use_cpu) if not text: diff --git a/Shaders/TaSTT_template.shader b/Shaders/TaSTT_template.shader index b40df36..26519b5 100644 --- a/Shaders/TaSTT_template.shader +++ b/Shaders/TaSTT_template.shader @@ -405,7 +405,6 @@ letter_uv = GetLetter(uv_with_margin, letter, texture_cols, texture_rows, 8, 4);
}
- fixed4 background = TaSTT_Backplate.Sample(sampler_linear_repeat, uv);
fixed4 text;
int which_texture = (int) floor(letter / (64 * 128));
@@ -438,7 +437,7 @@ }
fixed4 black = fixed4(0,0,0,1);
if (text.r == black.r && text.g == black.g && text.b == black.b && text.a == black.a) {
- return background;
+ return TaSTT_Backplate.Sample(sampler_linear_repeat, uv);
} else {
return text;
}
|
