summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--GUI/GUI/GUI/Frame.cpp60
-rw-r--r--GUI/GUI/GUI/Logging.cpp5
-rw-r--r--GUI/GUI/GUI/PythonWrapper.cpp65
-rw-r--r--GUI/GUI/GUI/PythonWrapper.h9
-rw-r--r--README.md5
-rw-r--r--Scripts/string_matcher.py10
-rw-r--r--Scripts/transcribe.py13
-rw-r--r--Shaders/TaSTT_template.shader3
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,
diff --git a/README.md b/README.md
index b450c04..4a48d2e 100644
--- a/README.md
+++ b/README.md
@@ -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;
}