[Update] 要素機能をmodel.pyを通して処理するように変更

This commit is contained in:
misygauziya
2023-08-18 15:39:57 +09:00
parent 19b29b4955
commit 027e9397d5
4 changed files with 445 additions and 299 deletions

240
VRCT.py
View File

@@ -1,35 +1,21 @@
from time import sleep from time import sleep
from os import path as os_path from os import path as os_path
from requests import get as requests_get
from queue import Queue
import customtkinter import customtkinter
from customtkinter import CTk, CTkFrame, CTkCheckBox, CTkFont, CTkButton, CTkImage, CTkTabview, CTkTextbox, CTkEntry from customtkinter import CTk, CTkFrame, CTkCheckBox, CTkFont, CTkButton, CTkImage, CTkTabview, CTkTextbox, CTkEntry
from PIL.Image import open as Image_open from PIL.Image import open as Image_open
from flashtext import KeywordProcessor
from threading import Thread from threading import Thread
from utils import print_textbox, thread_fnc, get_localized_text, widget_main_window_label_setter from utils import print_textbox, get_localized_text, widget_main_window_label_setter
from osc_tools import send_typing, send_message, send_test_action, receive_osc_parameters
from window_config import ToplevelWindowConfig from window_config import ToplevelWindowConfig
from window_information import ToplevelWindowInformation 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 config import config
from notification import notification_xsoverlay_for_vrct from model import model
__version__ = "1.3.2"
class App(CTk): class App(CTk):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
# init instance
self.translator = Translator()
self.keyword_processor = KeywordProcessor()
## set UI theme ## set UI theme
customtkinter.set_appearance_mode(config.APPEARANCE_THEME) customtkinter.set_appearance_mode(config.APPEARANCE_THEME)
customtkinter.set_default_color_theme("blue") customtkinter.set_default_color_theme("blue")
@@ -68,28 +54,16 @@ class App(CTk):
def init_process(self): def init_process(self):
# set translator # 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 # error update Auth key
print_textbox(self.textbox_message_log, "Auth Key or language setting is incorrect", "ERROR") 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") print_textbox(self.textbox_message_system_log, "Auth Key or language setting is incorrect", "ERROR")
# set word filter # set word filter
for f in config.INPUT_MIC_WORD_FILTER: model.addKeywords()
self.keyword_processor.add_keyword(f)
# start receive osc # check OSC started
th_receive_osc_parameters = Thread(target=receive_osc_parameters, args=(self.check_osc_receive,)) model.oscCheck()
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
def button_config_callback(self): def button_config_callback(self):
self.foreground_stop() self.foreground_stop()
@@ -117,7 +91,8 @@ class App(CTk):
self.information_window.focus() self.information_window.focus()
def checkbox_translation_callback(self): 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_log, "Start translation", "INFO")
print_textbox(self.textbox_message_system_log, "Start translation", "INFO") print_textbox(self.textbox_message_system_log, "Start translation", "INFO")
else: else:
@@ -125,61 +100,7 @@ class App(CTk):
print_textbox(self.textbox_message_system_log, "Stop translation", "INFO") print_textbox(self.textbox_message_system_log, "Stop translation", "INFO")
def transcription_send_start(self): def transcription_send_start(self):
self.mic_audio_queue = Queue() model.startMicTranscript(self.textbox_message_log, self.textbox_message_send_log, self.textbox_message_system_log)
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()
print_textbox(self.textbox_message_log, "Start voice2chatbox", "INFO") print_textbox(self.textbox_message_log, "Start voice2chatbox", "INFO")
print_textbox(self.textbox_message_system_log, "Start voice2chatbox", "INFO") print_textbox(self.textbox_message_system_log, "Start voice2chatbox", "INFO")
self.checkbox_transcription_send.configure(state="normal") self.checkbox_transcription_send.configure(state="normal")
@@ -187,12 +108,7 @@ class App(CTk):
self.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"]) self.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"])
def transcription_send_stop(self): def transcription_send_stop(self):
if isinstance(self.mic_print_transcript, thread_fnc): model.stopMicTranscript()
self.mic_print_transcript.stop()
if self.mic_audio_recorder.stop != None:
self.mic_audio_recorder.stop()
self.mic_audio_recorder.stop = None
print_textbox(self.textbox_message_log, "Stop voice2chatbox", "INFO") print_textbox(self.textbox_message_log, "Stop voice2chatbox", "INFO")
print_textbox(self.textbox_message_system_log, "Stop voice2chatbox", "INFO") print_textbox(self.textbox_message_system_log, "Stop voice2chatbox", "INFO")
self.checkbox_transcription_send.configure(state="normal") self.checkbox_transcription_send.configure(state="normal")
@@ -200,20 +116,16 @@ class App(CTk):
self.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"]) self.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"])
def transcription_send_stop_for_config(self): def transcription_send_stop_for_config(self):
if isinstance(self.mic_print_transcript, thread_fnc): model.stopMicTranscript()
self.mic_print_transcript.stop()
if self.mic_audio_recorder.stop != None:
self.mic_audio_recorder.stop()
self.mic_audio_recorder.stop = None
print_textbox(self.textbox_message_log, "Stop voice2chatbox", "INFO") print_textbox(self.textbox_message_log, "Stop voice2chatbox", "INFO")
print_textbox(self.textbox_message_system_log, "Stop voice2chatbox", "INFO") print_textbox(self.textbox_message_system_log, "Stop voice2chatbox", "INFO")
def checkbox_transcription_send_callback(self): 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_send.configure(state="disabled")
self.checkbox_transcription_receive.configure(state="disabled") self.checkbox_transcription_receive.configure(state="disabled")
self.button_config.configure(state="disabled", fg_color=["gray92", "gray14"]) 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 = Thread(target=self.transcription_send_start)
th_transcription_send_start.daemon = True th_transcription_send_start.daemon = True
th_transcription_send_start.start() th_transcription_send_start.start()
@@ -223,54 +135,7 @@ class App(CTk):
th_transcription_send_stop.start() th_transcription_send_stop.start()
def transcription_receive_start(self): def transcription_receive_start(self):
self.spk_audio_queue = Queue() model.startSpeakerTranscript(self.textbox_message_log, self.textbox_message_receive_log, self.textbox_message_system_log)
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()
print_textbox(self.textbox_message_log, "Start speaker2log", "INFO") print_textbox(self.textbox_message_log, "Start speaker2log", "INFO")
print_textbox(self.textbox_message_system_log, "Start speaker2log", "INFO") print_textbox(self.textbox_message_system_log, "Start speaker2log", "INFO")
self.checkbox_transcription_send.configure(state="normal") self.checkbox_transcription_send.configure(state="normal")
@@ -278,12 +143,7 @@ class App(CTk):
self.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"]) self.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"])
def transcription_receive_stop(self): def transcription_receive_stop(self):
if isinstance(self.spk_print_transcript, thread_fnc): model.stopSpeakerTranscript()
self.spk_print_transcript.stop()
if self.spk_audio_recorder.stop != None:
self.spk_audio_recorder.stop()
self.spk_audio_recorder.stop = None
print_textbox(self.textbox_message_log, "Stop speaker2log", "INFO") print_textbox(self.textbox_message_log, "Stop speaker2log", "INFO")
print_textbox(self.textbox_message_system_log, "Stop speaker2log", "INFO") print_textbox(self.textbox_message_system_log, "Stop speaker2log", "INFO")
self.checkbox_transcription_send.configure(state="normal") self.checkbox_transcription_send.configure(state="normal")
@@ -291,20 +151,16 @@ class App(CTk):
self.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"]) self.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"])
def transcription_receive_stop_for_config(self): def transcription_receive_stop_for_config(self):
if isinstance(self.spk_print_transcript, thread_fnc): model.stopSpeakerTranscript()
self.spk_print_transcript.stop()
if self.spk_audio_recorder.stop != None:
self.spk_audio_recorder.stop()
self.spk_audio_recorder.stop = None
print_textbox(self.textbox_message_log, "Stop speaker2log", "INFO") print_textbox(self.textbox_message_log, "Stop speaker2log", "INFO")
print_textbox(self.textbox_message_system_log, "Stop speaker2log", "INFO") print_textbox(self.textbox_message_system_log, "Stop speaker2log", "INFO")
def checkbox_transcription_receive_callback(self): 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_send.configure(state="disabled")
self.checkbox_transcription_receive.configure(state="disabled") self.checkbox_transcription_receive.configure(state="disabled")
self.button_config.configure(state="disabled", fg_color=["gray92", "gray14"]) 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 = Thread(target=self.transcription_receive_start)
th_transcription_receive_start.daemon = True th_transcription_receive_start.daemon = True
th_transcription_receive_start.start() th_transcription_receive_start.start()
@@ -314,28 +170,29 @@ class App(CTk):
th_transcription_receive_stop.start() th_transcription_receive_stop.start()
def transcription_start(self): 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 = Thread(target=self.transcription_send_start)
th_transcription_send_start.daemon = True th_transcription_send_start.daemon = True
th_transcription_send_start.start() th_transcription_send_start.start()
sleep(2) 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 = Thread(target=self.transcription_receive_start)
th_transcription_receive_start.daemon = True th_transcription_receive_start.daemon = True
th_transcription_receive_start.start() th_transcription_receive_start.start()
def transcription_stop(self): 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 = Thread(target=self.transcription_send_stop_for_config)
th_transcription_send_stop.daemon = True th_transcription_send_stop.daemon = True
th_transcription_send_stop.start() 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 = Thread(target=self.transcription_receive_stop_for_config)
th_transcription_receive_stop.daemon = True th_transcription_receive_stop.daemon = True
th_transcription_receive_stop.start() th_transcription_receive_stop.start()
def checkbox_foreground_callback(self): 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) self.attributes("-topmost", True)
print_textbox(self.textbox_message_log, "Start foreground", "INFO") print_textbox(self.textbox_message_log, "Start foreground", "INFO")
print_textbox(self.textbox_message_system_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") print_textbox(self.textbox_message_system_log, "Stop foreground", "INFO")
def foreground_start(self): def foreground_start(self):
if self.checkbox_foreground.get(): if config.ENABLE_FOREGROUND:
self.attributes("-topmost", True) self.attributes("-topmost", True)
print_textbox(self.textbox_message_log, "Start foreground", "INFO") print_textbox(self.textbox_message_log, "Start foreground", "INFO")
print_textbox(self.textbox_message_system_log, "Start foreground", "INFO") print_textbox(self.textbox_message_system_log, "Start foreground", "INFO")
def foreground_stop(self): def foreground_stop(self):
if self.checkbox_foreground.get(): if config.ENABLE_FOREGROUND:
self.attributes("-topmost", False) self.attributes("-topmost", False)
print_textbox(self.textbox_message_log, "Stop foreground", "INFO") print_textbox(self.textbox_message_log, "Stop foreground", "INFO")
print_textbox(self.textbox_message_system_log, "Stop foreground", "INFO") print_textbox(self.textbox_message_system_log, "Stop foreground", "INFO")
def entry_message_box_press_key_enter(self, event): def entry_message_box_press_key_enter(self, event):
# send OSC typing # osc stop send typing
send_typing(False, config.OSC_IP_ADDRESS, config.OSC_PORT) model.oscStopSendTyping()
if self.checkbox_foreground.get(): if config.ENABLE_FOREGROUND:
self.attributes("-topmost", True) self.attributes("-topmost", True)
message = self.entry_message_box.get() message = self.entry_message_box.get()
if len(message) > 0: if len(message) > 0:
# translate # translate
if self.checkbox_translation.get() is False: if config.ENABLE_TRANSLATION is False:
chat_message = f"{message}" 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_log, "Auth Key or language setting is incorrect", "ERROR")
print_textbox(self.textbox_message_system_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}" chat_message = f"{message}"
else: else:
result = self.translator.translate( chat_message = model.getInputTranslate(message)
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)
# send OSC message # send OSC message
if config.ENABLE_OSC is True: if config.ENABLE_OSC is True:
send_message(chat_message, config.OSC_IP_ADDRESS, config.OSC_PORT) model.oscSendMessage(chat_message)
else: else:
print_textbox(self.textbox_message_log, "OSC is not enabled, please enable OSC and rejoin.", "ERROR") 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") 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: if config.ENABLE_AUTO_CLEAR_CHATBOX is True:
self.entry_message_box.delete(0, customtkinter.END) 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): def entry_message_box_press_key_any(self, event):
# send OSC typing # osc start send typing
send_typing(True, config.OSC_IP_ADDRESS, config.OSC_PORT) model.oscStartSendTyping()
if self.checkbox_foreground.get(): if config.ENABLE_FOREGROUND:
self.attributes("-topmost", False) self.attributes("-topmost", False)
if event.keysym != "??": 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) self.entry_message_box.insert("end", event.char)
return "break" return "break"
def entry_message_box_leave(self, event): def entry_message_box_leave(self, event):
# send OSC typing # osc stop send typing
send_typing(False, config.OSC_IP_ADDRESS, config.OSC_PORT) model.oscStopSendTyping()
if self.checkbox_foreground.get(): if config.ENABLE_FOREGROUND:
self.attributes("-topmost", True) self.attributes("-topmost", True)
def delete_window(self): def delete_window(self):
@@ -558,11 +405,6 @@ class App(CTk):
widget_main_window_label_setter(self, language_yaml_data) 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__": if __name__ == "__main__":
try: try:
app = App() app = App()

