diff --git a/VRCT.py b/VRCT.py index cc028db9..b58812d6 100644 --- a/VRCT.py +++ b/VRCT.py @@ -47,7 +47,8 @@ class App(CTk): self.OUTPUT_SOURCE_LANG = list(translation_lang[self.CHOICE_TRANSLATOR].keys())[1] self.OUTPUT_TARGET_LANG = list(translation_lang[self.CHOICE_TRANSLATOR].keys())[0] ## Transcription Send - self.CHOICE_MIC_DEVICE = get_default_input_device()["name"] + self.CHOICE_MIC_HOST = get_default_input_device()["host"]["name"] + self.CHOICE_MIC_DEVICE = get_default_input_device()["device"]["name"] self.INPUT_MIC_VOICE_LANGUAGE = list(transcription_lang.keys())[0] self.INPUT_MIC_ENERGY_THRESHOLD = 300 self.INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD = True @@ -128,8 +129,11 @@ class App(CTk): self.OUTPUT_TARGET_LANG = config["OUTPUT_TARGET_LANG"] # Transcription + if "CHOICE_MIC_HOST" in config.keys(): + if config["CHOICE_MIC_HOST"] in [host for host in get_input_device_list().keys()]: + self.CHOICE_MIC_HOST = config["CHOICE_MIC_HOST"] if "CHOICE_MIC_DEVICE" in config.keys(): - if config["CHOICE_MIC_DEVICE"] in [device["name"] for device in get_input_device_list()]: + if config["CHOICE_MIC_DEVICE"] in [device["name"] for device in get_input_device_list()[self.CHOICE_MIC_HOST]]: self.CHOICE_MIC_DEVICE = config["CHOICE_MIC_DEVICE"] if "INPUT_MIC_VOICE_LANGUAGE" in config.keys(): if config["INPUT_MIC_VOICE_LANGUAGE"] in list(transcription_lang.keys()): @@ -208,6 +212,7 @@ class App(CTk): "INPUT_TARGET_LANG": self.INPUT_TARGET_LANG, "OUTPUT_SOURCE_LANG": self.OUTPUT_SOURCE_LANG, "OUTPUT_TARGET_LANG": self.OUTPUT_TARGET_LANG, + "CHOICE_MIC_HOST": self.CHOICE_MIC_HOST, "CHOICE_MIC_DEVICE": self.CHOICE_MIC_DEVICE, "INPUT_MIC_VOICE_LANGUAGE": self.INPUT_MIC_VOICE_LANGUAGE, "INPUT_MIC_ENERGY_THRESHOLD": self.INPUT_MIC_ENERGY_THRESHOLD, @@ -459,7 +464,7 @@ class App(CTk): if self.ENABLE_TRANSCRIPTION_SEND is True: self.button_config.configure(state="disabled", fg_color=["gray92", "gray14"]) self.mic_audio_queue = Queue() - mic_device = [device for device in get_input_device_list() if device["name"] == self.CHOICE_MIC_DEVICE][0] + mic_device = [device for device in get_input_device_list()[self.CHOICE_MIC_HOST] if device["name"] == self.CHOICE_MIC_DEVICE][0] self.mic_audio_recorder = SelectedMicRecorder( mic_device, self.INPUT_MIC_ENERGY_THRESHOLD, diff --git a/audio_utils.py b/audio_utils.py index b6d0d6e0..b66172c2 100644 --- a/audio_utils.py +++ b/audio_utils.py @@ -1,14 +1,17 @@ from pyaudiowpatch import PyAudio, paWASAPI def get_input_device_list(): - devices = [] + devices = {} with PyAudio() as p: - wasapi_info = p.get_host_api_info_by_type(paWASAPI) 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']): + host = p.get_host_api_info_by_index(host_index) + 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) - if device["hostApi"] == wasapi_info["index"] and device["maxInputChannels"] > 0 and device["isLoopbackDevice"] is False: - devices.append(device) + if device["maxInputChannels"] > 0 and device["isLoopbackDevice"] is False: + if host["name"] in devices.keys(): + devices[host["name"]].append(device) + else: + devices[host["name"]] = [device] return devices def get_output_device_list(): @@ -22,15 +25,15 @@ def get_output_device_list(): def get_default_input_device(): with PyAudio() as p: - wasapi_info = p.get_host_api_info_by_type(paWASAPI) - defaultInputDevice = wasapi_info["defaultInputDevice"] + api_info = p.get_default_host_api_info() + defaultInputDevice = api_info["defaultInputDevice"] for host_index in range(0, p.get_host_api_count()): + host = p.get_host_api_info_by_index(host_index) 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) if device["index"] == defaultInputDevice: - default_device = device - return default_device + return {"host":host, "device": device} def get_default_output_device(): with PyAudio() as p: diff --git a/window_config.py b/window_config.py index cce2a4f5..1587cc62 100644 --- a/window_config.py +++ b/window_config.py @@ -1,6 +1,5 @@ from time import sleep from queue import Queue -from threading import Thread from os import path as os_path from tkinter import DoubleVar, IntVar from tkinter import font as tk_font @@ -239,6 +238,24 @@ class ToplevelWindowConfig(CTkToplevel): row = 0 padx = 5 pady = 1 + self.label_input_mic_host = CTkLabel( + self.tabview_config.tab("Transcription"), + text="Input Mic Host:", + fg_color="transparent", + font=CTkFont(family=self.parent.FONT_FAMILY) + ) + self.label_input_mic_host.grid(row=row, column=0, columnspan=1, padx=padx, pady=pady, sticky="nsw") + self.optionmenu_input_mic_host = CTkOptionMenu( + self.tabview_config.tab("Transcription"), + values=[host for host in get_input_device_list().keys()], + command=self.optionmenu_input_mic_host_callback, + variable=StringVar(value=self.parent.CHOICE_MIC_HOST), + font=CTkFont(family=self.parent.FONT_FAMILY), + ) + self.optionmenu_input_mic_host.grid(row=row, column=1, columnspan=1 ,padx=padx, pady=pady, sticky="nsew") + self.optionmenu_input_mic_host._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY)) + + row += 1 self.label_input_mic_device = CTkLabel( self.tabview_config.tab("Transcription"), text="Input Mic Device:", @@ -248,7 +265,7 @@ class ToplevelWindowConfig(CTkToplevel): self.label_input_mic_device.grid(row=row, column=0, columnspan=1, padx=padx, pady=pady, sticky="nsw") self.optionmenu_input_mic_device = CTkOptionMenu( self.tabview_config.tab("Transcription"), - values=[device["name"] for device in get_input_device_list()], + values=[device["name"] for device in get_input_device_list()[self.parent.CHOICE_MIC_HOST]], command=self.optionmenu_input_mic_device_callback, variable=StringVar(value=self.parent.CHOICE_MIC_DEVICE), font=CTkFont(family=self.parent.FONT_FAMILY), @@ -710,6 +727,9 @@ class ToplevelWindowConfig(CTkToplevel): self.optionmenu_translation_output_target_language._dropdown_menu.configure(font=CTkFont(family=choice)) # tab Transcription + self.label_input_mic_host.configure(font=CTkFont(family=choice)) + self.optionmenu_input_mic_host.configure(font=CTkFont(family=choice)) + self.optionmenu_input_mic_host._dropdown_menu.configure(font=CTkFont(family=choice)) self.label_input_mic_device.configure(font=CTkFont(family=choice)) self.optionmenu_input_mic_device.configure(font=CTkFont(family=choice)) self.optionmenu_input_mic_device._dropdown_menu.configure(font=CTkFont(family=choice)) @@ -822,6 +842,11 @@ class ToplevelWindowConfig(CTkToplevel): self.parent.OUTPUT_TARGET_LANG = choice save_json(self.parent.PATH_CONFIG, "OUTPUT_TARGET_LANG", self.parent.OUTPUT_TARGET_LANG) + def optionmenu_input_mic_host_callback(self, choice): + self.parent.CHOICE_MIC_HOST = choice + save_json(self.parent.PATH_CONFIG, "CHOICE_MIC_HOST", self.parent.CHOICE_MIC_HOST) + self.optionmenu_input_mic_device.configure(values=[device["name"] for device in get_input_device_list()[self.parent.CHOICE_MIC_HOST]]) + def optionmenu_input_mic_device_callback(self, choice): self.parent.CHOICE_MIC_DEVICE = choice save_json(self.parent.PATH_CONFIG, "CHOICE_MIC_DEVICE", self.parent.CHOICE_MIC_DEVICE) @@ -844,7 +869,7 @@ class ToplevelWindowConfig(CTkToplevel): def checkbox_input_mic_threshold_check_callback(self): if self.checkbox_input_mic_threshold_check.get(): self.mic_energy_queue = Queue() - mic_device = [device for device in get_input_device_list() if device["name"] == self.parent.CHOICE_MIC_DEVICE][0] + mic_device = [device for device in get_input_device_list()[self.parent.CHOICE_MIC_HOST] if device["name"] == self.parent.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)