diff options
| author | yum <yum.food.vr@gmail.com> | 2023-06-28 21:24:56 -0700 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2023-06-28 21:24:56 -0700 |
| commit | bdaeb1911297d7901a12e3ac51b38c3463789279 (patch) | |
| tree | b6151c80100db635ca0c4479d8b1afde838b579e | |
| parent | ff7eb3c212195af71cd0ce4a3cd0c9a081d6ebda (diff) | |
Add profanity filter
Add toggle to UI to enable a profanity filter. It replaces vowels in bad
words with asterisks.
Bugfix: filters now apply to OBS
| -rw-r--r-- | GUI/GUI/GUI/Config.cpp | 3 | ||||
| -rw-r--r-- | GUI/GUI/GUI/Config.h | 1 | ||||
| -rw-r--r-- | GUI/GUI/GUI/Frame.cpp | 18 | ||||
| -rw-r--r-- | GUI/GUI/GUI/Frame.h | 1 | ||||
| -rw-r--r-- | GUI/GUI/GUI/PythonWrapper.cpp | 1 | ||||
| -rw-r--r-- | GUI/package.ps1 | 17 | ||||
| -rw-r--r-- | Scripts/transcribe.py | 40 |
7 files changed, 76 insertions, 5 deletions
diff --git a/GUI/GUI/GUI/Config.cpp b/GUI/GUI/GUI/Config.cpp index d337f77..b73f383 100644 --- a/GUI/GUI/GUI/Config.cpp +++ b/GUI/GUI/GUI/Config.cpp @@ -79,6 +79,7 @@ AppConfig::AppConfig(wxTextCtrl* out) remove_trailing_period(false),
enable_uppercase_filter(false),
enable_lowercase_filter(false),
+ enable_profanity_filter(false),
enable_debug_mode(false),
reset_on_toggle(true),
gpu_idx(0),
@@ -132,6 +133,7 @@ bool AppConfig::Serialize(const std::filesystem::path& path) { cm.Set("remove_trailing_period", remove_trailing_period);
cm.Set("enable_uppercase_filter", enable_uppercase_filter);
cm.Set("enable_lowercase_filter", enable_lowercase_filter);
+ cm.Set("enable_profanity_filter", enable_profanity_filter);
cm.Set("enable_debug_mode", enable_debug_mode);
cm.Set("reset_on_toggle", reset_on_toggle);
cm.Set("gpu_idx", gpu_idx);
@@ -198,6 +200,7 @@ bool AppConfig::Deserialize(const std::filesystem::path& path) { cm.Get("remove_trailing_period", c.remove_trailing_period);
cm.Get("enable_uppercase_filter", c.enable_uppercase_filter);
cm.Get("enable_lowercase_filter", c.enable_lowercase_filter);
+ cm.Get("enable_profanity_filter", c.enable_profanity_filter);
cm.Get("enable_debug_mode", c.enable_debug_mode);
cm.Get("reset_on_toggle", c.reset_on_toggle);
cm.Get("gpu_idx", c.gpu_idx);
diff --git a/GUI/GUI/GUI/Config.h b/GUI/GUI/GUI/Config.h index e4a9bf4..213ce57 100644 --- a/GUI/GUI/GUI/Config.h +++ b/GUI/GUI/GUI/Config.h @@ -65,6 +65,7 @@ public: bool remove_trailing_period;
bool enable_uppercase_filter;
bool enable_lowercase_filter;
+ bool enable_profanity_filter;
bool enable_debug_mode;
bool reset_on_toggle;
int gpu_idx;
diff --git a/GUI/GUI/GUI/Frame.cpp b/GUI/GUI/GUI/Frame.cpp index 706165b..69def6b 100644 --- a/GUI/GUI/GUI/Frame.cpp +++ b/GUI/GUI/GUI/Frame.cpp @@ -47,6 +47,7 @@ namespace { ID_PY_APP_REMOVE_TRAILING_PERIOD,
ID_PY_APP_ENABLE_UPPERCASE_FILTER,
ID_PY_APP_ENABLE_LOWERCASE_FILTER,
+ ID_PY_APP_ENABLE_PROFANITY_FILTER,
ID_PY_APP_ENABLE_DEBUG_MODE,
ID_PY_APP_RESET_ON_TOGGLE,
ID_PY_APP_ROWS,
@@ -882,6 +883,16 @@ Frame::Frame() );
py_app_enable_lowercase_filter_ = py_app_enable_lowercase_filter;
+ auto* py_app_enable_profanity_filter = new wxCheckBox(py_config_panel,
+ ID_PY_APP_ENABLE_PROFANITY_FILTER, "Enable profanity filter");
+ py_app_enable_profanity_filter->SetValue(app_c_->enable_profanity_filter);
+ py_app_enable_profanity_filter->SetToolTip(
+ "If checked, profane words in your transcript will have "
+ "their vowels replaced with asterisks. Currently only "
+ "English is supported."
+ );
+ py_app_enable_profanity_filter_ = py_app_enable_profanity_filter;
+
auto* py_app_enable_debug_mode = new wxCheckBox(py_config_panel,
ID_PY_APP_ENABLE_DEBUG_MODE, "Enable debug mode");
py_app_enable_debug_mode->SetValue(app_c_->enable_debug_mode);
@@ -933,6 +944,8 @@ Frame::Frame() /*flags=*/wxEXPAND);
sizer->Add(py_app_enable_lowercase_filter, /*proportion=*/0,
/*flags=*/wxEXPAND);
+ sizer->Add(py_app_enable_profanity_filter, /*proportion=*/0,
+ /*flags=*/wxEXPAND);
sizer->Add(py_app_enable_debug_mode, /*proportion=*/0,
/*flags=*/wxEXPAND);
sizer->Add(py_app_start_button, /*proportion=*/0,
@@ -1453,6 +1466,9 @@ void Frame::ApplyConfigToInputFields() auto* py_app_enable_lowercase_filter = static_cast<wxCheckBox*>(FindWindowById(ID_PY_APP_ENABLE_LOWERCASE_FILTER));
py_app_enable_lowercase_filter->SetValue(app_c_->enable_lowercase_filter);
+ auto* py_app_enable_profanity_filter = static_cast<wxCheckBox*>(FindWindowById(ID_PY_APP_ENABLE_PROFANITY_FILTER));
+ py_app_enable_profanity_filter->SetValue(app_c_->enable_profanity_filter);
+
auto* py_app_enable_debug_mode = static_cast<wxCheckBox*>(FindWindowById(ID_PY_APP_ENABLE_DEBUG_MODE));
py_app_enable_debug_mode->SetValue(app_c_->enable_debug_mode);
@@ -2044,6 +2060,7 @@ void Frame::OnAppStart(wxCommandEvent& event) { const bool remove_trailing_period = py_app_remove_trailing_period_->GetValue();
const bool enable_uppercase_filter = py_app_enable_uppercase_filter_->GetValue();
const bool enable_lowercase_filter = py_app_enable_lowercase_filter_->GetValue();
+ const bool enable_profanity_filter = py_app_enable_profanity_filter_->GetValue();
const bool enable_debug_mode = py_app_enable_debug_mode_->GetValue();
const bool reset_on_toggle = py_app_reset_on_toggle_->GetValue();
std::string rows_str = py_app_rows_->GetValue().ToStdString();
@@ -2143,6 +2160,7 @@ void Frame::OnAppStart(wxCommandEvent& event) { app_c_->remove_trailing_period = remove_trailing_period;
app_c_->enable_uppercase_filter = enable_uppercase_filter;
app_c_->enable_lowercase_filter = enable_lowercase_filter;
+ app_c_->enable_profanity_filter = enable_profanity_filter;
app_c_->enable_debug_mode = enable_debug_mode;
app_c_->reset_on_toggle = reset_on_toggle;
app_c_->gpu_idx = gpu_idx;
diff --git a/GUI/GUI/GUI/Frame.h b/GUI/GUI/GUI/Frame.h index 46f5bcd..bed6cf7 100644 --- a/GUI/GUI/GUI/Frame.h +++ b/GUI/GUI/GUI/Frame.h @@ -69,6 +69,7 @@ private: wxCheckBox* py_app_remove_trailing_period_;
wxCheckBox* py_app_enable_uppercase_filter_;
wxCheckBox* py_app_enable_lowercase_filter_;
+ wxCheckBox* py_app_enable_profanity_filter_;
wxCheckBox* py_app_enable_debug_mode_;
wxCheckBox* py_app_reset_on_toggle_;
wxCheckBox* unity_clear_osc_;
diff --git a/GUI/GUI/GUI/PythonWrapper.cpp b/GUI/GUI/GUI/PythonWrapper.cpp index c5421e8..6e80744 100644 --- a/GUI/GUI/GUI/PythonWrapper.cpp +++ b/GUI/GUI/GUI/PythonWrapper.cpp @@ -493,6 +493,7 @@ std::future<bool> PythonWrapper::StartApp( "--remove_trailing_period", config.remove_trailing_period ? "1" : "0", "--enable_uppercase_filter", config.enable_uppercase_filter ? "1" : "0", "--enable_lowercase_filter", config.enable_lowercase_filter ? "1" : "0", + "--enable_profanity_filter", config.enable_profanity_filter ? "1" : "0", "--enable_debug_mode", config.enable_debug_mode ? "1" : "0", "--emotes_pickle", kEmotesPickle, "--gpu_idx", std::to_string(config.gpu_idx), diff --git a/GUI/package.ps1 b/GUI/package.ps1 index 4800777..db84a6d 100644 --- a/GUI/package.ps1 +++ b/GUI/package.ps1 @@ -133,6 +133,22 @@ if (-Not (Test-Path UwwwuPP)) { popd > $null
}
+if (-Not (Test-Path Profanity)) {
+ mkdir Profanity
+ pushd Profanity > $null
+
+ $repo = "List-of-Dirty-Naughty-Obscene-and-Otherwise-Bad-Words"
+ git clone https://github.com/LDNOOBW/$repo
+
+ mkdir Profanity
+ cp $repo/LICENSE Profanity/
+ cp $repo/en Profanity/
+
+ echo "Source: https://github.com/LDNOOBW/List-of-Dirty-Naughty-Obscene-and-Otherwise-Bad-Words" > Profanity/AUTHOR
+
+ popd > $null
+}
+
mkdir $install_dir > $null
mkdir $install_dir/Resources > $null
cp -Recurse ../Animations TaSTT/Resources/Animations
@@ -153,6 +169,7 @@ mkdir TaSTT/Resources/Models mkdir TaSTT/Resources/Uwu
cp UwwwuPP/build/Src/Debug/Uwwwu.exe TaSTT/Resources/Uwu/
cp UwwwuPP/LICENSE TaSTT/Resources/Uwu/
+cp -r Profanity/Profanity TaSTT/Resources/Profanity
if (-Not $skip_zip) {
Compress-Archive -Path "$install_dir" -DestinationPath "$install_dir.zip" -Force
diff --git a/Scripts/transcribe.py b/Scripts/transcribe.py index 28b6ca0..d937cb6 100644 --- a/Scripts/transcribe.py +++ b/Scripts/transcribe.py @@ -6,6 +6,7 @@ from faster_whisper import WhisperModel from functools import partial from math import ceil from playsound import playsound +from profanity_filter import ProfanityFilter from sentence_splitter import split_text_into_sentences import argparse @@ -67,6 +68,11 @@ class AudioState: # gets appended to `text`. self.commit_fuzz_threshold = 8 + # If set, profanity in transcriptions will have their vowels replaced + # with asterisks. Only works in English. + self.enable_profanity_filter = False + self.profanity_filter: ProfanityFilter = None + # List of: # List of tuples of: # Segment start time, end time, and text @@ -154,7 +160,7 @@ def onAudioFramesAvailable( return (frames, pyaudio.paContinue) -def getMicStream(which_mic): +def getMicStream(which_mic) -> AudioState: audio_state = AudioState() audio_state.p = pyaudio.PyAudio() @@ -346,10 +352,11 @@ def transcribeAudio(audio_state, audio_state.preview_text = audio_state.text + preview_text now = time.time() - print("Transcription ({} seconds): {}".format( - now - last_transcribe_time, - audio_state.preview_text)) - last_transcribe_time = now + if audio_state.enable_debug_mode: + print("Raw transcription ({} seconds): {}".format( + now - last_transcribe_time, + audio_state.preview_text)) + last_transcribe_time = now # Translate if requested. translated = audio_state.preview_text @@ -388,8 +395,16 @@ def transcribeAudio(audio_state, filtered_text = filtered_text.upper() if enable_lowercase_filter: filtered_text = filtered_text.lower() + if audio_state.enable_profanity_filter: + filtered_text = audio_state.profanity_filter.filter(filtered_text) audio_state.filtered_text = filtered_text + now = time.time() + print("Transcription ({} seconds): {}".format( + now - last_transcribe_time, + filtered_text)) + last_transcribe_time = now + if old_text != audio_state.preview_text: # We think the user said something, so reset the amount of # time we sleep between transcriptions to the minimum. @@ -618,6 +633,7 @@ def transcribeLoop(mic: str, remove_trailing_period: bool, enable_uppercase_filter: bool, enable_lowercase_filter: bool, + enable_profanity_filter: bool, enable_debug_mode: bool, button: str, estate: EmotesState, @@ -633,6 +649,13 @@ def transcribeLoop(mic: str, audio_state.reset_on_toggle = reset_on_toggle audio_state.commit_fuzz_threshold = commit_fuzz_threshold audio_state.enable_debug_mode = enable_debug_mode + audio_state.enable_profanity_filter = enable_profanity_filter + + # Set up profanity filter + en_profanity_path = os.path.abspath("Resources/Profanity/en") + audio_state.profanity_filter = ProfanityFilter(en_profanity_path) + if enable_profanity_filter: + audio_state.profanity_filter.load() lang_bits = language_target.split(" | ") if len(lang_bits) == 2: @@ -780,6 +803,7 @@ if __name__ == "__main__": parser.add_argument("--remove_trailing_period", type=int, help="If set to 1, trailing period will be removed.") parser.add_argument("--enable_uppercase_filter", type=int, help="If set to 1, transcriptions will be converted to UPPERCASE.") parser.add_argument("--enable_lowercase_filter", type=int, help="If set to 1, transcriptions will be converted to lowercase.") + parser.add_argument("--enable_profanity_filter", type=int, help="If set to 1, profanity in transcriptions will have their vowels replaced with asterisks. Only works in English.") parser.add_argument("--button", type=str, help="The controller button used to start/stop transcription. E.g. \"left joystick\"") parser.add_argument("--emotes_pickle", type=str, help="The path to emotes pickle. See emotes_v2.py for details.") parser.add_argument("--gpu_idx", type=str, help="The index of the GPU device to use. On single GPU systems, use 0.") @@ -870,6 +894,11 @@ if __name__ == "__main__": else: args.enable_lowercase_filter = False + if args.enable_profanity_filter == 1: + args.enable_profanity_filter = True + else: + args.enable_profanity_filter = False + if args.enable_debug_mode == 1: args.enable_debug_mode = True else: @@ -896,6 +925,7 @@ if __name__ == "__main__": args.remove_trailing_period, args.enable_uppercase_filter, args.enable_lowercase_filter, + args.enable_profanity_filter, args.enable_debug_mode, args.button, estate, window_duration_s, |