View File

@@ -18,10 +18,50 @@ class Config:
cls._instance.load_config() cls._instance.load_config()
return cls._instance return cls._instance
@property
def VERSION(self):
return self._VERSION
@property @property
def PATH_CONFIG(self): def PATH_CONFIG(self):
return self._PATH_CONFIG 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 @property
def TRANSPARENCY(self): def TRANSPARENCY(self):
return self._TRANSPARENCY return self._TRANSPARENCY
@@ -371,8 +411,25 @@ class Config:
def GITHUB_URL(self): def GITHUB_URL(self):
return self._GITHUB_URL 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): def init_config(self):
self._VERSION = "1.3.2"
self._PATH_CONFIG = "./config.json" 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._TRANSPARENCY = 100
self._APPEARANCE_THEME = "System" self._APPEARANCE_THEME = "System"
self._UI_SCALING = "100%" self._UI_SCALING = "100%"
@@ -413,6 +470,12 @@ class Config:
self._ENABLE_OSC = False self._ENABLE_OSC = False
self._UPDATE_FLAG = False self._UPDATE_FLAG = False
self._GITHUB_URL = "https://api.github.com/repos/misyaguziya/VRCT/releases/latest" 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): def load_config(self):
if os_path.isfile(self.PATH_CONFIG) is not False: if os_path.isfile(self.PATH_CONFIG) is not False:

