From 027e9397d5bb60f29d84380ca1bd80ce3815f1b3 Mon Sep 17 00:00:00 2001 From: misygauziya Date: Fri, 18 Aug 2023 15:39:57 +0900 Subject: [PATCH] =?UTF-8?q?[Update]=20=E8=A6=81=E7=B4=A0=E6=A9=9F=E8=83=BD?= =?UTF-8?q?=E3=82=92model.py=E3=82=92=E9=80=9A=E3=81=97=E3=81=A6=E5=87=A6?= =?UTF-8?q?=E7=90=86=E3=81=99=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89?= =?UTF-8?q?=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VRCT.py | 240 +++++++------------------------------ config.py | 63 ++++++++++ model.py | 304 +++++++++++++++++++++++++++++++++++++++++++++++ window_config.py | 137 ++++++--------------- 4 files changed, 445 insertions(+), 299 deletions(-) create mode 100644 model.py diff --git a/VRCT.py b/VRCT.py index d62184f0..af03393a 100644 --- a/VRCT.py +++ b/VRCT.py @@ -1,35 +1,21 @@ from time import sleep from os import path as os_path -from requests import get as requests_get -from queue import Queue + import customtkinter from customtkinter import CTk, CTkFrame, CTkCheckBox, CTkFont, CTkButton, CTkImage, CTkTabview, CTkTextbox, CTkEntry from PIL.Image import open as Image_open -from flashtext import KeywordProcessor from threading import Thread -from utils import print_textbox, thread_fnc, get_localized_text, widget_main_window_label_setter -from osc_tools import send_typing, send_message, send_test_action, receive_osc_parameters +from utils import print_textbox, get_localized_text, widget_main_window_label_setter from window_config import ToplevelWindowConfig from window_information import ToplevelWindowInformation -from languages import transcription_lang -from audio_utils import get_input_device_list, get_output_device_list -from audio_recorder import SelectedMicRecorder, SelectedSpeakerRecorder -from audio_transcriber import AudioTranscriber -from translation import Translator from config import config -from notification import notification_xsoverlay_for_vrct - -__version__ = "1.3.2" +from model import model class App(CTk): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - # init instance - self.translator = Translator() - self.keyword_processor = KeywordProcessor() - ## set UI theme customtkinter.set_appearance_mode(config.APPEARANCE_THEME) customtkinter.set_default_color_theme("blue") @@ -68,28 +54,16 @@ class App(CTk): def init_process(self): # set translator - if self.translator.authentication(config.CHOICE_TRANSLATOR, config.AUTH_KEYS[config.CHOICE_TRANSLATOR]) is False: + if model.authenticationTranslator() is False: # error update Auth key print_textbox(self.textbox_message_log, "Auth Key or language setting is incorrect", "ERROR") print_textbox(self.textbox_message_system_log, "Auth Key or language setting is incorrect", "ERROR") # set word filter - for f in config.INPUT_MIC_WORD_FILTER: - self.keyword_processor.add_keyword(f) + model.addKeywords() - # start receive osc - th_receive_osc_parameters = Thread(target=receive_osc_parameters, args=(self.check_osc_receive,)) - th_receive_osc_parameters.daemon = True - th_receive_osc_parameters.start() - - # check osc started - send_test_action() - - # check update - response = requests_get(config.GITHUB_URL) - tag_name = response.json()["tag_name"] - if tag_name != __version__: - config.UPDATE_FLAG = True + # check OSC started + model.oscCheck() def button_config_callback(self): self.foreground_stop() @@ -117,7 +91,8 @@ class App(CTk): self.information_window.focus() def checkbox_translation_callback(self): - if self.checkbox_translation.get() is True: + config.ENABLE_TRANSLATION = self.checkbox_translation.get() + if config.ENABLE_TRANSLATION is True: print_textbox(self.textbox_message_log, "Start translation", "INFO") print_textbox(self.textbox_message_system_log, "Start translation", "INFO") else: @@ -125,61 +100,7 @@ class App(CTk): print_textbox(self.textbox_message_system_log, "Stop translation", "INFO") def transcription_send_start(self): - self.mic_audio_queue = Queue() - mic_device = [device for device in get_input_device_list()[config.CHOICE_MIC_HOST] if device["name"] == config.CHOICE_MIC_DEVICE][0] - self.mic_audio_recorder = SelectedMicRecorder( - mic_device, - config.INPUT_MIC_ENERGY_THRESHOLD, - config.INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD, - config.INPUT_MIC_RECORD_TIMEOUT, - ) - self.mic_audio_recorder.record_into_queue(self.mic_audio_queue) - self.mic_transcriber = AudioTranscriber( - speaker=False, - source=self.mic_audio_recorder.source, - phrase_timeout=config.INPUT_MIC_PHRASE_TIMEOUT, - max_phrases=config.INPUT_MIC_MAX_PHRASES, - ) - def mic_transcript_to_chatbox(): - self.mic_transcriber.transcribe_audio_queue(self.mic_audio_queue, transcription_lang[config.INPUT_MIC_VOICE_LANGUAGE]) - message = self.mic_transcriber.get_transcript() - if len(message) > 0: - # word filter - if len(self.keyword_processor.extract_keywords(message)) != 0: - print_textbox(self.textbox_message_log, f"Detect WordFilter :{message}", "INFO") - print_textbox(self.textbox_message_system_log, f"Detect WordFilter :{message}", "INFO") - return - - # translate - if self.checkbox_translation.get() is False: - voice_message = f"{message}" - elif self.translator.translator_status[config.CHOICE_TRANSLATOR] is False: - print_textbox(self.textbox_message_log, "Auth Key or language setting is incorrect", "ERROR") - print_textbox(self.textbox_message_system_log, "Auth Key or language setting is incorrect", "ERROR") - voice_message = f"{message}" - else: - result = self.translator.translate( - translator_name=config.CHOICE_TRANSLATOR, - source_language=config.INPUT_SOURCE_LANG, - target_language=config.INPUT_TARGET_LANG, - message=message - ) - voice_message = config.MESSAGE_FORMAT.replace("[message]", message).replace("[translation]", result) - - if self.checkbox_transcription_send.get() is True: - if config.ENABLE_OSC is True: - # send OSC message - send_message(voice_message, config.OSC_IP_ADDRESS, config.OSC_PORT) - else: - print_textbox(self.textbox_message_log, "OSC is not enabled, please enable OSC and rejoin.", "ERROR") - print_textbox(self.textbox_message_system_log, "OSC is not enabled, please enable OSC and rejoin.", "ERROR") - # update textbox message log - print_textbox(self.textbox_message_log, f"{voice_message}", "SEND") - print_textbox(self.textbox_message_send_log, f"{voice_message}", "SEND") - - self.mic_print_transcript = thread_fnc(mic_transcript_to_chatbox) - self.mic_print_transcript.daemon = True - self.mic_print_transcript.start() + model.startMicTranscript(self.textbox_message_log, self.textbox_message_send_log, self.textbox_message_system_log) print_textbox(self.textbox_message_log, "Start voice2chatbox", "INFO") print_textbox(self.textbox_message_system_log, "Start voice2chatbox", "INFO") self.checkbox_transcription_send.configure(state="normal") @@ -187,12 +108,7 @@ class App(CTk): self.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"]) def transcription_send_stop(self): - if isinstance(self.mic_print_transcript, thread_fnc): - self.mic_print_transcript.stop() - if self.mic_audio_recorder.stop != None: - self.mic_audio_recorder.stop() - self.mic_audio_recorder.stop = None - + model.stopMicTranscript() print_textbox(self.textbox_message_log, "Stop voice2chatbox", "INFO") print_textbox(self.textbox_message_system_log, "Stop voice2chatbox", "INFO") self.checkbox_transcription_send.configure(state="normal") @@ -200,20 +116,16 @@ class App(CTk): self.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"]) def transcription_send_stop_for_config(self): - if isinstance(self.mic_print_transcript, thread_fnc): - self.mic_print_transcript.stop() - if self.mic_audio_recorder.stop != None: - self.mic_audio_recorder.stop() - self.mic_audio_recorder.stop = None - + model.stopMicTranscript() print_textbox(self.textbox_message_log, "Stop voice2chatbox", "INFO") print_textbox(self.textbox_message_system_log, "Stop voice2chatbox", "INFO") def checkbox_transcription_send_callback(self): + config.ENABLE_TRANSCRIPTION_SEND = self.checkbox_transcription_send.get() self.checkbox_transcription_send.configure(state="disabled") self.checkbox_transcription_receive.configure(state="disabled") self.button_config.configure(state="disabled", fg_color=["gray92", "gray14"]) - if self.checkbox_transcription_send.get() is True: + if config.ENABLE_TRANSCRIPTION_SEND is True: th_transcription_send_start = Thread(target=self.transcription_send_start) th_transcription_send_start.daemon = True th_transcription_send_start.start() @@ -223,54 +135,7 @@ class App(CTk): th_transcription_send_stop.start() def transcription_receive_start(self): - self.spk_audio_queue = Queue() - spk_device = [device for device in get_output_device_list() if device["name"] == config.CHOICE_SPEAKER_DEVICE][0] - self.spk_audio_recorder = SelectedSpeakerRecorder( - spk_device, - config.INPUT_SPEAKER_ENERGY_THRESHOLD, - config.INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD, - config.INPUT_SPEAKER_RECORD_TIMEOUT, - ) - self.spk_audio_recorder.record_into_queue(self.spk_audio_queue) - self.spk_transcriber = AudioTranscriber( - speaker=True, - source=self.spk_audio_recorder.source, - phrase_timeout=config.INPUT_SPEAKER_PHRASE_TIMEOUT, - max_phrases=config.INPUT_SPEAKER_MAX_PHRASES, - ) - - def spk_transcript_to_textbox(): - self.spk_transcriber.transcribe_audio_queue(self.spk_audio_queue, transcription_lang[config.INPUT_SPEAKER_VOICE_LANGUAGE]) - message = self.spk_transcriber.get_transcript() - if len(message) > 0: - # translate - if self.checkbox_translation.get() is False: - voice_message = f"{message}" - elif self.translator.translator_status[config.CHOICE_TRANSLATOR] is False: - print_textbox(self.textbox_message_log, "Auth Key or language setting is incorrect", "ERROR") - print_textbox(self.textbox_message_system_log, "Auth Key or language setting is incorrect", "ERROR") - voice_message = f"{message}" - else: - result = self.translator.translate( - translator_name=config.CHOICE_TRANSLATOR, - source_language=config.OUTPUT_SOURCE_LANG, - target_language=config.OUTPUT_TARGET_LANG, - message=message - ) - voice_message = config.MESSAGE_FORMAT.replace("[message]", message).replace("[translation]", result) - # send OSC message - # send_message(voice_message, config.OSC_IP_ADDRESS, self.OSC_PORT) - - if self.checkbox_transcription_receive.get() is True: - # update textbox message receive log - print_textbox(self.textbox_message_log, f"{voice_message}", "RECEIVE") - print_textbox(self.textbox_message_receive_log, f"{voice_message}", "RECEIVE") - if config.ENABLE_NOTICE_XSOVERLAY is True: - notification_xsoverlay_for_vrct(content=f"{voice_message}") - - self.spk_print_transcript = thread_fnc(spk_transcript_to_textbox) - self.spk_print_transcript.daemon = True - self.spk_print_transcript.start() + model.startSpeakerTranscript(self.textbox_message_log, self.textbox_message_receive_log, self.textbox_message_system_log) print_textbox(self.textbox_message_log, "Start speaker2log", "INFO") print_textbox(self.textbox_message_system_log, "Start speaker2log", "INFO") self.checkbox_transcription_send.configure(state="normal") @@ -278,12 +143,7 @@ class App(CTk): self.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"]) def transcription_receive_stop(self): - if isinstance(self.spk_print_transcript, thread_fnc): - self.spk_print_transcript.stop() - if self.spk_audio_recorder.stop != None: - self.spk_audio_recorder.stop() - self.spk_audio_recorder.stop = None - + model.stopSpeakerTranscript() print_textbox(self.textbox_message_log, "Stop speaker2log", "INFO") print_textbox(self.textbox_message_system_log, "Stop speaker2log", "INFO") self.checkbox_transcription_send.configure(state="normal") @@ -291,20 +151,16 @@ class App(CTk): self.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"]) def transcription_receive_stop_for_config(self): - if isinstance(self.spk_print_transcript, thread_fnc): - self.spk_print_transcript.stop() - if self.spk_audio_recorder.stop != None: - self.spk_audio_recorder.stop() - self.spk_audio_recorder.stop = None - + model.stopSpeakerTranscript() print_textbox(self.textbox_message_log, "Stop speaker2log", "INFO") print_textbox(self.textbox_message_system_log, "Stop speaker2log", "INFO") def checkbox_transcription_receive_callback(self): + config.ENABLE_TRANSCRIPTION_RECEIVE = self.checkbox_transcription_receive.get() self.checkbox_transcription_send.configure(state="disabled") self.checkbox_transcription_receive.configure(state="disabled") self.button_config.configure(state="disabled", fg_color=["gray92", "gray14"]) - if self.checkbox_transcription_receive.get() is True: + if config.ENABLE_TRANSCRIPTION_RECEIVE is True: th_transcription_receive_start = Thread(target=self.transcription_receive_start) th_transcription_receive_start.daemon = True th_transcription_receive_start.start() @@ -314,28 +170,29 @@ class App(CTk): th_transcription_receive_stop.start() def transcription_start(self): - if self.checkbox_transcription_send.get() is True: + if config.ENABLE_TRANSCRIPTION_SEND is True: th_transcription_send_start = Thread(target=self.transcription_send_start) th_transcription_send_start.daemon = True th_transcription_send_start.start() sleep(2) - if self.checkbox_transcription_receive.get() is True: + if config.ENABLE_TRANSCRIPTION_RECEIVE is True: th_transcription_receive_start = Thread(target=self.transcription_receive_start) th_transcription_receive_start.daemon = True th_transcription_receive_start.start() def transcription_stop(self): - if self.checkbox_transcription_send.get() is True: + if config.ENABLE_TRANSCRIPTION_SEND is True: th_transcription_send_stop = Thread(target=self.transcription_send_stop_for_config) th_transcription_send_stop.daemon = True th_transcription_send_stop.start() - if self.checkbox_transcription_receive.get() is True: + if config.ENABLE_TRANSCRIPTION_RECEIVE is True: th_transcription_receive_stop = Thread(target=self.transcription_receive_stop_for_config) th_transcription_receive_stop.daemon = True th_transcription_receive_stop.start() def checkbox_foreground_callback(self): - if self.checkbox_foreground.get(): + config.ENABLE_FOREGROUND = self.checkbox_foreground.get() + if config.ENABLE_FOREGROUND: self.attributes("-topmost", True) print_textbox(self.textbox_message_log, "Start foreground", "INFO") print_textbox(self.textbox_message_system_log, "Start foreground", "INFO") @@ -345,45 +202,39 @@ class App(CTk): print_textbox(self.textbox_message_system_log, "Stop foreground", "INFO") def foreground_start(self): - if self.checkbox_foreground.get(): + if config.ENABLE_FOREGROUND: self.attributes("-topmost", True) print_textbox(self.textbox_message_log, "Start foreground", "INFO") print_textbox(self.textbox_message_system_log, "Start foreground", "INFO") def foreground_stop(self): - if self.checkbox_foreground.get(): + if config.ENABLE_FOREGROUND: self.attributes("-topmost", False) print_textbox(self.textbox_message_log, "Stop foreground", "INFO") print_textbox(self.textbox_message_system_log, "Stop foreground", "INFO") def entry_message_box_press_key_enter(self, event): - # send OSC typing - send_typing(False, config.OSC_IP_ADDRESS, config.OSC_PORT) + # osc stop send typing + model.oscStopSendTyping() - if self.checkbox_foreground.get(): + if config.ENABLE_FOREGROUND: self.attributes("-topmost", True) message = self.entry_message_box.get() if len(message) > 0: # translate - if self.checkbox_translation.get() is False: + if config.ENABLE_TRANSLATION is False: chat_message = f"{message}" - elif self.translator.translator_status[config.CHOICE_TRANSLATOR] is False: + elif model.getTranslatorStatus() is False: print_textbox(self.textbox_message_log, "Auth Key or language setting is incorrect", "ERROR") print_textbox(self.textbox_message_system_log, "Auth Key or language setting is incorrect", "ERROR") chat_message = f"{message}" else: - result = self.translator.translate( - translator_name=config.CHOICE_TRANSLATOR, - source_language=config.INPUT_SOURCE_LANG, - target_language=config.INPUT_TARGET_LANG, - message=message - ) - chat_message = config.MESSAGE_FORMAT.replace("[message]", message).replace("[translation]", result) + chat_message = model.getInputTranslate(message) # send OSC message if config.ENABLE_OSC is True: - send_message(chat_message, config.OSC_IP_ADDRESS, config.OSC_PORT) + model.oscSendMessage(chat_message) else: print_textbox(self.textbox_message_log, "OSC is not enabled, please enable OSC and rejoin.", "ERROR") print_textbox(self.textbox_message_system_log, "OSC is not enabled, please enable OSC and rejoin.", "ERROR") @@ -396,25 +247,21 @@ class App(CTk): if config.ENABLE_AUTO_CLEAR_CHATBOX is True: self.entry_message_box.delete(0, customtkinter.END) - BREAK_KEYSYM_LIST = [ - "Delete", "Select", "Up", "Down", "Next", "End", "Print", - "Prior","Insert","Home", "Left", "Clear", "Right", "Linefeed" - ] def entry_message_box_press_key_any(self, event): - # send OSC typing - send_typing(True, config.OSC_IP_ADDRESS, config.OSC_PORT) - if self.checkbox_foreground.get(): + # osc start send typing + model.oscStartSendTyping() + if config.ENABLE_FOREGROUND: self.attributes("-topmost", False) if event.keysym != "??": - if len(event.char) != 0 and event.keysym in self.BREAK_KEYSYM_LIST: + if len(event.char) != 0 and event.keysym in config.BREAK_KEYSYM_LIST: self.entry_message_box.insert("end", event.char) return "break" def entry_message_box_leave(self, event): - # send OSC typing - send_typing(False, config.OSC_IP_ADDRESS, config.OSC_PORT) - if self.checkbox_foreground.get(): + # osc stop send typing + model.oscStopSendTyping() + if config.ENABLE_FOREGROUND: self.attributes("-topmost", True) def delete_window(self): @@ -558,11 +405,6 @@ class App(CTk): widget_main_window_label_setter(self, language_yaml_data) - def check_osc_receive(self, address, osc_arguments): - print(address, osc_arguments) - if config.ENABLE_OSC is False: - config.ENABLE_OSC = True - if __name__ == "__main__": try: app = App() diff --git a/config.py b/config.py index 753cc7f2..0cb6f299 100644 --- a/config.py +++ b/config.py @@ -18,10 +18,50 @@ class Config: cls._instance.load_config() return cls._instance + @property + def VERSION(self): + return self._VERSION + @property def PATH_CONFIG(self): return self._PATH_CONFIG + @property + def ENABLE_TRANSLATION(self): + return self._ENABLE_TRANSLATION + + @ENABLE_TRANSLATION.setter + def ENABLE_TRANSLATION(self, value): + if type(value) is bool: + self._ENABLE_TRANSLATION = value + + @property + def ENABLE_TRANSCRIPTION_SEND(self): + return self._ENABLE_TRANSCRIPTION_SEND + + @ENABLE_TRANSCRIPTION_SEND.setter + def ENABLE_TRANSCRIPTION_SEND(self, value): + if type(value) is bool: + self._ENABLE_TRANSCRIPTION_SEND = value + + @property + def ENABLE_TRANSCRIPTION_RECEIVE(self): + return self._ENABLE_TRANSCRIPTION_RECEIVE + + @ENABLE_TRANSCRIPTION_RECEIVE.setter + def ENABLE_TRANSCRIPTION_RECEIVE(self, value): + if type(value) is bool: + self._ENABLE_TRANSCRIPTION_RECEIVE = value + + @property + def ENABLE_FOREGROUND(self): + return self._ENABLE_FOREGROUND + + @ENABLE_FOREGROUND.setter + def ENABLE_FOREGROUND(self, value): + if type(value) is bool: + self._ENABLE_FOREGROUND = value + @property def TRANSPARENCY(self): return self._TRANSPARENCY @@ -371,8 +411,25 @@ class Config: def GITHUB_URL(self): return self._GITHUB_URL + @property + def BREAK_KEYSYM_LIST(self): + return self._BREAK_KEYSYM_LIST + + @property + def MAX_MIC_ENERGY_THRESHOLD(self): + return self._MAX_MIC_ENERGY_THRESHOLD + + @property + def MAX_SPEAKER_ENERGY_THRESHOLD(self): + return self._MAX_SPEAKER_ENERGY_THRESHOLD + def init_config(self): + self._VERSION = "1.3.2" self._PATH_CONFIG = "./config.json" + self._ENABLE_TRANSLATION = False + self._ENABLE_TRANSCRIPTION_SEND = False + self._ENABLE_TRANSCRIPTION_RECEIVE = False + self._ENABLE_FOREGROUND = False self._TRANSPARENCY = 100 self._APPEARANCE_THEME = "System" self._UI_SCALING = "100%" @@ -413,6 +470,12 @@ class Config: self._ENABLE_OSC = False self._UPDATE_FLAG = False self._GITHUB_URL = "https://api.github.com/repos/misyaguziya/VRCT/releases/latest" + self._BREAK_KEYSYM_LIST = [ + "Delete", "Select", "Up", "Down", "Next", "End", "Print", + "Prior","Insert","Home", "Left", "Clear", "Right", "Linefeed" + ] + self._MAX_MIC_ENERGY_THRESHOLD = 2000 + self._MAX_SPEAKER_ENERGY_THRESHOLD = 4000 def load_config(self): if os_path.isfile(self.PATH_CONFIG) is not False: diff --git a/model.py b/model.py new file mode 100644 index 00000000..c550f43e --- /dev/null +++ b/model.py @@ -0,0 +1,304 @@ +from time import sleep +from queue import Queue +from threading import Thread +from requests import get as requests_get + +from translation import Translator +from flashtext import KeywordProcessor +from osc_tools import send_typing, send_message, send_test_action, receive_osc_parameters +from languages import transcription_lang +from audio_utils import get_input_device_list, get_output_device_list, get_default_output_device +from audio_recorder import SelectedMicRecorder, SelectedSpeakerRecorder +from audio_recorder import SelectedMicEnergyRecorder, SelectedSpeakeEnergyRecorder +from audio_transcriber import AudioTranscriber +from utils import print_textbox, thread_fnc +from config import config +from notification import notification_xsoverlay_for_vrct + +class Model: + _instance = None + + def __new__(cls): + if cls._instance is None: + cls._instance = super(Model, cls).__new__(cls) + cls._instance.init() + return cls._instance + + def init(self): + self.mic_energy_recorder = None + self.mic_energy_plot_progressbar = None + self.speaker_energy_get_progressbar = None + self.speaker_energy_plot_progressbar = None + self.translator = Translator() + self.keyword_processor = KeywordProcessor() + + def resetTranslator(self): + del self.translator + self.translator = Translator() + + def resetKeywordProcessor(self): + del self.translator + self.keyword_processor = KeywordProcessor() + + def authenticationTranslator(self, choice_translator=None, auth_key=None): + if choice_translator == None: + choice_translator = config.CHOICE_TRANSLATOR + if auth_key == None: + auth_key = config.AUTH_KEYS[choice_translator] + + result = self.translator.authentication(choice_translator, auth_key) + if result: + auth_keys = config.AUTH_KEYS + auth_keys[choice_translator] = auth_key + config.AUTH_KEYS = auth_keys + return result + + def getTranslatorStatus(self): + return self.translator.translator_status[config.CHOICE_TRANSLATOR] + + def getListTranslatorName(self): + return list(self.translator.translator_status.keys()) + + def getInputTranslate(self, message): + translation = self.translator.translate( + translator_name=config.CHOICE_TRANSLATOR, + source_language=config.INPUT_SOURCE_LANG, + target_language=config.INPUT_TARGET_LANG, + message=message + ) + message = config.MESSAGE_FORMAT.replace("[message]", message).replace("[translation]", translation) + return message + + def getOutputTranslate(self, message): + translation = self.translator.translate( + translator_name=config.CHOICE_TRANSLATOR, + source_language=config.OUTPUT_SOURCE_LANG, + target_language=config.OUTPUT_TARGET_LANG, + message=message + ) + message = config.MESSAGE_FORMAT.replace("[message]", message).replace("[translation]", translation) + return message + + def addKeywords(self): + for f in config.INPUT_MIC_WORD_FILTER: + self.keyword_processor.add_keyword(f) + + def checkKeywords(self, message): + return len(self.keyword_processor.extract_keywords(message)) != 0 + + @staticmethod + def oscStartSendTyping(): + send_typing(True, config.OSC_IP_ADDRESS, config.OSC_PORT) + + @staticmethod + def oscStopSendTyping(): + send_typing(False, config.OSC_IP_ADDRESS, config.OSC_PORT) + + @staticmethod + def oscSendMessage(message): + send_message(message, config.OSC_IP_ADDRESS, config.OSC_PORT) + + @staticmethod + def oscCheck(): + def check_osc_receive(address, osc_arguments): + if config.ENABLE_OSC is False: + config.ENABLE_OSC = True + + # start receive osc + th_receive_osc_parameters = Thread(target=receive_osc_parameters, args=(check_osc_receive,)) + th_receive_osc_parameters.daemon = True + th_receive_osc_parameters.start() + + # check osc started + send_test_action() + + # check update + response = requests_get(config.GITHUB_URL) + tag_name = response.json()["tag_name"] + if tag_name != config.VERSION: + config.UPDATE_FLAG = True + + @staticmethod + def getListInputHost(): + return [host for host in get_input_device_list().keys()] + + @staticmethod + def getListInputDevice(): + return [device["name"] for device in get_input_device_list()[config.CHOICE_MIC_HOST]] + + @staticmethod + def getInputDefaultDevice(): + return [device["name"] for device in get_input_device_list()[config.CHOICE_MIC_HOST]][0] + + @staticmethod + def getListOutputDevice(): + return [device["name"] for device in get_output_device_list()] + + @staticmethod + def checkSpeakerStatus(choice=config.CHOICE_SPEAKER_DEVICE): + speaker_device = [device for device in get_output_device_list() if device["name"] == choice][0] + if get_default_output_device()["index"] == speaker_device["index"]: + return True + return False + + def startMicTranscript(self, log, send_log, system_log): + mic_audio_queue = Queue() + self.mic_audio_recorder = SelectedMicRecorder( + [device for device in get_input_device_list()[config.CHOICE_MIC_HOST] if device["name"] == config.CHOICE_MIC_DEVICE][0], + config.INPUT_MIC_ENERGY_THRESHOLD, + config.INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD, + config.INPUT_MIC_RECORD_TIMEOUT, + ) + self.mic_audio_recorder.record_into_queue(mic_audio_queue) + mic_transcriber = AudioTranscriber( + speaker=False, + source=self.mic_audio_recorder.source, + phrase_timeout=config.INPUT_MIC_PHRASE_TIMEOUT, + max_phrases=config.INPUT_MIC_MAX_PHRASES, + ) + def mic_transcript_to_chatbox(): + mic_transcriber.transcribe_audio_queue(mic_audio_queue, transcription_lang[config.INPUT_MIC_VOICE_LANGUAGE]) + message = mic_transcriber.get_transcript() + if len(message) > 0: + print(message) + # word filter + if self.checkKeywords(message): + print_textbox(log, f"Detect WordFilter :{message}", "INFO") + print_textbox(system_log, f"Detect WordFilter :{message}", "INFO") + return + + # translate + if config.ENABLE_TRANSLATION is False: + voice_message = f"{message}" + elif self.getTranslatorStatus() is False: + print_textbox(log, "Auth Key or language setting is incorrect", "ERROR") + print_textbox(system_log, "Auth Key or language setting is incorrect", "ERROR") + voice_message = f"{message}" + else: + voice_message = self.getInputTranslate(message) + + if config.ENABLE_TRANSCRIPTION_SEND is True: + if config.ENABLE_OSC is True: + # osc send message + model.oscSendMessage(voice_message) + else: + print_textbox(log, "OSC is not enabled, please enable OSC and rejoin.", "ERROR") + print_textbox(system_log, "OSC is not enabled, please enable OSC and rejoin.", "ERROR") + # update textbox message log + print_textbox(log, f"{voice_message}", "SEND") + print_textbox(send_log, f"{voice_message}", "SEND") + + self.mic_print_transcript = thread_fnc(mic_transcript_to_chatbox) + self.mic_print_transcript.daemon = True + self.mic_print_transcript.start() + + def stopMicTranscript(self): + if isinstance(self.mic_print_transcript, thread_fnc): + self.mic_print_transcript.stop() + if self.mic_audio_recorder.stop != None: + self.mic_audio_recorder.stop() + self.mic_audio_recorder.stop = None + + def startCheckMicEnergy(self, progressBar): + def progressBarInputMicEnergyPlot(): + if mic_energy_queue.empty() is False: + energy = mic_energy_queue.get() + try: + progressBar.set(energy/config.MAX_MIC_ENERGY_THRESHOLD) + except: + pass + sleep(0.01) + mic_energy_queue = Queue() + mic_device = [device for device in get_input_device_list()[config.CHOICE_MIC_HOST] if device["name"] == config.CHOICE_MIC_DEVICE][0] + self.mic_energy_recorder = SelectedMicEnergyRecorder(mic_device) + self.mic_energy_recorder.record_into_queue(mic_energy_queue) + self.mic_energy_plot_progressbar = thread_fnc(progressBarInputMicEnergyPlot) + self.mic_energy_plot_progressbar.daemon = True + self.mic_energy_plot_progressbar.start() + + def stopCheckMicEnergy(self): + if self.mic_energy_recorder != None: + self.mic_energy_recorder.stop() + if self.mic_energy_plot_progressbar != None: + self.mic_energy_plot_progressbar.stop() + + def startSpeakerTranscript(self, log, receive_log, system_log): + spk_audio_queue = Queue() + spk_device = [device for device in get_output_device_list() if device["name"] == config.CHOICE_SPEAKER_DEVICE][0] + self.spk_audio_recorder = SelectedSpeakerRecorder( + spk_device, + config.INPUT_SPEAKER_ENERGY_THRESHOLD, + config.INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD, + config.INPUT_SPEAKER_RECORD_TIMEOUT, + ) + self.spk_audio_recorder.record_into_queue(spk_audio_queue) + spk_transcriber = AudioTranscriber( + speaker=True, + source=self.spk_audio_recorder.source, + phrase_timeout=config.INPUT_SPEAKER_PHRASE_TIMEOUT, + max_phrases=config.INPUT_SPEAKER_MAX_PHRASES, + ) + def spk_transcript_to_textbox(): + spk_transcriber.transcribe_audio_queue(spk_audio_queue, transcription_lang[config.INPUT_SPEAKER_VOICE_LANGUAGE]) + message = spk_transcriber.get_transcript() + if len(message) > 0: + # translate + if config.ENABLE_TRANSLATION is False: + voice_message = f"{message}" + elif model.getTranslatorStatus() is False: + print_textbox(log, "Auth Key or language setting is incorrect", "ERROR") + print_textbox(system_log, "Auth Key or language setting is incorrect", "ERROR") + voice_message = f"{message}" + else: + voice_message = model.getOutputTranslate(message) + + if config.ENABLE_TRANSCRIPTION_RECEIVE is True: + # update textbox message receive log + print_textbox(log, f"{voice_message}", "RECEIVE") + print_textbox(receive_log, f"{voice_message}", "RECEIVE") + if config.ENABLE_NOTICE_XSOVERLAY is True: + notification_xsoverlay_for_vrct(content=f"{voice_message}") + + self.spk_print_transcript = thread_fnc(spk_transcript_to_textbox) + self.spk_print_transcript.daemon = True + self.spk_print_transcript.start() + + def stopSpeakerTranscript(self): + if isinstance(self.spk_print_transcript, thread_fnc): + self.spk_print_transcript.stop() + if self.spk_audio_recorder.stop != None: + self.spk_audio_recorder.stop() + self.spk_audio_recorder.stop = None + + def startCheckSpeakerEnergy(self, progressBar): + def progressBar_input_speaker_energy_plot(): + if speaker_energy_queue.empty() is False: + energy = speaker_energy_queue.get() + try: + progressBar.set(energy/config.MAX_SPEAKER_ENERGY_THRESHOLD) + except: + pass + sleep(0.01) + + def progressBar_input_speaker_energy_get(): + with self.speaker_energy_recorder.source as source: + energy = self.speaker_energy_recorder.recorder.listen_energy(source) + self.speaker_energy_queue.put(energy) + + speaker_device = [device for device in get_output_device_list() if device["name"] == config.CHOICE_SPEAKER_DEVICE][0] + speaker_energy_queue = Queue() + self.speaker_energy_recorder = SelectedSpeakeEnergyRecorder(speaker_device) + self.speaker_energy_get_progressbar = thread_fnc(progressBar_input_speaker_energy_get) + self.speaker_energy_get_progressbar.daemon = True + self.speaker_energy_get_progressbar.start() + self.speaker_energy_plot_progressbar = thread_fnc(progressBar_input_speaker_energy_plot) + self.speaker_energy_plot_progressbar.daemon = True + self.speaker_energy_plot_progressbar.start() + + def stopCheckSpeakerEnergy(self): + if self.speaker_energy_get_progressbar != None: + self.speaker_energy_get_progressbar.stop() + if self.speaker_energy_plot_progressbar != None: + self.speaker_energy_plot_progressbar.stop() + +model = Model() diff --git a/window_config.py b/window_config.py index 8b28937e..b54429cf 100644 --- a/window_config.py +++ b/window_config.py @@ -1,17 +1,13 @@ -from time import sleep -from queue import Queue from os import path as os_path from tkinter import DoubleVar, IntVar from tkinter import font as tk_font import customtkinter from customtkinter import CTkToplevel, CTkTabview, CTkFont, CTkLabel, CTkSlider, CTkOptionMenu, StringVar, CTkEntry, CTkCheckBox, CTkProgressBar -from flashtext import KeywordProcessor from threading import Thread from config import config -from utils import print_textbox, thread_fnc, get_localized_text, get_key_by_value, widget_config_window_label_setter -from audio_utils import get_input_device_list, get_output_device_list, get_default_output_device -from audio_recorder import SelectedMicEnergyRecorder, SelectedSpeakeEnergyRecorder +from model import model +from utils import print_textbox, get_localized_text, get_key_by_value, widget_config_window_label_setter from languages import translation_lang, transcription_lang, selectable_languages from ctk_scrollable_dropdown import CTkScrollableDropdown @@ -33,15 +29,6 @@ class ToplevelWindowConfig(CTkToplevel): self.after(200, lambda: self.iconbitmap(os_path.join(os_path.dirname(__file__), "img", "app.ico"))) self.title("Config") - # init parameter - self.MAX_MIC_ENERGY_THRESHOLD = 2000 - self.MAX_SPEAKER_ENERGY_THRESHOLD = 4000 - self.mic_energy_recorder = None - self.mic_energy_plot_progressbar = None - self.speaker_energy_recorder = None - self.speaker_energy_get_progressbar = None - self.speaker_energy_plot_progressbar = None - # load ui language data language_yaml_data = get_localized_text(f"{config.UI_LANGUAGE}") # add tabview config @@ -202,7 +189,7 @@ class ToplevelWindowConfig(CTkToplevel): def optionmenu_translation_translator_callback(self, choice): self.optionmenu_translation_translator.set(choice) - if self.parent.translator.authentication(choice, config.AUTH_KEYS[choice]) is False: + if model.authenticationTranslator(choice_translator=choice) is False: print_textbox(self.parent.textbox_message_log, "Auth Key or language setting is incorrect", "ERROR") print_textbox(self.parent.textbox_message_system_log, "Auth Key or language setting is incorrect", "ERROR") else: @@ -253,15 +240,15 @@ class ToplevelWindowConfig(CTkToplevel): def optionmenu_input_mic_host_callback(self, choice): self.optionmenu_input_mic_host.set(choice) + config.CHOICE_MIC_HOST = choice + config.CHOICE_MIC_DEVICE = model.getInputDefaultDevice() + self.optionmenu_input_mic_device.configure( - values=[device["name"] for device in get_input_device_list()[choice]], - variable=StringVar(value=[device["name"] for device in get_input_device_list()[choice]][0])) + values=model.getListInputDevice(), + variable=StringVar(value=model.getInputDefaultDevice())) if SCROLLABLE_DROPDOWN: - self.scrollableDropdown_input_mic_device.configure(values=[device["name"] for device in get_input_device_list()[choice]]) - - config.CHOICE_MIC_HOST = choice - config.CHOICE_MIC_DEVICE = [device["name"] for device in get_input_device_list()[choice]][0] + self.scrollableDropdown_input_mic_device.configure(values=model.getListInputDevice()) def optionmenu_input_mic_device_callback(self, choice): self.optionmenu_input_mic_device.set(choice) @@ -273,31 +260,13 @@ class ToplevelWindowConfig(CTkToplevel): self.optionmenu_input_mic_voice_language.set(choice) config.INPUT_MIC_VOICE_LANGUAGE = choice - def progressBar_input_mic_energy_plot(self): - if self.mic_energy_queue.empty() is False: - energy = self.mic_energy_queue.get() - try: - self.progressBar_input_mic_energy_threshold.set(energy/self.MAX_MIC_ENERGY_THRESHOLD) - except: - pass - sleep(0.01) - def mic_threshold_check_start(self): - self.mic_energy_queue = Queue() - mic_device = [device for device in get_input_device_list()[config.CHOICE_MIC_HOST] if device["name"] == config.CHOICE_MIC_DEVICE][0] - self.mic_energy_recorder = SelectedMicEnergyRecorder(mic_device) - self.mic_energy_recorder.record_into_queue(self.mic_energy_queue) - self.mic_energy_plot_progressbar = thread_fnc(self.progressBar_input_mic_energy_plot) - self.mic_energy_plot_progressbar.daemon = True - self.mic_energy_plot_progressbar.start() + model.startCheckMicEnergy(self.progressBar_input_mic_energy_threshold) self.checkbox_input_mic_threshold_check.configure(state="normal") self.checkbox_input_speaker_threshold_check.configure(state="normal") def mic_threshold_check_stop(self): - if self.mic_energy_recorder != None: - self.mic_energy_recorder.stop() - if self.mic_energy_plot_progressbar != None: - self.mic_energy_plot_progressbar.stop() + model.stopCheckMicEnergy() self.progressBar_input_mic_energy_threshold.set(0) self.checkbox_input_mic_threshold_check.configure(state="normal") self.checkbox_input_speaker_threshold_check.configure(state="normal") @@ -338,13 +307,11 @@ class ToplevelWindowConfig(CTkToplevel): config.INPUT_MIC_WORD_FILTER = word_filter.split(",") else: config.INPUT_MIC_WORD_FILTER = [] - self.parent.keyword_processor = KeywordProcessor() - for f in self.parent.INPUT_MIC_WORD_FILTER: - self.parent.keyword_processor.add_keyword(f) + model.resetKeywordProcessor() + model.addKeywords() def optionmenu_input_speaker_device_callback(self, choice): - speaker_device = [device for device in get_output_device_list() if device["name"] == choice][0] - if get_default_output_device()["index"] == speaker_device["index"]: + if model.checkSpeakerStatus(choice): self.optionmenu_input_speaker_device.set(choice) config.CHOICE_SPEAKER_DEVICE = choice else: @@ -356,45 +323,13 @@ class ToplevelWindowConfig(CTkToplevel): self.optionmenu_input_speaker_voice_language.set(choice) config.INPUT_SPEAKER_VOICE_LANGUAGE = choice - def progressBar_input_speaker_energy_plot(self): - if self.speaker_energy_queue.empty() is False: - energy = self.speaker_energy_queue.get() - try: - self.progressBar_input_speaker_energy_threshold.set(energy/self.MAX_SPEAKER_ENERGY_THRESHOLD) - except: - pass - sleep(0.01) - - def progressBar_input_speaker_energy_get(self): - with self.speaker_energy_recorder.source as source: - energy = self.speaker_energy_recorder.recorder.listen_energy(source) - self.speaker_energy_queue.put(energy) - def speaker_threshold_check_start(self): - speaker_device = [device for device in get_output_device_list() if device["name"] == config.CHOICE_SPEAKER_DEVICE][0] - - if get_default_output_device()["index"] == speaker_device["index"]: - self.speaker_energy_queue = Queue() - self.speaker_energy_recorder = SelectedSpeakeEnergyRecorder(speaker_device) - self.speaker_energy_get_progressbar = thread_fnc(self.progressBar_input_speaker_energy_get) - self.speaker_energy_get_progressbar.daemon = True - self.speaker_energy_get_progressbar.start() - self.speaker_energy_plot_progressbar = thread_fnc(self.progressBar_input_speaker_energy_plot) - self.speaker_energy_plot_progressbar.daemon = True - self.speaker_energy_plot_progressbar.start() - else: - print_textbox(self.parent.textbox_message_log, "Windows playback device and selected device do not match. Change the Windows playback device.", "ERROR") - print_textbox(self.parent.textbox_message_system_log, "Windows playback device and selected device do not match. Change the Windows playback device.", "ERROR") - self.checkbox_input_speaker_threshold_check.deselect() + model.startCheckSpeakerEnergy(self.progressBar_input_speaker_energy_threshold) self.checkbox_input_mic_threshold_check.configure(state="normal") self.checkbox_input_speaker_threshold_check.configure(state="normal") def speaker_threshold_check_stop(self): - if self.speaker_energy_get_progressbar != None: - self.speaker_energy_get_progressbar.stop() - if self.speaker_energy_plot_progressbar != None: - self.speaker_energy_plot_progressbar.stop() - + model.stopCheckSpeakerEnergy() self.progressBar_input_speaker_energy_threshold.set(0) self.checkbox_input_mic_threshold_check.configure(state="normal") self.checkbox_input_speaker_threshold_check.configure(state="normal") @@ -404,9 +339,14 @@ class ToplevelWindowConfig(CTkToplevel): self.checkbox_input_speaker_threshold_check.configure(state="disabled") self.update() if self.checkbox_input_speaker_threshold_check.get(): - th_speaker_threshold_check_start = Thread(target=self.speaker_threshold_check_start) - th_speaker_threshold_check_start.daemon = True - th_speaker_threshold_check_start.start() + if model.checkSpeakerStatus(): + th_speaker_threshold_check_start = Thread(target=self.speaker_threshold_check_start) + th_speaker_threshold_check_start.daemon = True + th_speaker_threshold_check_start.start() + else: + print_textbox(self.parent.textbox_message_log, "Windows playback device and selected device do not match. Change the Windows playback device.", "ERROR") + print_textbox(self.parent.textbox_message_system_log, "Windows playback device and selected device do not match. Change the Windows playback device.", "ERROR") + self.checkbox_input_speaker_threshold_check.deselect() else: th_speaker_threshold_check_stop = Thread(target=self.speaker_threshold_check_stop) th_speaker_threshold_check_stop.daemon = True @@ -436,10 +376,7 @@ class ToplevelWindowConfig(CTkToplevel): def entry_authkey_callback(self, event): value = self.entry_authkey.get() if len(value) > 0: - if self.parent.translator.authentication("DeepL(auth)", value) is True: - auth_keys = config.AUTH_KEYS - auth_keys["DeepL(auth)"] = value - config.AUTH_KEYS = auth_keys + if model.authenticationTranslator(choice_translator="DeepL(auth)", auth_key=value) is True: print_textbox(self.parent.textbox_message_log, "Auth key update completed", "INFO") print_textbox(self.parent.textbox_message_system_log, "Auth key update completed", "INFO") else: @@ -683,7 +620,7 @@ class ToplevelWindowConfig(CTkToplevel): self.label_translation_translator.grid(row=row, column=0, columnspan=1, padx=padx, pady=pady, sticky="nsw") self.optionmenu_translation_translator = CTkOptionMenu( self.tabview_config.tab(config_tab_title_translation), - values=list(self.parent.translator.translator_status.keys()), + values=model.getListTranslatorName(), command=self.optionmenu_translation_translator_callback, variable=StringVar(value=config.CHOICE_TRANSLATOR), font=CTkFont(family=config.FONT_FAMILY), @@ -695,7 +632,7 @@ class ToplevelWindowConfig(CTkToplevel): if SCROLLABLE_DROPDOWN: self.scrollableDropdown_translation_translator = CTkScrollableDropdown( self.optionmenu_translation_translator, - values=list(self.parent.translator.translator_status.keys()), + values=model.getListTranslatorName(), justify="left", button_color="transparent", command=self.optionmenu_translation_translator_callback, @@ -862,7 +799,7 @@ class ToplevelWindowConfig(CTkToplevel): self.label_input_mic_host.grid(row=row, column=0, columnspan=1, padx=padx, pady=pady, sticky="nsw") self.optionmenu_input_mic_host = CTkOptionMenu( self.tabview_config.tab(config_tab_title_transcription), - values=[host for host in get_input_device_list().keys()], + values=model.getListInputHost(), command=self.optionmenu_input_mic_host_callback, variable=StringVar(value=config.CHOICE_MIC_HOST), font=CTkFont(family=config.FONT_FAMILY), @@ -874,7 +811,7 @@ class ToplevelWindowConfig(CTkToplevel): if SCROLLABLE_DROPDOWN: self.scrollableDropdown_input_mic_host = CTkScrollableDropdown( self.optionmenu_input_mic_host, - values=[host for host in get_input_device_list().keys()], + values=model.getListInputHost(), justify="left", button_color="transparent", command=self.optionmenu_input_mic_host_callback, @@ -896,7 +833,7 @@ class ToplevelWindowConfig(CTkToplevel): self.label_input_mic_device.grid(row=row, column=0, columnspan=1, padx=padx, pady=pady, sticky="nsw") self.optionmenu_input_mic_device = CTkOptionMenu( self.tabview_config.tab(config_tab_title_transcription), - values=[device["name"] for device in get_input_device_list()[config.CHOICE_MIC_HOST]], + values=model.getListInputDevice(), command=self.optionmenu_input_mic_device_callback, variable=StringVar(value=config.CHOICE_MIC_DEVICE), font=CTkFont(family=config.FONT_FAMILY), @@ -908,7 +845,7 @@ class ToplevelWindowConfig(CTkToplevel): if SCROLLABLE_DROPDOWN: self.scrollableDropdown_input_mic_device = CTkScrollableDropdown( self.optionmenu_input_mic_device, - values=[device["name"] for device in get_input_device_list()[config.CHOICE_MIC_HOST]], + values=model.getListInputDevice(), justify="left", button_color="transparent", command=self.optionmenu_input_mic_device_callback, @@ -966,11 +903,11 @@ class ToplevelWindowConfig(CTkToplevel): self.slider_input_mic_energy_threshold = CTkSlider( self.tabview_config.tab(config_tab_title_transcription), from_=0, - to=self.MAX_MIC_ENERGY_THRESHOLD, + to=config.MAX_MIC_ENERGY_THRESHOLD, border_width=7, button_length=0, button_corner_radius=3, - number_of_steps=self.MAX_MIC_ENERGY_THRESHOLD, + number_of_steps=config.MAX_MIC_ENERGY_THRESHOLD, command=self.slider_input_mic_energy_threshold_callback, variable=IntVar(value=config.INPUT_MIC_ENERGY_THRESHOLD), ) @@ -1102,7 +1039,7 @@ class ToplevelWindowConfig(CTkToplevel): self.label_input_speaker_device.grid(row=row, column=0, columnspan=1, padx=padx, pady=pady, sticky="nsw") self.optionmenu_input_speaker_device = CTkOptionMenu( self.tabview_config.tab(config_tab_title_transcription), - values=[device["name"] for device in get_output_device_list()], + values=model.getListOutputDevice(), command=self.optionmenu_input_speaker_device_callback, variable=StringVar(value=config.CHOICE_SPEAKER_DEVICE), font=CTkFont(family=config.FONT_FAMILY), @@ -1114,7 +1051,7 @@ class ToplevelWindowConfig(CTkToplevel): if SCROLLABLE_DROPDOWN: self.scrollableDropdown_input_speaker_device = CTkScrollableDropdown( self.optionmenu_input_speaker_device, - values=[device["name"] for device in get_output_device_list()], + values=model.getListOutputDevice(), justify="left", button_color="transparent", command=self.optionmenu_input_speaker_device_callback, @@ -1173,11 +1110,11 @@ class ToplevelWindowConfig(CTkToplevel): self.slider_input_speaker_energy_threshold = CTkSlider( self.tabview_config.tab(config_tab_title_transcription), from_=0, - to=self.MAX_SPEAKER_ENERGY_THRESHOLD, + to=config.MAX_SPEAKER_ENERGY_THRESHOLD, border_width=7, button_length=0, button_corner_radius=3, - number_of_steps=self.MAX_SPEAKER_ENERGY_THRESHOLD, + number_of_steps=config.MAX_SPEAKER_ENERGY_THRESHOLD, command=self.slider_input_speaker_energy_threshold_callback, variable=IntVar(value=config.INPUT_SPEAKER_ENERGY_THRESHOLD), )