Merge branch 'optimization' into develop

This commit is contained in:
misygauziya
2023-07-06 13:53:59 +09:00
8 changed files with 464 additions and 461 deletions

240
VRCT.py
View File

@@ -1,27 +1,29 @@
import os from os import path as os_path
import json from json import load as json_load
import queue from json import dump as json_dump
from queue import Queue
import tkinter as tk import tkinter as tk
import customtkinter import customtkinter
from PIL import Image 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 flashtext import KeywordProcessor
import utils from utils import save_json, print_textbox, thread_fnc
import osc_tools from osc_tools import send_typing, send_message
import window_config from window_config import ToplevelWindowConfig
import window_information from window_information import ToplevelWindowInformation
import languages from languages import transcription_lang, translators, translation_lang
import audio_utils from audio_utils import get_input_device_list, get_output_device_list, get_default_input_device, get_default_output_device
import audio_recorder from audio_recorder import SelectedMicRecorder, SelectedSpeakerRecorder
import audio_transcriber from audio_transcriber import AudioTranscriber
import translation from translation import Translator
class App(customtkinter.CTk): class App(CTk):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
# init instance # init instance
self.translator = translation.Translator() self.translator = Translator()
self.keyword_processor = KeywordProcessor() self.keyword_processor = KeywordProcessor()
# init config # init config
@@ -38,14 +40,14 @@ class App(customtkinter.CTk):
self.UI_SCALING = "100%" self.UI_SCALING = "100%"
self.FONT_FAMILY = "Yu Gothic UI" self.FONT_FAMILY = "Yu Gothic UI"
## Translation ## Translation
self.CHOICE_TRANSLATOR = languages.translators[0] self.CHOICE_TRANSLATOR = translators[0]
self.INPUT_SOURCE_LANG = list(languages.translation_lang[self.CHOICE_TRANSLATOR].keys())[0] self.INPUT_SOURCE_LANG = list(translation_lang[self.CHOICE_TRANSLATOR].keys())[0]
self.INPUT_TARGET_LANG = list(languages.translation_lang[self.CHOICE_TRANSLATOR].keys())[1] self.INPUT_TARGET_LANG = list(translation_lang[self.CHOICE_TRANSLATOR].keys())[1]
self.OUTPUT_SOURCE_LANG = list(languages.translation_lang[self.CHOICE_TRANSLATOR].keys())[1] self.OUTPUT_SOURCE_LANG = list(translation_lang[self.CHOICE_TRANSLATOR].keys())[1]
self.OUTPUT_TARGET_LANG = list(languages.translation_lang[self.CHOICE_TRANSLATOR].keys())[0] self.OUTPUT_TARGET_LANG = list(translation_lang[self.CHOICE_TRANSLATOR].keys())[0]
## Transcription Send ## Transcription Send
self.CHOICE_MIC_DEVICE = audio_utils.get_default_input_device()["name"] self.CHOICE_MIC_DEVICE = get_default_input_device()["name"]
self.INPUT_MIC_VOICE_LANGUAGE = list(languages.transcription_lang.keys())[0] self.INPUT_MIC_VOICE_LANGUAGE = list(transcription_lang.keys())[0]
self.INPUT_MIC_ENERGY_THRESHOLD = 300 self.INPUT_MIC_ENERGY_THRESHOLD = 300
self.INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD = True self.INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD = True
self.INPUT_MIC_RECORD_TIMEOUT = 3 self.INPUT_MIC_RECORD_TIMEOUT = 3
@@ -53,8 +55,8 @@ class App(customtkinter.CTk):
self.INPUT_MIC_MAX_PHRASES = 10 self.INPUT_MIC_MAX_PHRASES = 10
self.INPUT_MIC_WORD_FILTER = [] self.INPUT_MIC_WORD_FILTER = []
## Transcription Receive ## Transcription Receive
self.CHOICE_SPEAKER_DEVICE = audio_utils.get_default_output_device()["name"] self.CHOICE_SPEAKER_DEVICE = get_default_output_device()["name"]
self.INPUT_SPEAKER_VOICE_LANGUAGE = list(languages.transcription_lang.keys())[1] self.INPUT_SPEAKER_VOICE_LANGUAGE = list(transcription_lang.keys())[1]
self.INPUT_SPEAKER_ENERGY_THRESHOLD = 300 self.INPUT_SPEAKER_ENERGY_THRESHOLD = 300
self.INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD = True self.INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD = True
self.INPUT_SPEAKER_RECORD_TIMEOUT = 3 self.INPUT_SPEAKER_RECORD_TIMEOUT = 3
@@ -72,9 +74,9 @@ class App(customtkinter.CTk):
self.MESSAGE_FORMAT = "[message]([translation])" self.MESSAGE_FORMAT = "[message]([translation])"
# load config # load config
if os.path.isfile(self.PATH_CONFIG) is not False: if os_path.isfile(self.PATH_CONFIG) is not False:
with open(self.PATH_CONFIG, 'r') as fp: with open(self.PATH_CONFIG, 'r') as fp:
config = json.load(fp) config = json_load(fp)
# main window # main window
if "ENABLE_TRANSLATION" in config.keys(): if "ENABLE_TRANSLATION" in config.keys():
if type(config["ENABLE_TRANSLATION"]) is bool: if type(config["ENABLE_TRANSLATION"]) is bool:
@@ -109,24 +111,24 @@ class App(customtkinter.CTk):
if config["CHOICE_TRANSLATOR"] in list(self.translator.translator_status.keys()): if config["CHOICE_TRANSLATOR"] in list(self.translator.translator_status.keys()):
self.CHOICE_TRANSLATOR = config["CHOICE_TRANSLATOR"] self.CHOICE_TRANSLATOR = config["CHOICE_TRANSLATOR"]
if "INPUT_SOURCE_LANG" in config.keys(): if "INPUT_SOURCE_LANG" in config.keys():
if config["INPUT_SOURCE_LANG"] in list(languages.translation_lang[self.CHOICE_TRANSLATOR].keys()): if config["INPUT_SOURCE_LANG"] in list(translation_lang[self.CHOICE_TRANSLATOR].keys()):
self.INPUT_SOURCE_LANG = config["INPUT_SOURCE_LANG"] self.INPUT_SOURCE_LANG = config["INPUT_SOURCE_LANG"]
if "INPUT_TARGET_LANG" in config.keys(): if "INPUT_TARGET_LANG" in config.keys():
if config["INPUT_SOURCE_LANG"] in list(languages.translation_lang[self.CHOICE_TRANSLATOR].keys()): if config["INPUT_SOURCE_LANG"] in list(translation_lang[self.CHOICE_TRANSLATOR].keys()):
self.INPUT_TARGET_LANG = config["INPUT_TARGET_LANG"] self.INPUT_TARGET_LANG = config["INPUT_TARGET_LANG"]
if "OUTPUT_SOURCE_LANG" in config.keys(): if "OUTPUT_SOURCE_LANG" in config.keys():
if config["INPUT_SOURCE_LANG"] in list(languages.translation_lang[self.CHOICE_TRANSLATOR].keys()): if config["INPUT_SOURCE_LANG"] in list(translation_lang[self.CHOICE_TRANSLATOR].keys()):
self.OUTPUT_SOURCE_LANG = config["OUTPUT_SOURCE_LANG"] self.OUTPUT_SOURCE_LANG = config["OUTPUT_SOURCE_LANG"]
if "OUTPUT_TARGET_LANG" in config.keys(): if "OUTPUT_TARGET_LANG" in config.keys():
if config["INPUT_SOURCE_LANG"] in list(languages.translation_lang[self.CHOICE_TRANSLATOR].keys()): if config["INPUT_SOURCE_LANG"] in list(translation_lang[self.CHOICE_TRANSLATOR].keys()):
self.OUTPUT_TARGET_LANG = config["OUTPUT_TARGET_LANG"] self.OUTPUT_TARGET_LANG = config["OUTPUT_TARGET_LANG"]
# Transcription # Transcription
if "CHOICE_MIC_DEVICE" in config.keys(): if "CHOICE_MIC_DEVICE" in config.keys():
if config["CHOICE_MIC_DEVICE"] in [device["name"] for device in audio_utils.get_input_device_list()]: if config["CHOICE_MIC_DEVICE"] in [device["name"] for device in get_input_device_list()]:
self.CHOICE_MIC_DEVICE = config["CHOICE_MIC_DEVICE"] self.CHOICE_MIC_DEVICE = config["CHOICE_MIC_DEVICE"]
if "INPUT_MIC_VOICE_LANGUAGE" in config.keys(): if "INPUT_MIC_VOICE_LANGUAGE" in config.keys():
if config["INPUT_MIC_VOICE_LANGUAGE"] in list(languages.transcription_lang.keys()): if config["INPUT_MIC_VOICE_LANGUAGE"] in list(transcription_lang.keys()):
self.INPUT_MIC_VOICE_LANGUAGE = config["INPUT_MIC_VOICE_LANGUAGE"] self.INPUT_MIC_VOICE_LANGUAGE = config["INPUT_MIC_VOICE_LANGUAGE"]
if "INPUT_MIC_ENERGY_THRESHOLD" in config.keys(): if "INPUT_MIC_ENERGY_THRESHOLD" in config.keys():
if type(config["INPUT_MIC_ENERGY_THRESHOLD"]) is int: if type(config["INPUT_MIC_ENERGY_THRESHOLD"]) is int:
@@ -148,10 +150,10 @@ class App(customtkinter.CTk):
self.INPUT_MIC_WORD_FILTER = config["INPUT_MIC_WORD_FILTER"] self.INPUT_MIC_WORD_FILTER = config["INPUT_MIC_WORD_FILTER"]
if "CHOICE_SPEAKER_DEVICE" in config.keys(): if "CHOICE_SPEAKER_DEVICE" in config.keys():
if config["CHOICE_SPEAKER_DEVICE"] in [device["name"] for device in audio_utils.get_output_device_list()]: if config["CHOICE_SPEAKER_DEVICE"] in [device["name"] for device in get_output_device_list()]:
self.CHOICE_SPEAKER_DEVICE = config["CHOICE_SPEAKER_DEVICE"] self.CHOICE_SPEAKER_DEVICE = config["CHOICE_SPEAKER_DEVICE"]
if "INPUT_SPEAKER_VOICE_LANGUAGE" in config.keys(): if "INPUT_SPEAKER_VOICE_LANGUAGE" in config.keys():
if config["INPUT_SPEAKER_VOICE_LANGUAGE"] in list(languages.transcription_lang.keys()): if config["INPUT_SPEAKER_VOICE_LANGUAGE"] in list(transcription_lang.keys()):
self.INPUT_SPEAKER_VOICE_LANGUAGE = config["INPUT_SPEAKER_VOICE_LANGUAGE"] self.INPUT_SPEAKER_VOICE_LANGUAGE = config["INPUT_SPEAKER_VOICE_LANGUAGE"]
if "INPUT_SPEAKER_ENERGY_THRESHOLD" in config.keys(): if "INPUT_SPEAKER_ENERGY_THRESHOLD" in config.keys():
if type(config["INPUT_SPEAKER_ENERGY_THRESHOLD"]) is int: if type(config["INPUT_SPEAKER_ENERGY_THRESHOLD"]) is int:
@@ -221,14 +223,14 @@ class App(customtkinter.CTk):
"AUTH_KEYS": self.AUTH_KEYS, "AUTH_KEYS": self.AUTH_KEYS,
"MESSAGE_FORMAT": self.MESSAGE_FORMAT, "MESSAGE_FORMAT": self.MESSAGE_FORMAT,
} }
json.dump(config, fp, indent=4) json_dump(config, fp, indent=4)
## set UI theme ## set UI theme
customtkinter.set_appearance_mode(self.APPEARANCE_THEME) customtkinter.set_appearance_mode(self.APPEARANCE_THEME)
customtkinter.set_default_color_theme("blue") customtkinter.set_default_color_theme("blue")
# init main window # init main window
self.iconbitmap(os.path.join(os.path.dirname(__file__), "img", "app.ico")) self.iconbitmap(os_path.join(os_path.dirname(__file__), "img", "app.ico"))
self.title("VRCT") self.title("VRCT")
self.geometry(f"{400}x{175}") self.geometry(f"{400}x{175}")
self.minsize(400, 175) self.minsize(400, 175)
@@ -236,84 +238,84 @@ class App(customtkinter.CTk):
self.grid_rowconfigure(0, weight=1) self.grid_rowconfigure(0, weight=1)
# add sidebar left # add sidebar left
self.sidebar_frame = customtkinter.CTkFrame(self, corner_radius=0) self.sidebar_frame = CTkFrame(self, corner_radius=0)
self.sidebar_frame.grid(row=0, column=0, rowspan=4, sticky="nsw") self.sidebar_frame.grid(row=0, column=0, rowspan=4, sticky="nsw")
self.sidebar_frame.grid_rowconfigure(5, weight=1) self.sidebar_frame.grid_rowconfigure(5, weight=1)
# add checkbox translation # add checkbox translation
self.checkbox_translation = customtkinter.CTkCheckBox( self.checkbox_translation = CTkCheckBox(
self.sidebar_frame, self.sidebar_frame,
text="translation", text="translation",
onvalue=True, onvalue=True,
offvalue=False, offvalue=False,
command=self.checkbox_translation_callback, command=self.checkbox_translation_callback,
font=customtkinter.CTkFont(family=self.FONT_FAMILY) font=CTkFont(family=self.FONT_FAMILY)
) )
self.checkbox_translation.grid(row=0, column=0, columnspan=2 ,padx=10, pady=(5, 5), sticky="we") self.checkbox_translation.grid(row=0, column=0, columnspan=2 ,padx=10, pady=(5, 5), sticky="we")
# add checkbox transcription send # add checkbox transcription send
self.checkbox_transcription_send = customtkinter.CTkCheckBox( self.checkbox_transcription_send = CTkCheckBox(
self.sidebar_frame, self.sidebar_frame,
text="voice2chatbox", text="voice2chatbox",
onvalue=True, onvalue=True,
offvalue=False, offvalue=False,
command=self.checkbox_transcription_send_callback, command=self.checkbox_transcription_send_callback,
font=customtkinter.CTkFont(family=self.FONT_FAMILY) font=CTkFont(family=self.FONT_FAMILY)
) )
self.checkbox_transcription_send.grid(row=1, column=0, columnspan=2 ,padx=10, pady=(5, 5), sticky="we") self.checkbox_transcription_send.grid(row=1, column=0, columnspan=2 ,padx=10, pady=(5, 5), sticky="we")
# add checkbox transcription receive # add checkbox transcription receive
self.checkbox_transcription_receive = customtkinter.CTkCheckBox( self.checkbox_transcription_receive = CTkCheckBox(
self.sidebar_frame, self.sidebar_frame,
text="speaker2log", text="speaker2log",
onvalue=True, onvalue=True,
offvalue=False, offvalue=False,
command=self.checkbox_transcription_receive_callback, command=self.checkbox_transcription_receive_callback,
font=customtkinter.CTkFont(family=self.FONT_FAMILY) font=CTkFont(family=self.FONT_FAMILY)
) )
self.checkbox_transcription_receive.grid(row=2, column=0, columnspan=2 ,padx=10, pady=(5, 5), sticky="we") self.checkbox_transcription_receive.grid(row=2, column=0, columnspan=2 ,padx=10, pady=(5, 5), sticky="we")
# add checkbox foreground # add checkbox foreground
self.checkbox_foreground = customtkinter.CTkCheckBox( self.checkbox_foreground = CTkCheckBox(
self.sidebar_frame, self.sidebar_frame,
text="foreground", text="foreground",
onvalue=True, onvalue=True,
offvalue=False, offvalue=False,
command=self.checkbox_foreground_callback, command=self.checkbox_foreground_callback,
font=customtkinter.CTkFont(family=self.FONT_FAMILY) font=CTkFont(family=self.FONT_FAMILY)
) )
self.checkbox_foreground.grid(row=3, column=0, columnspan=2 ,padx=10, pady=(5, 5), sticky="we") self.checkbox_foreground.grid(row=3, column=0, columnspan=2 ,padx=10, pady=(5, 5), sticky="we")
# add button information # add button information
self.button_information = customtkinter.CTkButton( self.button_information = CTkButton(
self.sidebar_frame, self.sidebar_frame,
text="", text="",
width=25, width=25,
command=self.button_information_callback, command=self.button_information_callback,
image=customtkinter.CTkImage(Image.open(os.path.join(os.path.dirname(__file__), "img", "info-icon-white.png"))) image=CTkImage(Image_open(os_path.join(os_path.dirname(__file__), "img", "info-icon-white.png")))
) )
self.button_information.grid(row=5, column=0, padx=(10, 5), pady=(5, 5), sticky="wse") self.button_information.grid(row=5, column=0, padx=(10, 5), pady=(5, 5), sticky="wse")
self.information_window = None self.information_window = None
# add button config # add button config
self.button_config = customtkinter.CTkButton( self.button_config = CTkButton(
self.sidebar_frame, self.sidebar_frame,
text="", text="",
width=25, width=25,
command=self.button_config_callback, command=self.button_config_callback,
image=customtkinter.CTkImage(Image.open(os.path.join(os.path.dirname(__file__), "img", "config-icon-white.png"))) image=CTkImage(Image_open(os_path.join(os_path.dirname(__file__), "img", "config-icon-white.png")))
) )
self.button_config.grid(row=5, column=1, padx=(5, 10), pady=(5, 5), sticky="wse") self.button_config.grid(row=5, column=1, padx=(5, 10), pady=(5, 5), sticky="wse")
self.config_window = None self.config_window = None
# add tabview textbox # add tabview textbox
self.tabview_logs = customtkinter.CTkTabview(master=self) self.tabview_logs = CTkTabview(master=self)
self.tabview_logs.add("log") self.tabview_logs.add("log")
self.tabview_logs.add("send") self.tabview_logs.add("send")
self.tabview_logs.add("receive") self.tabview_logs.add("receive")
self.tabview_logs.add("system") self.tabview_logs.add("system")
self.tabview_logs.grid(row=0, column=1, padx=0, pady=0, sticky="nsew") self.tabview_logs.grid(row=0, column=1, padx=0, pady=0, sticky="nsew")
self.tabview_logs._segmented_button.configure(font=customtkinter.CTkFont(family=self.FONT_FAMILY)) self.tabview_logs._segmented_button.configure(font=CTkFont(family=self.FONT_FAMILY))
self.tabview_logs._segmented_button.grid(sticky="W") self.tabview_logs._segmented_button.grid(sticky="W")
self.tabview_logs.tab("log").grid_rowconfigure(0, weight=1) self.tabview_logs.tab("log").grid_rowconfigure(0, weight=1)
self.tabview_logs.tab("log").grid_columnconfigure(0, weight=1) self.tabview_logs.tab("log").grid_columnconfigure(0, weight=1)
@@ -326,42 +328,42 @@ class App(customtkinter.CTk):
self.tabview_logs.configure(fg_color="transparent") self.tabview_logs.configure(fg_color="transparent")
# add textbox message log # add textbox message log
self.textbox_message_log = customtkinter.CTkTextbox( self.textbox_message_log = CTkTextbox(
self.tabview_logs.tab("log"), self.tabview_logs.tab("log"),
font=customtkinter.CTkFont(family=self.FONT_FAMILY) font=CTkFont(family=self.FONT_FAMILY)
) )
self.textbox_message_log.grid(row=0, column=0, padx=0, pady=0, sticky="nsew") self.textbox_message_log.grid(row=0, column=0, padx=0, pady=0, sticky="nsew")
self.textbox_message_log.configure(state='disabled') self.textbox_message_log.configure(state='disabled')
# add textbox message send log # add textbox message send log
self.textbox_message_send_log = customtkinter.CTkTextbox( self.textbox_message_send_log = CTkTextbox(
self.tabview_logs.tab("send"), self.tabview_logs.tab("send"),
font=customtkinter.CTkFont(family=self.FONT_FAMILY) font=CTkFont(family=self.FONT_FAMILY)
) )
self.textbox_message_send_log.grid(row=0, column=0, padx=0, pady=0, sticky="nsew") self.textbox_message_send_log.grid(row=0, column=0, padx=0, pady=0, sticky="nsew")
self.textbox_message_send_log.configure(state='disabled') self.textbox_message_send_log.configure(state='disabled')
# add textbox message receive log # add textbox message receive log
self.textbox_message_receive_log = customtkinter.CTkTextbox( self.textbox_message_receive_log = CTkTextbox(
self.tabview_logs.tab("receive"), self.tabview_logs.tab("receive"),
font=customtkinter.CTkFont(family=self.FONT_FAMILY) font=CTkFont(family=self.FONT_FAMILY)
) )
self.textbox_message_receive_log.grid(row=0, column=0, padx=0, pady=0, sticky="nsew") self.textbox_message_receive_log.grid(row=0, column=0, padx=0, pady=0, sticky="nsew")
self.textbox_message_receive_log.configure(state='disabled') self.textbox_message_receive_log.configure(state='disabled')
# add textbox message system log # add textbox message system log
self.textbox_message_system_log = customtkinter.CTkTextbox( self.textbox_message_system_log = CTkTextbox(
self.tabview_logs.tab("system"), self.tabview_logs.tab("system"),
font=customtkinter.CTkFont(family=self.FONT_FAMILY) font=CTkFont(family=self.FONT_FAMILY)
) )
self.textbox_message_system_log.grid(row=0, column=0, padx=0, pady=0, sticky="nsew") self.textbox_message_system_log.grid(row=0, column=0, padx=0, pady=0, sticky="nsew")
self.textbox_message_system_log.configure(state='disabled') self.textbox_message_system_log.configure(state='disabled')
# add entry message box # add entry message box
self.entry_message_box = customtkinter.CTkEntry( self.entry_message_box = CTkEntry(
self, self,
placeholder_text="message", placeholder_text="message",
font=customtkinter.CTkFont(family=self.FONT_FAMILY) font=CTkFont(family=self.FONT_FAMILY)
) )
self.entry_message_box.grid(row=1, column=1, columnspan=2, padx=5, pady=(5, 10), sticky="nsew") self.entry_message_box.grid(row=1, column=1, columnspan=2, padx=5, pady=(5, 10), sticky="nsew")
@@ -369,8 +371,8 @@ class App(customtkinter.CTk):
## set translator ## set translator
if self.translator.authentication(self.CHOICE_TRANSLATOR, self.AUTH_KEYS[self.CHOICE_TRANSLATOR]) is False: if self.translator.authentication(self.CHOICE_TRANSLATOR, self.AUTH_KEYS[self.CHOICE_TRANSLATOR]) is False:
# error update Auth key # error update Auth key
utils.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")
utils.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 checkbox enable translation ## set checkbox enable translation
if self.ENABLE_TRANSLATION: if self.ENABLE_TRANSLATION:
@@ -421,7 +423,7 @@ class App(customtkinter.CTk):
def button_config_callback(self): def button_config_callback(self):
if self.config_window is None or not self.config_window.winfo_exists(): if self.config_window is None or not self.config_window.winfo_exists():
self.config_window = window_config.ToplevelWindowConfig(self) self.config_window = ToplevelWindowConfig(self)
self.checkbox_translation.configure(state="disabled") self.checkbox_translation.configure(state="disabled")
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")
@@ -429,41 +431,41 @@ class App(customtkinter.CTk):
def button_information_callback(self): def button_information_callback(self):
if self.information_window is None or not self.information_window.winfo_exists(): if self.information_window is None or not self.information_window.winfo_exists():
self.information_window = window_information.ToplevelWindowInformation(self) self.information_window = ToplevelWindowInformation(self)
self.information_window.focus() self.information_window.focus()
def checkbox_translation_callback(self): def checkbox_translation_callback(self):
self.ENABLE_TRANSLATION = self.checkbox_translation.get() self.ENABLE_TRANSLATION = self.checkbox_translation.get()
if self.ENABLE_TRANSLATION: if self.ENABLE_TRANSLATION:
self.button_config.configure(state="disabled", fg_color=["gray92", "gray14"]) self.button_config.configure(state="disabled", fg_color=["gray92", "gray14"])
utils.print_textbox(self.textbox_message_log, "Start translation", "INFO") print_textbox(self.textbox_message_log, "Start translation", "INFO")
utils.print_textbox(self.textbox_message_system_log, "Start translation", "INFO") print_textbox(self.textbox_message_system_log, "Start translation", "INFO")
else: else:
if ((self.checkbox_translation.get() is False) and if ((self.checkbox_translation.get() is False) and
(self.checkbox_transcription_send.get() is False) and (self.checkbox_transcription_send.get() is False) and
(self.checkbox_transcription_receive.get() is False)): (self.checkbox_transcription_receive.get() is False)):
self.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"]) self.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"])
utils.print_textbox(self.textbox_message_log, "Stop translation", "INFO") print_textbox(self.textbox_message_log, "Stop translation", "INFO")
utils.print_textbox(self.textbox_message_system_log, "Stop translation", "INFO") print_textbox(self.textbox_message_system_log, "Stop translation", "INFO")
utils.save_json(self.PATH_CONFIG, "ENABLE_TRANSLATION", self.ENABLE_TRANSLATION) save_json(self.PATH_CONFIG, "ENABLE_TRANSLATION", self.ENABLE_TRANSLATION)
def checkbox_transcription_send_callback(self): def checkbox_transcription_send_callback(self):
self.ENABLE_TRANSCRIPTION_SEND = self.checkbox_transcription_send.get() self.ENABLE_TRANSCRIPTION_SEND = self.checkbox_transcription_send.get()
if self.ENABLE_TRANSCRIPTION_SEND is True: if self.ENABLE_TRANSCRIPTION_SEND is True:
self.button_config.configure(state="disabled", fg_color=["gray92", "gray14"]) self.button_config.configure(state="disabled", fg_color=["gray92", "gray14"])
self.mic_audio_queue = queue.Queue() self.mic_audio_queue = Queue()
mic_device = [device for device in audio_utils.get_input_device_list() if device["name"] == self.CHOICE_MIC_DEVICE][0] mic_device = [device for device in get_input_device_list() if device["name"] == self.CHOICE_MIC_DEVICE][0]
self.mic_audio_recorder = audio_recorder.SelectedMicRecorder( self.mic_audio_recorder = SelectedMicRecorder(
mic_device, mic_device,
self.INPUT_MIC_ENERGY_THRESHOLD, self.INPUT_MIC_ENERGY_THRESHOLD,
self.INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD, self.INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD,
self.INPUT_MIC_RECORD_TIMEOUT, self.INPUT_MIC_RECORD_TIMEOUT,
) )
self.mic_audio_recorder.record_into_queue(self.mic_audio_queue) self.mic_audio_recorder.record_into_queue(self.mic_audio_queue)
self.mic_transcriber = audio_transcriber.AudioTranscriber( self.mic_transcriber = AudioTranscriber(
speaker=False, speaker=False,
source=self.mic_audio_recorder.source, source=self.mic_audio_recorder.source,
language=languages.transcription_lang[self.INPUT_MIC_VOICE_LANGUAGE], language=transcription_lang[self.INPUT_MIC_VOICE_LANGUAGE],
phrase_timeout=self.INPUT_MIC_PHRASE_TIMEOUT, phrase_timeout=self.INPUT_MIC_PHRASE_TIMEOUT,
max_phrases=self.INPUT_MIC_MAX_PHRASES, max_phrases=self.INPUT_MIC_MAX_PHRASES,
) )
@@ -473,16 +475,16 @@ class App(customtkinter.CTk):
if len(message) > 0: if len(message) > 0:
# word filter # word filter
if len(self.keyword_processor.extract_keywords(message)) != 0: if len(self.keyword_processor.extract_keywords(message)) != 0:
utils.print_textbox(self.textbox_message_log, f"Detect WordFilter :{message}", "INFO") print_textbox(self.textbox_message_log, f"Detect WordFilter :{message}", "INFO")
utils.print_textbox(self.textbox_message_system_log, f"Detect WordFilter :{message}", "INFO") print_textbox(self.textbox_message_system_log, f"Detect WordFilter :{message}", "INFO")
return return
# translate # translate
if self.checkbox_translation.get() is False: if self.checkbox_translation.get() is False:
voice_message = f"{message}" voice_message = f"{message}"
elif self.translator.translator_status[self.CHOICE_TRANSLATOR] is False: elif self.translator.translator_status[self.CHOICE_TRANSLATOR] is False:
utils.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")
utils.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")
voice_message = f"{message}" voice_message = f"{message}"
else: else:
result = self.translator.translate( result = self.translator.translate(
@@ -495,49 +497,49 @@ class App(customtkinter.CTk):
if self.checkbox_transcription_send.get() is True: if self.checkbox_transcription_send.get() is True:
# send OSC message # send OSC message
osc_tools.send_message(voice_message, self.OSC_IP_ADDRESS, self.OSC_PORT) send_message(voice_message, self.OSC_IP_ADDRESS, self.OSC_PORT)
# update textbox message log # update textbox message log
utils.print_textbox(self.textbox_message_log, f"{voice_message}", "SEND") print_textbox(self.textbox_message_log, f"{voice_message}", "SEND")
utils.print_textbox(self.textbox_message_send_log, f"{voice_message}", "SEND") print_textbox(self.textbox_message_send_log, f"{voice_message}", "SEND")
self.mic_print_transcript = utils.thread_fnc(mic_transcript_to_chatbox) self.mic_print_transcript = thread_fnc(mic_transcript_to_chatbox)
self.mic_print_transcript.daemon = True self.mic_print_transcript.daemon = True
self.mic_print_transcript.start() self.mic_print_transcript.start()
utils.print_textbox(self.textbox_message_log, "Start voice2chatbox", "INFO") print_textbox(self.textbox_message_log, "Start voice2chatbox", "INFO")
utils.print_textbox(self.textbox_message_system_log, "Start voice2chatbox", "INFO") print_textbox(self.textbox_message_system_log, "Start voice2chatbox", "INFO")
else: else:
if ((self.checkbox_translation.get() is False) and if ((self.checkbox_translation.get() is False) and
(self.checkbox_transcription_send.get() is False) and (self.checkbox_transcription_send.get() is False) and
(self.checkbox_transcription_receive.get() is False)): (self.checkbox_transcription_receive.get() is False)):
self.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"]) self.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"])
if isinstance(self.mic_print_transcript, utils.thread_fnc): if isinstance(self.mic_print_transcript, thread_fnc):
self.mic_print_transcript.stop() self.mic_print_transcript.stop()
if self.mic_audio_recorder.stop != None: if self.mic_audio_recorder.stop != None:
self.mic_audio_recorder.stop() self.mic_audio_recorder.stop()
self.mic_audio_recorder.stop = None self.mic_audio_recorder.stop = None
utils.print_textbox(self.textbox_message_log, "Stop voice2chatbox", "INFO") print_textbox(self.textbox_message_log, "Stop voice2chatbox", "INFO")
utils.print_textbox(self.textbox_message_system_log, "Stop voice2chatbox", "INFO") print_textbox(self.textbox_message_system_log, "Stop voice2chatbox", "INFO")
utils.save_json(self.PATH_CONFIG, "ENABLE_TRANSCRIPTION_SEND", self.ENABLE_TRANSCRIPTION_SEND) save_json(self.PATH_CONFIG, "ENABLE_TRANSCRIPTION_SEND", self.ENABLE_TRANSCRIPTION_SEND)
def checkbox_transcription_receive_callback(self): def checkbox_transcription_receive_callback(self):
self.ENABLE_TRANSCRIPTION_RECEIVE = self.checkbox_transcription_receive.get() self.ENABLE_TRANSCRIPTION_RECEIVE = self.checkbox_transcription_receive.get()
if self.ENABLE_TRANSCRIPTION_RECEIVE is True: if self.ENABLE_TRANSCRIPTION_RECEIVE is True:
self.button_config.configure(state="disabled", fg_color=["gray92", "gray14"]) self.button_config.configure(state="disabled", fg_color=["gray92", "gray14"])
self.spk_audio_queue = queue.Queue() self.spk_audio_queue = Queue()
spk_device = [device for device in audio_utils.get_output_device_list() if device["name"] == self.CHOICE_SPEAKER_DEVICE][0] spk_device = [device for device in get_output_device_list() if device["name"] == self.CHOICE_SPEAKER_DEVICE][0]
self.spk_audio_recorder = audio_recorder.SelectedSpeakerRecorder( self.spk_audio_recorder = SelectedSpeakerRecorder(
spk_device, spk_device,
self.INPUT_SPEAKER_ENERGY_THRESHOLD, self.INPUT_SPEAKER_ENERGY_THRESHOLD,
self.INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD, self.INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD,
self.INPUT_SPEAKER_RECORD_TIMEOUT, self.INPUT_SPEAKER_RECORD_TIMEOUT,
) )
self.spk_audio_recorder.record_into_queue(self.spk_audio_queue) self.spk_audio_recorder.record_into_queue(self.spk_audio_queue)
self.spk_transcriber = audio_transcriber.AudioTranscriber( self.spk_transcriber = AudioTranscriber(
speaker=True, speaker=True,
source=self.spk_audio_recorder.source, source=self.spk_audio_recorder.source,
language=languages.transcription_lang[self.INPUT_SPEAKER_VOICE_LANGUAGE], language=transcription_lang[self.INPUT_SPEAKER_VOICE_LANGUAGE],
phrase_timeout=self.INPUT_SPEAKER_PHRASE_TIMEOUT, phrase_timeout=self.INPUT_SPEAKER_PHRASE_TIMEOUT,
max_phrases=self.INPUT_SPEAKER_MAX_PHRASES, max_phrases=self.INPUT_SPEAKER_MAX_PHRASES,
) )
@@ -550,8 +552,8 @@ class App(customtkinter.CTk):
if self.checkbox_translation.get() is False: if self.checkbox_translation.get() is False:
voice_message = f"{message}" voice_message = f"{message}"
elif self.translator.translator_status[self.CHOICE_TRANSLATOR] is False: elif self.translator.translator_status[self.CHOICE_TRANSLATOR] is False:
utils.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")
utils.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")
voice_message = f"{message}" voice_message = f"{message}"
else: else:
result = self.translator.translate( result = self.translator.translate(
@@ -562,47 +564,47 @@ class App(customtkinter.CTk):
) )
voice_message = self.MESSAGE_FORMAT.replace("[message]", message).replace("[translation]", result) voice_message = self.MESSAGE_FORMAT.replace("[message]", message).replace("[translation]", result)
# send OSC message # send OSC message
# osc_tools.send_message(voice_message, self.OSC_IP_ADDRESS, self.OSC_PORT) # send_message(voice_message, self.OSC_IP_ADDRESS, self.OSC_PORT)
if self.checkbox_transcription_receive.get() is True: if self.checkbox_transcription_receive.get() is True:
# update textbox message receive log # update textbox message receive log
utils.print_textbox(self.textbox_message_log, f"{voice_message}", "RECEIVE") print_textbox(self.textbox_message_log, f"{voice_message}", "RECEIVE")
utils.print_textbox(self.textbox_message_receive_log, f"{voice_message}", "RECEIVE") print_textbox(self.textbox_message_receive_log, f"{voice_message}", "RECEIVE")
self.spk_print_transcript = utils.thread_fnc(spk_transcript_to_textbox) self.spk_print_transcript = thread_fnc(spk_transcript_to_textbox)
self.spk_print_transcript.daemon = True self.spk_print_transcript.daemon = True
self.spk_print_transcript.start() self.spk_print_transcript.start()
utils.print_textbox(self.textbox_message_log, "Start speaker2log", "INFO") print_textbox(self.textbox_message_log, "Start speaker2log", "INFO")
utils.print_textbox(self.textbox_message_system_log, "Start speaker2log", "INFO") print_textbox(self.textbox_message_system_log, "Start speaker2log", "INFO")
else: else:
if ((self.checkbox_translation.get() is False) and if ((self.checkbox_translation.get() is False) and
(self.checkbox_transcription_send.get() is False) and (self.checkbox_transcription_send.get() is False) and
(self.checkbox_transcription_receive.get() is False)): (self.checkbox_transcription_receive.get() is False)):
self.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"]) self.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"])
if isinstance(self.spk_print_transcript, utils.thread_fnc): if isinstance(self.spk_print_transcript, thread_fnc):
self.spk_print_transcript.stop() self.spk_print_transcript.stop()
if self.spk_audio_recorder.stop != None: if self.spk_audio_recorder.stop != None:
self.spk_audio_recorder.stop() self.spk_audio_recorder.stop()
self.spk_audio_recorder.stop = None self.spk_audio_recorder.stop = None
utils.print_textbox(self.textbox_message_log, "Stop speaker2log", "INFO") print_textbox(self.textbox_message_log, "Stop speaker2log", "INFO")
utils.print_textbox(self.textbox_message_system_log, "Stop speaker2log", "INFO") print_textbox(self.textbox_message_system_log, "Stop speaker2log", "INFO")
utils.save_json(self.PATH_CONFIG, "ENABLE_TRANSCRIPTION_RECEIVE", self.ENABLE_TRANSCRIPTION_RECEIVE) save_json(self.PATH_CONFIG, "ENABLE_TRANSCRIPTION_RECEIVE", self.ENABLE_TRANSCRIPTION_RECEIVE)
def checkbox_foreground_callback(self): def checkbox_foreground_callback(self):
self.ENABLE_FOREGROUND = self.checkbox_foreground.get() self.ENABLE_FOREGROUND = self.checkbox_foreground.get()
if self.ENABLE_FOREGROUND: if self.ENABLE_FOREGROUND:
self.attributes("-topmost", True) self.attributes("-topmost", True)
utils.print_textbox(self.textbox_message_log, "Start foreground", "INFO") print_textbox(self.textbox_message_log, "Start foreground", "INFO")
utils.print_textbox(self.textbox_message_system_log, "Start foreground", "INFO") print_textbox(self.textbox_message_system_log, "Start foreground", "INFO")
else: else:
self.attributes("-topmost", False) self.attributes("-topmost", False)
utils.print_textbox(self.textbox_message_log, "Stop foreground", "INFO") print_textbox(self.textbox_message_log, "Stop foreground", "INFO")
utils.print_textbox(self.textbox_message_system_log, "Stop foreground", "INFO") print_textbox(self.textbox_message_system_log, "Stop foreground", "INFO")
utils.save_json(self.PATH_CONFIG, "ENABLE_FOREGROUND", self.ENABLE_FOREGROUND) save_json(self.PATH_CONFIG, "ENABLE_FOREGROUND", self.ENABLE_FOREGROUND)
def entry_message_box_press_key_enter(self, event): def entry_message_box_press_key_enter(self, event):
# send OSC typing # send OSC typing
osc_tools.send_typing(False, self.OSC_IP_ADDRESS, self.OSC_PORT) send_typing(False, self.OSC_IP_ADDRESS, self.OSC_PORT)
if self.ENABLE_FOREGROUND: if self.ENABLE_FOREGROUND:
self.attributes("-topmost", True) self.attributes("-topmost", True)
@@ -613,8 +615,8 @@ class App(customtkinter.CTk):
if self.checkbox_translation.get() is False: if self.checkbox_translation.get() is False:
chat_message = f"{message}" chat_message = f"{message}"
elif self.translator.translator_status[self.CHOICE_TRANSLATOR] is False: elif self.translator.translator_status[self.CHOICE_TRANSLATOR] is False:
utils.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")
utils.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( result = self.translator.translate(
@@ -626,24 +628,24 @@ class App(customtkinter.CTk):
chat_message = self.MESSAGE_FORMAT.replace("[message]", message).replace("[translation]", result) chat_message = self.MESSAGE_FORMAT.replace("[message]", message).replace("[translation]", result)
# send OSC message # send OSC message
osc_tools.send_message(chat_message, self.OSC_IP_ADDRESS, self.OSC_PORT) send_message(chat_message, self.OSC_IP_ADDRESS, self.OSC_PORT)
# update textbox message log # update textbox message log
utils.print_textbox(self.textbox_message_log, f"{chat_message}", "SEND") print_textbox(self.textbox_message_log, f"{chat_message}", "SEND")
utils.print_textbox(self.textbox_message_send_log, f"{chat_message}", "SEND") print_textbox(self.textbox_message_send_log, f"{chat_message}", "SEND")
# delete message in entry message box # delete message in entry message box
# self.entry_message_box.delete(0, customtkinter.END) # self.entry_message_box.delete(0, customtkinter.END)
def entry_message_box_press_key_any(self, event): def entry_message_box_press_key_any(self, event):
# send OSC typing # send OSC typing
osc_tools.send_typing(True, self.OSC_IP_ADDRESS, self.OSC_PORT) send_typing(True, self.OSC_IP_ADDRESS, self.OSC_PORT)
if self.ENABLE_FOREGROUND: if self.ENABLE_FOREGROUND:
self.attributes("-topmost", False) self.attributes("-topmost", False)
def entry_message_box_leave(self, event): def entry_message_box_leave(self, event):
# send OSC typing # send OSC typing
osc_tools.send_typing(False, self.OSC_IP_ADDRESS, self.OSC_PORT) send_typing(False, self.OSC_IP_ADDRESS, self.OSC_PORT)
if self.ENABLE_FOREGROUND: if self.ENABLE_FOREGROUND:
self.attributes("-topmost", True) self.attributes("-topmost", True)

View File

@@ -1,10 +1,10 @@
import speech_recognition as sr from speech_recognition import Recognizer, Microphone
import pyaudiowpatch as pyaudio from pyaudiowpatch import get_sample_size, paInt16
from datetime import datetime from datetime import datetime
class BaseRecorder: class BaseRecorder:
def __init__(self, source, energy_threshold, dynamic_energy_threshold, record_timeout): def __init__(self, source, energy_threshold, dynamic_energy_threshold, record_timeout):
self.recorder = sr.Recognizer() self.recorder = Recognizer()
self.recorder.energy_threshold = energy_threshold self.recorder.energy_threshold = energy_threshold
self.recorder.dynamic_energy_threshold = dynamic_energy_threshold self.recorder.dynamic_energy_threshold = dynamic_energy_threshold
self.record_timeout = record_timeout self.record_timeout = record_timeout
@@ -20,14 +20,14 @@ class BaseRecorder:
self.recorder.adjust_for_ambient_noise(self.source) self.recorder.adjust_for_ambient_noise(self.source)
def record_into_queue(self, audio_queue): def record_into_queue(self, audio_queue):
def record_callback(_, audio:sr.AudioData) -> None: def record_callback(_, audio):
audio_queue.put((audio.get_raw_data(), datetime.now())) audio_queue.put((audio.get_raw_data(), datetime.now()))
self.stop = self.recorder.listen_in_background(self.source, record_callback, phrase_time_limit=self.record_timeout) self.stop = self.recorder.listen_in_background(self.source, record_callback, phrase_time_limit=self.record_timeout)
class SelectedMicRecorder(BaseRecorder): class SelectedMicRecorder(BaseRecorder):
def __init__(self, device, energy_threshold, dynamic_energy_threshold, record_timeout): def __init__(self, device, energy_threshold, dynamic_energy_threshold, record_timeout):
source=sr.Microphone( source=Microphone(
device_index=device['index'], device_index=device['index'],
sample_rate=int(device["defaultSampleRate"]), sample_rate=int(device["defaultSampleRate"]),
) )
@@ -37,10 +37,10 @@ class SelectedMicRecorder(BaseRecorder):
class SelectedSpeakerRecorder(BaseRecorder): class SelectedSpeakerRecorder(BaseRecorder):
def __init__(self, device, energy_threshold, dynamic_energy_threshold, record_timeout): def __init__(self, device, energy_threshold, dynamic_energy_threshold, record_timeout):
source = sr.Microphone(speaker=True, source = Microphone(speaker=True,
device_index= device["index"], device_index= device["index"],
sample_rate=int(device["defaultSampleRate"]), sample_rate=int(device["defaultSampleRate"]),
chunk_size=pyaudio.get_sample_size(pyaudio.paInt16), chunk_size=get_sample_size(paInt16),
channels=device["maxInputChannels"] channels=device["maxInputChannels"]
) )
super().__init__(source=source, energy_threshold=energy_threshold, dynamic_energy_threshold=dynamic_energy_threshold, record_timeout=record_timeout) super().__init__(source=source, energy_threshold=energy_threshold, dynamic_energy_threshold=dynamic_energy_threshold, record_timeout=record_timeout)

View File

@@ -1,9 +1,9 @@
import io from io import BytesIO
import threading from threading import Event
import wave import wave
import speech_recognition as sr from speech_recognition import Recognizer, AudioData, AudioFile
from datetime import timedelta from datetime import timedelta
import pyaudiowpatch as pyaudio from pyaudiowpatch import get_sample_size, paInt16
PHRASE_TIMEOUT = 3 PHRASE_TIMEOUT = 3
MAX_PHRASES = 10 MAX_PHRASES = 10
@@ -15,8 +15,8 @@ class AudioTranscriber:
self.phrase_timeout = phrase_timeout self.phrase_timeout = phrase_timeout
self.max_phrases = max_phrases self.max_phrases = max_phrases
self.transcript_data = [] self.transcript_data = []
self.transcript_changed_event = threading.Event() self.transcript_changed_event = Event()
self.audio_recognizer = sr.Recognizer() self.audio_recognizer = Recognizer()
self.audio_sources = { self.audio_sources = {
"sample_rate": source.SAMPLE_RATE, "sample_rate": source.SAMPLE_RATE,
"sample_width": source.SAMPLE_WIDTH, "sample_width": source.SAMPLE_WIDTH,
@@ -59,19 +59,18 @@ class AudioTranscriber:
source_info["last_spoken"] = time_spoken source_info["last_spoken"] = time_spoken
def process_mic_data(self): def process_mic_data(self):
audio_data = sr.AudioData(self.audio_sources["last_sample"], self.audio_sources["sample_rate"], self.audio_sources["sample_width"]) audio_data = AudioData(self.audio_sources["last_sample"], self.audio_sources["sample_rate"], self.audio_sources["sample_width"])
return audio_data return audio_data
def process_speaker_data(self): def process_speaker_data(self):
temp_file = io.BytesIO() temp_file = BytesIO()
with wave.open(temp_file, 'wb') as wf: with wave.open(temp_file, 'wb') as wf:
wf.setnchannels(self.audio_sources["channels"]) wf.setnchannels(self.audio_sources["channels"])
p = pyaudio.PyAudio() wf.setsampwidth(get_sample_size(paInt16))
wf.setsampwidth(p.get_sample_size(pyaudio.paInt16))
wf.setframerate(self.audio_sources["sample_rate"]) wf.setframerate(self.audio_sources["sample_rate"])
wf.writeframes(self.audio_sources["last_sample"]) wf.writeframes(self.audio_sources["last_sample"])
temp_file.seek(0) temp_file.seek(0)
with sr.AudioFile(temp_file) as source: with AudioFile(temp_file) as source:
audio = self.audio_recognizer.record(source) audio = self.audio_recognizer.record(source)
return audio return audio

View File

@@ -1,9 +1,9 @@
import pyaudiowpatch as pyaudio from pyaudiowpatch import PyAudio, paWASAPI
def get_input_device_list(): def get_input_device_list():
devices = [] devices = []
with pyaudio.PyAudio() as p: with PyAudio() as p:
wasapi_info = p.get_host_api_info_by_type(pyaudio.paWASAPI) wasapi_info = p.get_host_api_info_by_type(paWASAPI)
for host_index in range(0, p.get_host_api_count()): for host_index in range(0, p.get_host_api_count()):
for device_index in range(0, p. get_host_api_info_by_index(host_index)['deviceCount']): for device_index in range(0, p. get_host_api_info_by_index(host_index)['deviceCount']):
device = p.get_device_info_by_host_api_device_index(host_index, device_index) device = p.get_device_info_by_host_api_device_index(host_index, device_index)
@@ -13,16 +13,16 @@ def get_input_device_list():
def get_output_device_list(): def get_output_device_list():
devices =[] devices =[]
with pyaudio.PyAudio() as p: with PyAudio() as p:
wasapi_info = p.get_host_api_info_by_type(pyaudio.paWASAPI) wasapi_info = p.get_host_api_info_by_type(paWASAPI)
for device in p.get_loopback_device_info_generator(): for device in p.get_loopback_device_info_generator():
if device["hostApi"] == wasapi_info["index"] and device["isLoopbackDevice"] is True: if device["hostApi"] == wasapi_info["index"] and device["isLoopbackDevice"] is True:
devices.append(device) devices.append(device)
return devices return devices
def get_default_input_device(): def get_default_input_device():
with pyaudio.PyAudio() as p: with PyAudio() as p:
wasapi_info = p.get_host_api_info_by_type(pyaudio.paWASAPI) wasapi_info = p.get_host_api_info_by_type(paWASAPI)
defaultInputDevice = wasapi_info["defaultInputDevice"] defaultInputDevice = wasapi_info["defaultInputDevice"]
for host_index in range(0, p.get_host_api_count()): for host_index in range(0, p.get_host_api_count()):
@@ -33,8 +33,8 @@ def get_default_input_device():
return default_device return default_device
def get_default_output_device(): def get_default_output_device():
with pyaudio.PyAudio() as p: with PyAudio() as p:
wasapi_info = p.get_host_api_info_by_type(pyaudio.paWASAPI) wasapi_info = p.get_host_api_info_by_type(paWASAPI)
defaultOutputDevice = wasapi_info["defaultOutputDevice"] defaultOutputDevice = wasapi_info["defaultOutputDevice"]
for host_index in range(0, p.get_host_api_count()): for host_index in range(0, p.get_host_api_count()):

View File

@@ -1,13 +1,13 @@
import deepl from deepl import Translator as deepl_Translator
import deepl_translate from deepl_translate import translate as deepl_web_Translator
import translators as ts from translators import translate_text as other_web_Translator
import languages from languages import translators, translation_lang
# Translator # Translator
class Translator(): class Translator():
def __init__(self): def __init__(self):
self.translator_status = {} self.translator_status = {}
for translator in languages.translators: for translator in translators:
self.translator_status[translator] = False self.translator_status[translator] = False
self.deepl_client = None self.deepl_client = None
@@ -18,7 +18,7 @@ class Translator():
self.translator_status["DeepL(web)"] = True self.translator_status["DeepL(web)"] = True
result = True result = True
elif translator_name == "DeepL(auth)": elif translator_name == "DeepL(auth)":
self.deepl_client = deepl.Translator(authkey) self.deepl_client = deepl_Translator(authkey)
self.deepl_client.translate_text(" ", target_lang="EN-US") self.deepl_client.translate_text(" ", target_lang="EN-US")
self.translator_status["DeepL(auth)"] = True self.translator_status["DeepL(auth)"] = True
result = True result = True
@@ -35,10 +35,10 @@ class Translator():
def translate(self, translator_name, source_language, target_language, message): def translate(self, translator_name, source_language, target_language, message):
result = "" result = ""
try: try:
source_language=languages.translation_lang[translator_name][source_language] source_language=translation_lang[translator_name][source_language]
target_language=languages.translation_lang[translator_name][target_language] target_language=translation_lang[translator_name][target_language]
if translator_name == "DeepL(web)": if translator_name == "DeepL(web)":
result = deepl_translate.translate( result = deepl_web_Translator(
source_language=source_language, source_language=source_language,
target_language=target_language, target_language=target_language,
text=message text=message
@@ -50,14 +50,14 @@ class Translator():
target_lang=target_language, target_lang=target_language,
).text ).text
elif translator_name == "Google(web)": elif translator_name == "Google(web)":
result = ts.translate_text( result = other_web_Translator(
query_text=message, query_text=message,
translator="google", translator="google",
from_language=source_language, from_language=source_language,
to_language=target_language, to_language=target_language,
) )
elif translator_name == "Bing(web)": elif translator_name == "Bing(web)":
result = ts.translate_text( result = other_web_Translator(
query_text=message, query_text=message,
translator="bing", translator="bing",
from_language=source_language, from_language=source_language,

View File

@@ -1,16 +1,16 @@
import json from json import load, dump
import datetime from datetime import datetime
import threading from threading import Thread, Event
def save_json(path, key, value): def save_json(path, key, value):
with open(path, "r") as fp: with open(path, "r") as fp:
json_data = json.load(fp) json_data = load(fp)
json_data[key] = value json_data[key] = value
with open(path, "w") as fp: with open(path, "w") as fp:
json.dump(json_data, fp, indent=4) dump(json_data, fp, indent=4)
def print_textbox(textbox, message, tags=None): def print_textbox(textbox, message, tags=None):
now = datetime.datetime.now() now = datetime.now()
now = now.strftime('%H:%M:%S') now = now.strftime('%H:%M:%S')
textbox.tag_config("ERROR", foreground="#FF0000") textbox.tag_config("ERROR", foreground="#FF0000")
@@ -25,11 +25,11 @@ def print_textbox(textbox, message, tags=None):
textbox.configure(state='disabled') textbox.configure(state='disabled')
textbox.see("end") textbox.see("end")
class thread_fnc(threading.Thread): class thread_fnc(Thread):
def __init__(self, fnc, daemon=True, *args, **kwargs): def __init__(self, fnc, daemon=True, *args, **kwargs):
super(thread_fnc, self).__init__(daemon=daemon, *args, **kwargs) super(thread_fnc, self).__init__(daemon=daemon, *args, **kwargs)
self.fnc = fnc self.fnc = fnc
self._stop = threading.Event() self._stop = Event()
def stop(self): def stop(self):
self._stop.set() self._stop.set()
def stopped(self): def stopped(self):

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
import os import os
import customtkinter from customtkinter import CTkToplevel, CTkTextbox, CTkFont
class ToplevelWindowInformation(customtkinter.CTkToplevel): class ToplevelWindowInformation(CTkToplevel):
def __init__(self, parent, *args, **kwargs): def __init__(self, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs) super().__init__(parent, *args, **kwargs)
self.parent = parent self.parent = parent
@@ -13,9 +13,9 @@ class ToplevelWindowInformation(customtkinter.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("Information") self.title("Information")
# create textbox information # create textbox information
self.textbox_information = customtkinter.CTkTextbox( self.textbox_information = CTkTextbox(
self, self,
font=customtkinter.CTkFont(family=self.parent.FONT_FAMILY) font=CTkFont(family=self.parent.FONT_FAMILY)
) )
self.textbox_information.grid(row=0, column=0, padx=(10, 10), pady=(10, 10), sticky="nsew") self.textbox_information.grid(row=0, column=0, padx=(10, 10), pady=(10, 10), sticky="nsew")
textbox_information_message = """VRCT(v1.2) textbox_information_message = """VRCT(v1.2)