304
model.py Normal file
View File

@@ -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()

View File

@@ -1,17 +1,13 @@
from time import sleep
from queue import Queue
from os import path as os_path from os import path as os_path
from tkinter import DoubleVar, IntVar from tkinter import DoubleVar, IntVar
from tkinter import font as tk_font from tkinter import font as tk_font
import customtkinter import customtkinter
from customtkinter import CTkToplevel, CTkTabview, CTkFont, CTkLabel, CTkSlider, CTkOptionMenu, StringVar, CTkEntry, CTkCheckBox, CTkProgressBar from customtkinter import CTkToplevel, CTkTabview, CTkFont, CTkLabel, CTkSlider, CTkOptionMenu, StringVar, CTkEntry, CTkCheckBox, CTkProgressBar
from flashtext import KeywordProcessor
from threading import Thread from threading import Thread
from config import config from config import config
from utils import print_textbox, thread_fnc, get_localized_text, get_key_by_value, widget_config_window_label_setter from model import model
from audio_utils import get_input_device_list, get_output_device_list, get_default_output_device from utils import print_textbox, get_localized_text, get_key_by_value, widget_config_window_label_setter
from audio_recorder import SelectedMicEnergyRecorder, SelectedSpeakeEnergyRecorder
from languages import translation_lang, transcription_lang, selectable_languages from languages import translation_lang, transcription_lang, selectable_languages
from ctk_scrollable_dropdown import CTkScrollableDropdown 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.after(200, lambda: self.iconbitmap(os_path.join(os_path.dirname(__file__), "img", "app.ico")))
self.title("Config") 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 # load ui language data
language_yaml_data = get_localized_text(f"{config.UI_LANGUAGE}") language_yaml_data = get_localized_text(f"{config.UI_LANGUAGE}")
# add tabview config # add tabview config
@@ -202,7 +189,7 @@ class ToplevelWindowConfig(CTkToplevel):
def optionmenu_translation_translator_callback(self, choice): def optionmenu_translation_translator_callback(self, choice):
self.optionmenu_translation_translator.set(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_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") print_textbox(self.parent.textbox_message_system_log, "Auth Key or language setting is incorrect", "ERROR")
else: else:
@@ -253,15 +240,15 @@ class ToplevelWindowConfig(CTkToplevel):
def optionmenu_input_mic_host_callback(self, choice): def optionmenu_input_mic_host_callback(self, choice):
self.optionmenu_input_mic_host.set(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( self.optionmenu_input_mic_device.configure(
values=[device["name"] for device in get_input_device_list()[choice]], values=model.getListInputDevice(),
variable=StringVar(value=[device["name"] for device in get_input_device_list()[choice]][0])) variable=StringVar(value=model.getInputDefaultDevice()))
if SCROLLABLE_DROPDOWN: if SCROLLABLE_DROPDOWN:
self.scrollableDropdown_input_mic_device.configure(values=[device["name"] for device in get_input_device_list()[choice]]) self.scrollableDropdown_input_mic_device.configure(values=model.getListInputDevice())
config.CHOICE_MIC_HOST = choice
config.CHOICE_MIC_DEVICE = [device["name"] for device in get_input_device_list()[choice]][0]
def optionmenu_input_mic_device_callback(self, choice): def optionmenu_input_mic_device_callback(self, choice):
self.optionmenu_input_mic_device.set(choice) self.optionmenu_input_mic_device.set(choice)
@@ -273,31 +260,13 @@ class ToplevelWindowConfig(CTkToplevel):
self.optionmenu_input_mic_voice_language.set(choice) self.optionmenu_input_mic_voice_language.set(choice)
config.INPUT_MIC_VOICE_LANGUAGE = 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): def mic_threshold_check_start(self):
self.mic_energy_queue = Queue() model.startCheckMicEnergy(self.progressBar_input_mic_energy_threshold)
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()
self.checkbox_input_mic_threshold_check.configure(state="normal") self.checkbox_input_mic_threshold_check.configure(state="normal")
self.checkbox_input_speaker_threshold_check.configure(state="normal") self.checkbox_input_speaker_threshold_check.configure(state="normal")
def mic_threshold_check_stop(self): def mic_threshold_check_stop(self):
if self.mic_energy_recorder != None: model.stopCheckMicEnergy()
self.mic_energy_recorder.stop()
if self.mic_energy_plot_progressbar != None:
self.mic_energy_plot_progressbar.stop()
self.progressBar_input_mic_energy_threshold.set(0) self.progressBar_input_mic_energy_threshold.set(0)
self.checkbox_input_mic_threshold_check.configure(state="normal") self.checkbox_input_mic_threshold_check.configure(state="normal")
self.checkbox_input_speaker_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(",") config.INPUT_MIC_WORD_FILTER = word_filter.split(",")
else: else:
config.INPUT_MIC_WORD_FILTER = [] config.INPUT_MIC_WORD_FILTER = []
self.parent.keyword_processor = KeywordProcessor() model.resetKeywordProcessor()
for f in self.parent.INPUT_MIC_WORD_FILTER: model.addKeywords()
self.parent.keyword_processor.add_keyword(f)
def optionmenu_input_speaker_device_callback(self, choice): def optionmenu_input_speaker_device_callback(self, choice):
speaker_device = [device for device in get_output_device_list() if device["name"] == choice][0] if model.checkSpeakerStatus(choice):
if get_default_output_device()["index"] == speaker_device["index"]:
self.optionmenu_input_speaker_device.set(choice) self.optionmenu_input_speaker_device.set(choice)
config.CHOICE_SPEAKER_DEVICE = choice config.CHOICE_SPEAKER_DEVICE = choice
else: else:
@@ -356,45 +323,13 @@ class ToplevelWindowConfig(CTkToplevel):
self.optionmenu_input_speaker_voice_language.set(choice) self.optionmenu_input_speaker_voice_language.set(choice)
config.INPUT_SPEAKER_VOICE_LANGUAGE = 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): def speaker_threshold_check_start(self):
speaker_device = [device for device in get_output_device_list() if device["name"] == config.CHOICE_SPEAKER_DEVICE][0] model.startCheckSpeakerEnergy(self.progressBar_input_speaker_energy_threshold)
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()
self.checkbox_input_mic_threshold_check.configure(state="normal") self.checkbox_input_mic_threshold_check.configure(state="normal")
self.checkbox_input_speaker_threshold_check.configure(state="normal") self.checkbox_input_speaker_threshold_check.configure(state="normal")
def speaker_threshold_check_stop(self): def speaker_threshold_check_stop(self):
if self.speaker_energy_get_progressbar != None: model.stopCheckSpeakerEnergy()
self.speaker_energy_get_progressbar.stop()
if self.speaker_energy_plot_progressbar != None:
self.speaker_energy_plot_progressbar.stop()
self.progressBar_input_speaker_energy_threshold.set(0) self.progressBar_input_speaker_energy_threshold.set(0)
self.checkbox_input_mic_threshold_check.configure(state="normal") self.checkbox_input_mic_threshold_check.configure(state="normal")
self.checkbox_input_speaker_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.checkbox_input_speaker_threshold_check.configure(state="disabled")
self.update() self.update()
if self.checkbox_input_speaker_threshold_check.get(): if self.checkbox_input_speaker_threshold_check.get():
th_speaker_threshold_check_start = Thread(target=self.speaker_threshold_check_start) if model.checkSpeakerStatus():
th_speaker_threshold_check_start.daemon = True th_speaker_threshold_check_start = Thread(target=self.speaker_threshold_check_start)
th_speaker_threshold_check_start.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: else:
th_speaker_threshold_check_stop = Thread(target=self.speaker_threshold_check_stop) th_speaker_threshold_check_stop = Thread(target=self.speaker_threshold_check_stop)
th_speaker_threshold_check_stop.daemon = True th_speaker_threshold_check_stop.daemon = True
@@ -436,10 +376,7 @@ class ToplevelWindowConfig(CTkToplevel):
def entry_authkey_callback(self, event): def entry_authkey_callback(self, event):
value = self.entry_authkey.get() value = self.entry_authkey.get()
if len(value) > 0: if len(value) > 0:
if self.parent.translator.authentication("DeepL(auth)", value) is True: if model.authenticationTranslator(choice_translator="DeepL(auth)", auth_key=value) is True:
auth_keys = config.AUTH_KEYS
auth_keys["DeepL(auth)"] = value
config.AUTH_KEYS = auth_keys
print_textbox(self.parent.textbox_message_log, "Auth key update completed", "INFO") 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") print_textbox(self.parent.textbox_message_system_log, "Auth key update completed", "INFO")
else: 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.label_translation_translator.grid(row=row, column=0, columnspan=1, padx=padx, pady=pady, sticky="nsw")
self.optionmenu_translation_translator = CTkOptionMenu( self.optionmenu_translation_translator = CTkOptionMenu(
self.tabview_config.tab(config_tab_title_translation), 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, command=self.optionmenu_translation_translator_callback,
variable=StringVar(value=config.CHOICE_TRANSLATOR), variable=StringVar(value=config.CHOICE_TRANSLATOR),
font=CTkFont(family=config.FONT_FAMILY), font=CTkFont(family=config.FONT_FAMILY),
@@ -695,7 +632,7 @@ class ToplevelWindowConfig(CTkToplevel):
if SCROLLABLE_DROPDOWN: if SCROLLABLE_DROPDOWN:
self.scrollableDropdown_translation_translator = CTkScrollableDropdown( self.scrollableDropdown_translation_translator = CTkScrollableDropdown(
self.optionmenu_translation_translator, self.optionmenu_translation_translator,
values=list(self.parent.translator.translator_status.keys()), values=model.getListTranslatorName(),
justify="left", justify="left",
button_color="transparent", button_color="transparent",
command=self.optionmenu_translation_translator_callback, 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.label_input_mic_host.grid(row=row, column=0, columnspan=1, padx=padx, pady=pady, sticky="nsw")
self.optionmenu_input_mic_host = CTkOptionMenu( self.optionmenu_input_mic_host = CTkOptionMenu(
self.tabview_config.tab(config_tab_title_transcription), 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, command=self.optionmenu_input_mic_host_callback,
variable=StringVar(value=config.CHOICE_MIC_HOST), variable=StringVar(value=config.CHOICE_MIC_HOST),
font=CTkFont(family=config.FONT_FAMILY), font=CTkFont(family=config.FONT_FAMILY),
@@ -874,7 +811,7 @@ class ToplevelWindowConfig(CTkToplevel):
if SCROLLABLE_DROPDOWN: if SCROLLABLE_DROPDOWN:
self.scrollableDropdown_input_mic_host = CTkScrollableDropdown( self.scrollableDropdown_input_mic_host = CTkScrollableDropdown(
self.optionmenu_input_mic_host, self.optionmenu_input_mic_host,
values=[host for host in get_input_device_list().keys()], values=model.getListInputHost(),
justify="left", justify="left",
button_color="transparent", button_color="transparent",
command=self.optionmenu_input_mic_host_callback, 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.label_input_mic_device.grid(row=row, column=0, columnspan=1, padx=padx, pady=pady, sticky="nsw")
self.optionmenu_input_mic_device = CTkOptionMenu( self.optionmenu_input_mic_device = CTkOptionMenu(
self.tabview_config.tab(config_tab_title_transcription), 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, command=self.optionmenu_input_mic_device_callback,
variable=StringVar(value=config.CHOICE_MIC_DEVICE), variable=StringVar(value=config.CHOICE_MIC_DEVICE),
font=CTkFont(family=config.FONT_FAMILY), font=CTkFont(family=config.FONT_FAMILY),
@@ -908,7 +845,7 @@ class ToplevelWindowConfig(CTkToplevel):
if SCROLLABLE_DROPDOWN: if SCROLLABLE_DROPDOWN:
self.scrollableDropdown_input_mic_device = CTkScrollableDropdown( self.scrollableDropdown_input_mic_device = CTkScrollableDropdown(
self.optionmenu_input_mic_device, self.optionmenu_input_mic_device,
values=[device["name"] for device in get_input_device_list()[config.CHOICE_MIC_HOST]], values=model.getListInputDevice(),
justify="left", justify="left",
button_color="transparent", button_color="transparent",
command=self.optionmenu_input_mic_device_callback, command=self.optionmenu_input_mic_device_callback,
@@ -966,11 +903,11 @@ class ToplevelWindowConfig(CTkToplevel):
self.slider_input_mic_energy_threshold = CTkSlider( self.slider_input_mic_energy_threshold = CTkSlider(
self.tabview_config.tab(config_tab_title_transcription), self.tabview_config.tab(config_tab_title_transcription),
from_=0, from_=0,
to=self.MAX_MIC_ENERGY_THRESHOLD, to=config.MAX_MIC_ENERGY_THRESHOLD,
border_width=7, border_width=7,
button_length=0, button_length=0,
button_corner_radius=3, 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, command=self.slider_input_mic_energy_threshold_callback,
variable=IntVar(value=config.INPUT_MIC_ENERGY_THRESHOLD), 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.label_input_speaker_device.grid(row=row, column=0, columnspan=1, padx=padx, pady=pady, sticky="nsw")
self.optionmenu_input_speaker_device = CTkOptionMenu( self.optionmenu_input_speaker_device = CTkOptionMenu(
self.tabview_config.tab(config_tab_title_transcription), 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, command=self.optionmenu_input_speaker_device_callback,
variable=StringVar(value=config.CHOICE_SPEAKER_DEVICE), variable=StringVar(value=config.CHOICE_SPEAKER_DEVICE),
font=CTkFont(family=config.FONT_FAMILY), font=CTkFont(family=config.FONT_FAMILY),
@@ -1114,7 +1051,7 @@ class ToplevelWindowConfig(CTkToplevel):
if SCROLLABLE_DROPDOWN: if SCROLLABLE_DROPDOWN:
self.scrollableDropdown_input_speaker_device = CTkScrollableDropdown( self.scrollableDropdown_input_speaker_device = CTkScrollableDropdown(
self.optionmenu_input_speaker_device, self.optionmenu_input_speaker_device,
values=[device["name"] for device in get_output_device_list()], values=model.getListOutputDevice(),
justify="left", justify="left",
button_color="transparent", button_color="transparent",
command=self.optionmenu_input_speaker_device_callback, command=self.optionmenu_input_speaker_device_callback,
@@ -1173,11 +1110,11 @@ class ToplevelWindowConfig(CTkToplevel):
self.slider_input_speaker_energy_threshold = CTkSlider( self.slider_input_speaker_energy_threshold = CTkSlider(
self.tabview_config.tab(config_tab_title_transcription), self.tabview_config.tab(config_tab_title_transcription),
from_=0, from_=0,
to=self.MAX_SPEAKER_ENERGY_THRESHOLD, to=config.MAX_SPEAKER_ENERGY_THRESHOLD,
border_width=7, border_width=7,
button_length=0, button_length=0,
button_corner_radius=3, 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, command=self.slider_input_speaker_energy_threshold_callback,
variable=IntVar(value=config.INPUT_SPEAKER_ENERGY_THRESHOLD), variable=IntVar(value=config.INPUT_SPEAKER_ENERGY_THRESHOLD),
) )