From 2e2c237a269cf0c8ef3b033d5b77dba66a9e355b Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Tue, 16 Apr 2024 10:21:55 +0900 Subject: [PATCH 01/14] =?UTF-8?q?=F0=9F=9A=A7[WIP/TEST]=20Model=20:=20VRCh?= =?UTF-8?q?at=E3=81=A7MUTE=E3=81=AB=E3=81=97=E3=81=9F=E5=A0=B4=E5=90=88?= =?UTF-8?q?=E3=81=AB=E3=83=9E=E3=82=A4=E3=82=AF=E6=96=87=E5=AD=97=E8=B5=B7?= =?UTF-8?q?=E3=81=93=E3=81=97=E3=82=92=E3=81=97=E3=81=AA=E3=81=84=E6=A9=9F?= =?UTF-8?q?=E8=83=BD=E3=82=92=E5=AE=9F=E8=A3=85=EF=BC=88=E9=80=94=E4=B8=AD?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controller.py | 21 +++++++++++++++++++ model.py | 57 +++++++++++++++++++++++++++------------------------ 2 files changed, 51 insertions(+), 27 deletions(-) diff --git a/controller.py b/controller.py index 054f0d6c..880d7708 100644 --- a/controller.py +++ b/controller.py @@ -910,6 +910,24 @@ def callbackSetEnableSendReceivedMessageToVrc(value): # ---------------------Speaker2Chatbox--------------------- +def createDictOSCReceiveParameters(): + osc_parameter_prefix = "/avatar/parameters/" + param_MuteSelf = "MuteSelf" + param_Voice = "Voice" + + def change_handler_muteself(address, osc_arguments): + config.VRCHAT_MUTESELF = osc_arguments + + def change_handler_voice(address, osc_arguments): + config.VRCHAT_MUTESELF = False + + dict_filter_and_target = { + osc_parameter_prefix + param_MuteSelf: change_handler_muteself, + osc_parameter_prefix + param_Voice: change_handler_voice, + } + return dict_filter_and_target + + # Advanced Settings Tab def callbackSetOscIpAddress(value): if value == "": @@ -975,6 +993,9 @@ def createMainWindow(splash): if config.ENABLE_LOGGER is True: model.startLogger() + # init OSC + model.startReceiveOSC(createDictOSCReceiveParameters()) + splash.toProgress(3) # Last one. # set UI and callback diff --git a/model.py b/model.py index 0f844182..9c6e2950 100644 --- a/model.py +++ b/model.py @@ -209,39 +209,42 @@ class Model: def oscSendMessage(message): sendMessage(message, config.OSC_IP_ADDRESS, config.OSC_PORT) - def checkOSCStarted(self, fnc): - self.is_valid_osc = False - def checkOscReceive(address, osc_arguments): - if self.is_valid_osc is False: - self.is_valid_osc = True + # def checkOSCStarted(self, fnc): + # self.is_valid_osc = False + # def checkOscReceive(address, osc_arguments): + # if self.is_valid_osc is False: + # self.is_valid_osc = True - self.listening_server = receiveOscParameters(checkOscReceive) - def oscListener(): - self.listening_server.serve_forever() + # self.listening_server = receiveOscParameters(checkOscReceive) + # def oscListener(): + # self.listening_server.serve_forever() - def sendTestActionLoop(): - for _ in range(10): - sendTestAction() - if self.is_valid_osc is True: - break - sleep(0.1) - self.listening_server.shutdown() + # def sendTestActionLoop(): + # for _ in range(10): + # sendTestAction() + # if self.is_valid_osc is True: + # break + # sleep(0.1) + # self.listening_server.shutdown() - # start receive osc - th_receive_osc_parameters = Thread(target=oscListener) - th_receive_osc_parameters.daemon = True - th_receive_osc_parameters.start() + # # start receive osc + # th_receive_osc_parameters = Thread(target=oscListener) + # th_receive_osc_parameters.daemon = True + # th_receive_osc_parameters.start() - # check osc started - th_send_osc_test_action = Thread(target=sendTestActionLoop) - th_send_osc_test_action.daemon = True - th_send_osc_test_action.start() + # # check osc started + # th_send_osc_test_action = Thread(target=sendTestActionLoop) + # th_send_osc_test_action.daemon = True + # th_send_osc_test_action.start() - th_receive_osc_parameters.join() - th_send_osc_test_action.join() + # th_receive_osc_parameters.join() + # th_send_osc_test_action.join() - if self.is_valid_osc is False: - fnc() + # if self.is_valid_osc is False: + # fnc() + + def startReceiveOSC(self, fnc): + self.listening_server = receiveOscParameters(fnc) @staticmethod def checkSoftwareUpdated(): From 1c19236d62970fb67ac5b0120f66a9e06b7ddc51 Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Tue, 16 Apr 2024 21:44:26 +0900 Subject: [PATCH 02/14] =?UTF-8?q?=F0=9F=91=8D=EF=B8=8F[Update]=20Model=20:?= =?UTF-8?q?=20VRChat=E3=81=AEmute/voice=E3=82=92=E6=A4=9C=E5=87=BA?= =?UTF-8?q?=E3=81=97=E6=96=87=E5=AD=97=E8=B5=B7=E3=81=93=E3=81=97=E3=82=92?= =?UTF-8?q?=E5=81=9C=E6=AD=A2=E3=81=99=E3=82=8B=E6=A9=9F=E8=83=BD=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.py | 12 +++++++ controller.py | 24 +++++++++---- model.py | 80 +++++++++++++++++++++++++++++++++++------ models/osc/osc_tools.py | 6 ++-- 4 files changed, 102 insertions(+), 20 deletions(-) diff --git a/config.py b/config.py index 9e17df87..87efb0d6 100644 --- a/config.py +++ b/config.py @@ -830,6 +830,17 @@ class Config: self._ENABLE_LOGGER = value saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + @property + @json_serializable('ENABLE_MUTE_DETECT') + def ENABLE_MUTE_DETECT(self): + return self._ENABLE_MUTE_DETECT + + @ENABLE_MUTE_DETECT.setter + def ENABLE_MUTE_DETECT(self, value): + if isinstance(value, bool): + self._ENABLE_MUTE_DETECT = value + saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + @property @json_serializable('IS_CONFIG_WINDOW_COMPACT_MODE') def IS_CONFIG_WINDOW_COMPACT_MODE(self): @@ -995,6 +1006,7 @@ class Config: self._ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC = False # Speaker2Chatbox self._ENABLE_SPEAKER2CHATBOX_PASS = "000000000" self._ENABLE_LOGGER = False + self._ENABLE_MUTE_DETECT = False self._IS_CONFIG_WINDOW_COMPACT_MODE = False def load_config(self): diff --git a/controller.py b/controller.py index 880d7708..a5a4dbda 100644 --- a/controller.py +++ b/controller.py @@ -909,20 +909,30 @@ def callbackSetEnableSendReceivedMessageToVrc(value): config.ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC = value # ---------------------Speaker2Chatbox--------------------- - def createDictOSCReceiveParameters(): osc_parameter_prefix = "/avatar/parameters/" param_MuteSelf = "MuteSelf" param_Voice = "Voice" - def change_handler_muteself(address, osc_arguments): - config.VRCHAT_MUTESELF = osc_arguments + def change_handler_mute(address, osc_arguments): + if config.ENABLE_MUTE_DETECT is True: + if osc_arguments is True and change_handler_mute.status_mute is False: + model.stopPutQueueMicAudio() + change_handler_mute.status_mute = True + elif osc_arguments is False and change_handler_mute.status_mute is True: + model.startPutQueueMicAudio() + change_handler_mute.status_mute = False def change_handler_voice(address, osc_arguments): - config.VRCHAT_MUTESELF = False + if config.ENABLE_MUTE_DETECT is True: + if change_handler_mute.status_mute is True: + model.startPutQueueMicAudio() + change_handler_mute.status_mute = False + + change_handler_mute.status_mute = False dict_filter_and_target = { - osc_parameter_prefix + param_MuteSelf: change_handler_muteself, + osc_parameter_prefix + param_MuteSelf: change_handler_mute, osc_parameter_prefix + param_Voice: change_handler_voice, } return dict_filter_and_target @@ -993,8 +1003,8 @@ def createMainWindow(splash): if config.ENABLE_LOGGER is True: model.startLogger() - # init OSC - model.startReceiveOSC(createDictOSCReceiveParameters()) + # init OSC receive + model.startReceiveOSC() splash.toProgress(3) # Last one. diff --git a/model.py b/model.py index 9c6e2950..39a3117d 100644 --- a/model.py +++ b/model.py @@ -17,7 +17,7 @@ from typing import Callable from flashtext import KeywordProcessor from models.translation.translation_translator import Translator from models.transcription.transcription_utils import getInputDevices, getOutputDevices -from models.osc.osc_tools import sendTyping, sendMessage, sendTestAction, receiveOscParameters +from models.osc.osc_tools import sendTyping, sendMessage, receiveOscParameters from models.transcription.transcription_recorder import SelectedMicEnergyAndAudioRecorder, SelectedSpeakerEnergyAndAudioRecorder from models.transcription.transcription_recorder import SelectedMicEnergyRecorder, SelectedSpeakerEnergyRecorder from models.transcription.transcription_transcriber import AudioTranscriber @@ -46,6 +46,18 @@ class threadFnc(Thread): return self.fnc(*self._args, **self._kwargs) +class ConditionalQueue(Queue): + def __init__(self, flag=True, *args, **kwargs): + super().__init__(*args, **kwargs) + self.flag = flag + + def put(self, item, block=True, timeout=None): + if self.flag is True: + super().put(item, block, timeout) + + def set_flag(self, value): + self.flag = value + class Model: _instance = None @@ -67,6 +79,9 @@ class Model: self.speaker_energy_plot_progressbar = None self.translator = Translator() self.keyword_processor = KeywordProcessor() + self.mic_audio_queue = ConditionalQueue() + # self.mic_energy_queue = ConditionalQueue() + self.mute_status = False def checkCTranslatorCTranslate2ModelWeight(self): return checkCTranslate2Weight(config.PATH_LOCAL, config.CTRANSLATE2_WEIGHT_TYPE) @@ -243,8 +258,39 @@ class Model: # if self.is_valid_osc is False: # fnc() - def startReceiveOSC(self, fnc): - self.listening_server = receiveOscParameters(fnc) + # def startReceiveOSC(self, fnc): + # th_osc_server = threadFnc(receiveOscParameters, args=(fnc,)) + # th_osc_server.daemon = True + # th_osc_server.start() + + def startReceiveOSC(self): + osc_parameter_prefix = "/avatar/parameters/" + param_MuteSelf = "MuteSelf" + param_Voice = "Voice" + + def change_handler_mute(address, osc_arguments): + if config.ENABLE_MUTE_DETECT is True: + if osc_arguments is True and self.mute_status is False: + self.stopPutQueueMicAudio() + self.mute_status = True + elif osc_arguments is False and self.mute_status is True: + self.startPutQueueMicAudio() + self.mute_status = False + + def change_handler_voice(address, osc_arguments): + if config.ENABLE_MUTE_DETECT is True: + if self.mute_status is True: + self.startPutQueueMicAudio() + self.mute_status = False + + dict_filter_and_target = { + osc_parameter_prefix + param_MuteSelf: change_handler_mute, + osc_parameter_prefix + param_Voice: change_handler_voice, + } + + th_osc_server = threadFnc(receiveOscParameters, args=(dict_filter_and_target,)) + th_osc_server.daemon = True + th_osc_server.start() @staticmethod def checkSoftwareUpdated(): @@ -321,8 +367,8 @@ class Model: pass return - mic_audio_queue = Queue() - # mic_energy_queue = Queue() + self.mic_audio_queue = ConditionalQueue() + # self.mic_energy_queue = ConditionalQueue() mic_device = choice_mic_device[0] record_timeout = config.INPUT_MIC_RECORD_TIMEOUT phase_timeout = config.INPUT_MIC_PHRASE_TIMEOUT @@ -335,8 +381,8 @@ class Model: dynamic_energy_threshold=config.INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD, record_timeout=record_timeout, ) - # self.mic_audio_recorder.recordIntoQueue(mic_audio_queue, mic_energy_queue) - self.mic_audio_recorder.recordIntoQueue(mic_audio_queue, None) + # self.mic_audio_recorder.recordIntoQueue(self.mic_audio_queue, mic_energy_queue) + self.mic_audio_recorder.recordIntoQueue(self.mic_audio_queue, None) self.mic_transcriber = AudioTranscriber( speaker=False, source=self.mic_audio_recorder.source, @@ -348,15 +394,17 @@ class Model: ) def sendMicTranscript(): try: - self.mic_transcriber.transcribeAudioQueue(mic_audio_queue, config.SOURCE_LANGUAGE, config.SOURCE_COUNTRY) + self.mic_transcriber.transcribeAudioQueue(self.mic_audio_queue, config.SOURCE_LANGUAGE, config.SOURCE_COUNTRY) message = self.mic_transcriber.getTranscript() fnc(message) except Exception: pass def endMicTranscript(): - mic_audio_queue.queue.clear() - # mic_energy_queue.queue.clear() + while not self.mic_audio_queue.empty(): + self.mic_audio_queue.get() + # while not self.mic_energy_queue.empty(): + # self.mic_energy_queue.get() del self.mic_transcriber gc.collect() @@ -378,6 +426,18 @@ class Model: # self.mic_get_energy.daemon = True # self.mic_get_energy.start() + def startPutQueueMicAudio(self): + while not self.mic_audio_queue.empty(): + self.mic_audio_queue.get() + self.mic_audio_queue.set_flag(True) + # self.mic_energy_queue.set_flag(True) + + def stopPutQueueMicAudio(self): + self.mic_audio_queue.set_flag(False) + while not self.mic_audio_queue.empty(): + self.mic_audio_queue.get() + # self.mic_energy_queue.set_flag(False) + def stopMicTranscript(self): if isinstance(self.mic_print_transcript, threadFnc): self.mic_print_transcript.stop() diff --git a/models/osc/osc_tools.py b/models/osc/osc_tools.py index 51608f66..cf9804ac 100644 --- a/models/osc/osc_tools.py +++ b/models/osc/osc_tools.py @@ -1,5 +1,5 @@ from time import sleep -import threading +from threading import Thread from pythonosc import osc_message_builder from pythonosc import udp_client from pythonosc import dispatcher @@ -55,14 +55,14 @@ def receiveOscParameters(dict_filter_and_target, ip_address="127.0.0.1", title=" osc_dispatcher = dispatcher.Dispatcher() for filter, target in dict_filter_and_target.items(): osc_dispatcher.map(filter, target) - osc_udp_server = osc_server.ThreadingOSCUDPServer((ip_address, osc_port), osc_dispatcher) - threading.Thread(target=osc_udp_server.serve_forever, daemon = True).start() osc_client = OSCQueryService(title, http_port, osc_port) for filter, target in dict_filter_and_target.items(): osc_client.advertise_endpoint(filter) + osc_udp_server.serve_forever() + if __name__ == "__main__": osc_parameter_prefix = "/avatar/parameters/" osc_avatar_change_path = "/avatar/change" From 497de5bcff7bb9a92cad17b47453821484b3963b Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Tue, 16 Apr 2024 21:46:27 +0900 Subject: [PATCH 03/14] =?UTF-8?q?=F0=9F=97=91=EF=B8=8F[Remove]=20Model=20:?= =?UTF-8?q?=20OSC=20Receive=E3=81=AB=E3=81=A4=E3=81=84=E3=81=A6=E4=B8=8D?= =?UTF-8?q?=E8=A6=81=E3=81=AA=E3=82=B3=E3=83=BC=E3=83=89=E3=82=92=E5=89=8A?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model.py | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/model.py b/model.py index 39a3117d..700e5f0e 100644 --- a/model.py +++ b/model.py @@ -224,45 +224,6 @@ class Model: def oscSendMessage(message): sendMessage(message, config.OSC_IP_ADDRESS, config.OSC_PORT) - # def checkOSCStarted(self, fnc): - # self.is_valid_osc = False - # def checkOscReceive(address, osc_arguments): - # if self.is_valid_osc is False: - # self.is_valid_osc = True - - # self.listening_server = receiveOscParameters(checkOscReceive) - # def oscListener(): - # self.listening_server.serve_forever() - - # def sendTestActionLoop(): - # for _ in range(10): - # sendTestAction() - # if self.is_valid_osc is True: - # break - # sleep(0.1) - # self.listening_server.shutdown() - - # # start receive osc - # th_receive_osc_parameters = Thread(target=oscListener) - # th_receive_osc_parameters.daemon = True - # th_receive_osc_parameters.start() - - # # check osc started - # th_send_osc_test_action = Thread(target=sendTestActionLoop) - # th_send_osc_test_action.daemon = True - # th_send_osc_test_action.start() - - # th_receive_osc_parameters.join() - # th_send_osc_test_action.join() - - # if self.is_valid_osc is False: - # fnc() - - # def startReceiveOSC(self, fnc): - # th_osc_server = threadFnc(receiveOscParameters, args=(fnc,)) - # th_osc_server.daemon = True - # th_osc_server.start() - def startReceiveOSC(self): osc_parameter_prefix = "/avatar/parameters/" param_MuteSelf = "MuteSelf" From cc7e21a6095751f6f828a4b7a1b73c599e6c5c38 Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Wed, 1 May 2024 20:05:33 +0900 Subject: [PATCH 04/14] [Update] Config Window: Add switch function. VRChat Mic Mute Sync. --- controller.py | 5 +++++ locales/en.yml | 4 ++++ locales/ja.yml | 5 +++++ view.py | 7 +++++++ .../setting_box_others/createSettingBox_Others.py | 14 ++++++++++++++ 5 files changed, 35 insertions(+) diff --git a/controller.py b/controller.py index a5a4dbda..455cbfb7 100644 --- a/controller.py +++ b/controller.py @@ -855,6 +855,10 @@ def callbackSetEnableAutoExportMessageLogs(value): else: model.stopLogger() +def callbackSetEnableVrcMicMuteSync(value): + print("callbackSetEnableVrcMicMuteSync", value) + config.ENABLE_MUTE_DETECT = value + def callbackSetEnableSendMessageToVrc(value): print("callbackSetEnableSendMessageToVrc", value) config.ENABLE_SEND_MESSAGE_TO_VRC = value @@ -1103,6 +1107,7 @@ def createMainWindow(splash): "callback_set_send_message_button_type": callbackSetSendMessageButtonType, "callback_set_enable_notice_xsoverlay": callbackSetEnableNoticeXsoverlay, "callback_set_enable_auto_export_message_logs": callbackSetEnableAutoExportMessageLogs, + "callback_set_enable_vrc_mic_mute_sync": callbackSetEnableVrcMicMuteSync, "callback_set_enable_send_message_to_vrc": callbackSetEnableSendMessageToVrc, # Others(Message Formats(Send) "callback_set_send_message_format": callbackSetSendMessageFormat, diff --git a/locales/en.yml b/locales/en.yml index 8199c81d..48c861e1 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -224,6 +224,10 @@ config_window: label: Auto Export Message Logs desc: Automatically export the conversation messages as a text file. + vrc_mic_mute_sync: + label: VRChat Mic Mute Sync + desc: VRCT will not send the message to VRChat while VRChat's mic is muted. + send_message_to_vrc: label: Send Message To VRChat desc: There is a way to use it without sending messages to VRChat, but it is not supported. Enable this feature when you intend to send a message to VRChat. diff --git a/locales/ja.yml b/locales/ja.yml index 2c0fd2be..009d68f1 100644 --- a/locales/ja.yml +++ b/locales/ja.yml @@ -224,6 +224,11 @@ config_window: label: 会話ログを自動的に保存する desc: テキストファイルとしてログがlogsフォルダ内に保存されます。 + vrc_mic_mute_sync: + label: VRChatマイクミュート同期機能 + desc: VRChatのマイクがミュートされている間は、メッセージをVRChatに送信しません。 + + send_message_to_vrc: label: VRChatにメッセージを送信する desc: "サポート対象外ですが、VRChatにメッセージを送信せずに使う方法があります。送信したい場合、この機能を有効にする事を忘れないでください。" diff --git a/view.py b/view.py index a7466fa8..56858a4f 100644 --- a/view.py +++ b/view.py @@ -446,6 +446,12 @@ class View(): VAR_ENABLE_AUTO_EXPORT_MESSAGE_LOGS=BooleanVar(value=config.ENABLE_LOGGER), + VAR_LABEL_ENABLE_VRC_MIC_MUTE_SYNC=StringVar(value=i18n.t("config_window.vrc_mic_mute_sync.label")), + VAR_DESC_ENABLE_VRC_MIC_MUTE_SYNC=StringVar(value=i18n.t("config_window.vrc_mic_mute_sync.desc")), + CALLBACK_SET_ENABLE_VRC_MIC_MUTE_SYNC=None, + VAR_ENABLE_VRC_MIC_MUTE_SYNC=BooleanVar(value=config.ENABLE_MUTE_DETECT), + + VAR_LABEL_ENABLE_SEND_MESSAGE_TO_VRC=StringVar(value=i18n.t("config_window.send_message_to_vrc.label")), VAR_DESC_ENABLE_SEND_MESSAGE_TO_VRC=StringVar(value=i18n.t("config_window.send_message_to_vrc.desc")), CALLBACK_SET_ENABLE_SEND_MESSAGE_TO_VRC=None, @@ -684,6 +690,7 @@ class View(): self.view_variable.CALLBACK_SET_ENABLE_NOTICE_XSOVERLAY=config_window_registers.get("callback_set_enable_notice_xsoverlay", None) self.view_variable.CALLBACK_SET_ENABLE_AUTO_EXPORT_MESSAGE_LOGS=config_window_registers.get("callback_set_enable_auto_export_message_logs", None) + self.view_variable.CALLBACK_SET_ENABLE_VRC_MIC_MUTE_SYNC=config_window_registers.get("callback_set_enable_vrc_mic_mute_sync", None) self.view_variable.CALLBACK_SET_ENABLE_SEND_MESSAGE_TO_VRC=config_window_registers.get("callback_set_enable_send_message_to_vrc", None) self.view_variable.CALLBACK_SET_SEND_MESSAGE_FORMAT=config_window_registers.get("callback_set_send_message_format", None) diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_others/createSettingBox_Others.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_others/createSettingBox_Others.py index b32116fe..4348c2db 100644 --- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_others/createSettingBox_Others.py +++ b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_others/createSettingBox_Others.py @@ -27,6 +27,9 @@ def createSettingBox_Others(setting_box_wrapper, config_window, settings, view_v def buttonAutoExportMessageLogsCallback(): callFunctionIfCallable(view_variable.CALLBACK_OPEN_FILEPATH_LOGS) + def checkboxVrcMuteSyncCallback(checkbox_box_widget): + callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_VRC_MIC_MUTE_SYNC, checkbox_box_widget.get()) + def checkboxEnableSendMessageToVrcCallback(checkbox_box_widget): callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_SEND_MESSAGE_TO_VRC, checkbox_box_widget.get()) @@ -86,6 +89,17 @@ def createSettingBox_Others(setting_box_wrapper, config_window, settings, view_v row+=1 + config_window.sb__vrc_mic_mute_sync = createSettingBoxCheckbox( + for_var_label_text=view_variable.VAR_LABEL_ENABLE_VRC_MIC_MUTE_SYNC, + for_var_desc_text=view_variable.VAR_DESC_ENABLE_VRC_MIC_MUTE_SYNC, + checkbox_attr_name="sb__checkbox_vrc_mic_mute_sync", + command=lambda: checkboxVrcMuteSyncCallback(config_window.sb__checkbox_vrc_mic_mute_sync), + variable=view_variable.VAR_ENABLE_VRC_MIC_MUTE_SYNC, + ) + config_window.sb__vrc_mic_mute_sync.grid(row=row) + row+=1 + + config_window.sb__enable_send_message_to_vrc = createSettingBoxCheckbox( for_var_label_text=view_variable.VAR_LABEL_ENABLE_SEND_MESSAGE_TO_VRC, for_var_desc_text=view_variable.VAR_DESC_ENABLE_SEND_MESSAGE_TO_VRC, From bd0a0e45921b841851ada910a0947a18c318d11f Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Thu, 2 May 2024 14:25:21 +0900 Subject: [PATCH 05/14] =?UTF-8?q?[Chore]=20=E5=A4=89=E6=95=B0=E5=90=8D?= =?UTF-8?q?=E5=A4=89=E6=9B=B4:=20config.ENABLE=5FMUTE=5FDETECT=20->=20conf?= =?UTF-8?q?ig.ENABLE=5FVRC=5FMIC=5FMUTE=5FSYNC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.py | 14 +++++++------- controller.py | 6 +++--- model.py | 4 ++-- view.py | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/config.py b/config.py index 87efb0d6..8fd1942e 100644 --- a/config.py +++ b/config.py @@ -831,14 +831,14 @@ class Config: saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) @property - @json_serializable('ENABLE_MUTE_DETECT') - def ENABLE_MUTE_DETECT(self): - return self._ENABLE_MUTE_DETECT + @json_serializable('ENABLE_VRC_MIC_MUTE_SYNC') + def ENABLE_VRC_MIC_MUTE_SYNC(self): + return self._ENABLE_VRC_MIC_MUTE_SYNC - @ENABLE_MUTE_DETECT.setter - def ENABLE_MUTE_DETECT(self, value): + @ENABLE_VRC_MIC_MUTE_SYNC.setter + def ENABLE_VRC_MIC_MUTE_SYNC(self, value): if isinstance(value, bool): - self._ENABLE_MUTE_DETECT = value + self._ENABLE_VRC_MIC_MUTE_SYNC = value saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) @property @@ -1006,7 +1006,7 @@ class Config: self._ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC = False # Speaker2Chatbox self._ENABLE_SPEAKER2CHATBOX_PASS = "000000000" self._ENABLE_LOGGER = False - self._ENABLE_MUTE_DETECT = False + self._ENABLE_VRC_MIC_MUTE_SYNC = False self._IS_CONFIG_WINDOW_COMPACT_MODE = False def load_config(self): diff --git a/controller.py b/controller.py index 455cbfb7..6f4f586c 100644 --- a/controller.py +++ b/controller.py @@ -857,7 +857,7 @@ def callbackSetEnableAutoExportMessageLogs(value): def callbackSetEnableVrcMicMuteSync(value): print("callbackSetEnableVrcMicMuteSync", value) - config.ENABLE_MUTE_DETECT = value + config.ENABLE_VRC_MIC_MUTE_SYNC = value def callbackSetEnableSendMessageToVrc(value): print("callbackSetEnableSendMessageToVrc", value) @@ -919,7 +919,7 @@ def createDictOSCReceiveParameters(): param_Voice = "Voice" def change_handler_mute(address, osc_arguments): - if config.ENABLE_MUTE_DETECT is True: + if config.ENABLE_VRC_MIC_MUTE_SYNC is True: if osc_arguments is True and change_handler_mute.status_mute is False: model.stopPutQueueMicAudio() change_handler_mute.status_mute = True @@ -928,7 +928,7 @@ def createDictOSCReceiveParameters(): change_handler_mute.status_mute = False def change_handler_voice(address, osc_arguments): - if config.ENABLE_MUTE_DETECT is True: + if config.ENABLE_VRC_MIC_MUTE_SYNC is True: if change_handler_mute.status_mute is True: model.startPutQueueMicAudio() change_handler_mute.status_mute = False diff --git a/model.py b/model.py index 700e5f0e..8bf62554 100644 --- a/model.py +++ b/model.py @@ -230,7 +230,7 @@ class Model: param_Voice = "Voice" def change_handler_mute(address, osc_arguments): - if config.ENABLE_MUTE_DETECT is True: + if config.ENABLE_VRC_MIC_MUTE_SYNC is True: if osc_arguments is True and self.mute_status is False: self.stopPutQueueMicAudio() self.mute_status = True @@ -239,7 +239,7 @@ class Model: self.mute_status = False def change_handler_voice(address, osc_arguments): - if config.ENABLE_MUTE_DETECT is True: + if config.ENABLE_VRC_MIC_MUTE_SYNC is True: if self.mute_status is True: self.startPutQueueMicAudio() self.mute_status = False diff --git a/view.py b/view.py index 56858a4f..38cfaae2 100644 --- a/view.py +++ b/view.py @@ -449,7 +449,7 @@ class View(): VAR_LABEL_ENABLE_VRC_MIC_MUTE_SYNC=StringVar(value=i18n.t("config_window.vrc_mic_mute_sync.label")), VAR_DESC_ENABLE_VRC_MIC_MUTE_SYNC=StringVar(value=i18n.t("config_window.vrc_mic_mute_sync.desc")), CALLBACK_SET_ENABLE_VRC_MIC_MUTE_SYNC=None, - VAR_ENABLE_VRC_MIC_MUTE_SYNC=BooleanVar(value=config.ENABLE_MUTE_DETECT), + VAR_ENABLE_VRC_MIC_MUTE_SYNC=BooleanVar(value=config.ENABLE_VRC_MIC_MUTE_SYNC), VAR_LABEL_ENABLE_SEND_MESSAGE_TO_VRC=StringVar(value=i18n.t("config_window.send_message_to_vrc.label")), From 047a3a35bfd4d09518dc969d59af162c130fe719 Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Mon, 6 May 2024 16:57:15 +0900 Subject: [PATCH 06/14] =?UTF-8?q?=F0=9F=91=8D=EF=B8=8F[Update]=20Model=20:?= =?UTF-8?q?=20OSC=20Parameter=E3=82=92=E8=83=BD=E5=8B=95=E7=9A=84=E3=81=AB?= =?UTF-8?q?=E5=8F=96=E5=BE=97=E3=81=99=E3=82=8B=E5=87=A6=E7=90=86=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0/mute=E5=90=8C=E6=9C=9F=E6=A9=9F=E8=83=BD?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model.py | 37 +++++++++++++++++-------------------- models/osc/osc_tools.py | 9 ++++++++- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/model.py b/model.py index 700e5f0e..d393759f 100644 --- a/model.py +++ b/model.py @@ -17,7 +17,7 @@ from typing import Callable from flashtext import KeywordProcessor from models.translation.translation_translator import Translator from models.transcription.transcription_utils import getInputDevices, getOutputDevices -from models.osc.osc_tools import sendTyping, sendMessage, receiveOscParameters +from models.osc.osc_tools import sendTyping, sendMessage, receiveOscParameters, getOSCParameterValue from models.transcription.transcription_recorder import SelectedMicEnergyAndAudioRecorder, SelectedSpeakerEnergyAndAudioRecorder from models.transcription.transcription_recorder import SelectedMicEnergyRecorder, SelectedSpeakerEnergyRecorder from models.transcription.transcription_transcriber import AudioTranscriber @@ -79,8 +79,7 @@ class Model: self.speaker_energy_plot_progressbar = None self.translator = Translator() self.keyword_processor = KeywordProcessor() - self.mic_audio_queue = ConditionalQueue() - # self.mic_energy_queue = ConditionalQueue() + self.mic_audio_queue = None self.mute_status = False def checkCTranslatorCTranslate2ModelWeight(self): @@ -227,7 +226,7 @@ class Model: def startReceiveOSC(self): osc_parameter_prefix = "/avatar/parameters/" param_MuteSelf = "MuteSelf" - param_Voice = "Voice" + self.mute_status = getOSCParameterValue(address=osc_parameter_prefix + param_MuteSelf) def change_handler_mute(address, osc_arguments): if config.ENABLE_MUTE_DETECT is True: @@ -238,18 +237,11 @@ class Model: self.startPutQueueMicAudio() self.mute_status = False - def change_handler_voice(address, osc_arguments): - if config.ENABLE_MUTE_DETECT is True: - if self.mute_status is True: - self.startPutQueueMicAudio() - self.mute_status = False - dict_filter_and_target = { osc_parameter_prefix + param_MuteSelf: change_handler_mute, - osc_parameter_prefix + param_Voice: change_handler_voice, } - th_osc_server = threadFnc(receiveOscParameters, args=(dict_filter_and_target,)) + th_osc_server = Thread(target=receiveOscParameters, args=(dict_filter_and_target,)) th_osc_server.daemon = True th_osc_server.start() @@ -330,6 +322,9 @@ class Model: self.mic_audio_queue = ConditionalQueue() # self.mic_energy_queue = ConditionalQueue() + if config.ENABLE_MUTE_DETECT is True and self.mute_status is True: + model.stopPutQueueMicAudio() + mic_device = choice_mic_device[0] record_timeout = config.INPUT_MIC_RECORD_TIMEOUT phase_timeout = config.INPUT_MIC_PHRASE_TIMEOUT @@ -388,16 +383,18 @@ class Model: # self.mic_get_energy.start() def startPutQueueMicAudio(self): - while not self.mic_audio_queue.empty(): - self.mic_audio_queue.get() - self.mic_audio_queue.set_flag(True) - # self.mic_energy_queue.set_flag(True) + if isinstance(self.mic_audio_queue, ConditionalQueue): + while not self.mic_audio_queue.empty(): + self.mic_audio_queue.get() + self.mic_audio_queue.set_flag(True) + # self.mic_energy_queue.set_flag(True) def stopPutQueueMicAudio(self): - self.mic_audio_queue.set_flag(False) - while not self.mic_audio_queue.empty(): - self.mic_audio_queue.get() - # self.mic_energy_queue.set_flag(False) + if isinstance(self.mic_audio_queue, ConditionalQueue): + self.mic_audio_queue.set_flag(False) + while not self.mic_audio_queue.empty(): + self.mic_audio_queue.get() + # self.mic_energy_queue.set_flag(False) def stopMicTranscript(self): if isinstance(self.mic_print_transcript, threadFnc): diff --git a/models/osc/osc_tools.py b/models/osc/osc_tools.py index cf9804ac..e7aa7d23 100644 --- a/models/osc/osc_tools.py +++ b/models/osc/osc_tools.py @@ -1,10 +1,10 @@ from time import sleep -from threading import Thread from pythonosc import osc_message_builder from pythonosc import udp_client from pythonosc import dispatcher from pythonosc import osc_server from tinyoscquery.queryservice import OSCQueryService +from tinyoscquery.query import OSCQueryBrowser, OSCQueryClient from tinyoscquery.utility import get_open_udp_port, get_open_tcp_port # send OSC message typing @@ -48,6 +48,13 @@ def sendChangeVoice(ip_address="127.0.0.1", port=9000): sendInputVoice(flag=0, ip_address=ip_address, port=port) sleep(0.05) +def getOSCParameterValue(address, server_name="VRChat-Client"): + browser = OSCQueryBrowser() + sleep(1) + service = browser.find_service_by_name(server_name) + oscq = OSCQueryClient(service) + mute_self_node = oscq.query_node(address) + return mute_self_node.value[0] def receiveOscParameters(dict_filter_and_target, ip_address="127.0.0.1", title="VRCT"): osc_port = get_open_udp_port() From 7f6c9a53ac0becf126cd5571bf228503ee226119 Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Mon, 6 May 2024 17:30:09 +0900 Subject: [PATCH 07/14] =?UTF-8?q?=F0=9F=90=9B[bugfix]=20Model=20:=20OSC=20?= =?UTF-8?q?mute=E5=90=8C=E6=9C=9F=E6=A9=9F=E8=83=BD=E3=82=92=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controller.py | 1 + model.py | 35 +++++++++++++++++++++-------------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/controller.py b/controller.py index 6f4f586c..599963e3 100644 --- a/controller.py +++ b/controller.py @@ -858,6 +858,7 @@ def callbackSetEnableAutoExportMessageLogs(value): def callbackSetEnableVrcMicMuteSync(value): print("callbackSetEnableVrcMicMuteSync", value) config.ENABLE_VRC_MIC_MUTE_SYNC = value + model.changePutQueueMicAudio() def callbackSetEnableSendMessageToVrc(value): print("callbackSetEnableSendMessageToVrc", value) diff --git a/model.py b/model.py index fe38fe02..2cdbd49b 100644 --- a/model.py +++ b/model.py @@ -223,25 +223,24 @@ class Model: def oscSendMessage(message): sendMessage(message, config.OSC_IP_ADDRESS, config.OSC_PORT) + @staticmethod + def getMuteSelfStatus(): + return getOSCParameterValue(address="/avatar/parameters/MuteSelf") + def startReceiveOSC(self): osc_parameter_prefix = "/avatar/parameters/" param_MuteSelf = "MuteSelf" - self.mute_status = getOSCParameterValue(address=osc_parameter_prefix + param_MuteSelf) + self.mute_status = self.getMuteSelfStatus() def change_handler_mute(address, osc_arguments): - if config.ENABLE_VRC_MIC_MUTE_SYNC is True: - if osc_arguments is True and self.mute_status is False: + if osc_arguments is True and self.mute_status is False: + self.mute_status = True + if config.ENABLE_VRC_MIC_MUTE_SYNC is True: self.stopPutQueueMicAudio() - self.mute_status = True - elif osc_arguments is False and self.mute_status is True: + elif osc_arguments is False and self.mute_status is True: + self.mute_status = False + if config.ENABLE_VRC_MIC_MUTE_SYNC is True: self.startPutQueueMicAudio() - self.mute_status = False - - def change_handler_voice(address, osc_arguments): - if config.ENABLE_VRC_MIC_MUTE_SYNC is True: - if self.mute_status is True: - self.startPutQueueMicAudio() - self.mute_status = False dict_filter_and_target = { osc_parameter_prefix + param_MuteSelf: change_handler_mute, @@ -328,8 +327,7 @@ class Model: self.mic_audio_queue = ConditionalQueue() # self.mic_energy_queue = ConditionalQueue() - if config.ENABLE_MUTE_DETECT is True and self.mute_status is True: - model.stopPutQueueMicAudio() + self.changePutQueueMicAudio() mic_device = choice_mic_device[0] record_timeout = config.INPUT_MIC_RECORD_TIMEOUT @@ -402,6 +400,15 @@ class Model: self.mic_audio_queue.get() # self.mic_energy_queue.set_flag(False) + def changePutQueueMicAudio(self): + if config.ENABLE_VRC_MIC_MUTE_SYNC is True: + if self.mute_status is True: + self.stopPutQueueMicAudio() + else: + self.startPutQueueMicAudio() + else: + self.startPutQueueMicAudio() + def stopMicTranscript(self): if isinstance(self.mic_print_transcript, threadFnc): self.mic_print_transcript.stop() From 9241a7cf1f97b324623e15eba2b55d25786672d4 Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Mon, 6 May 2024 18:37:13 +0900 Subject: [PATCH 08/14] =?UTF-8?q?=F0=9F=9A=A7[WIP/TEST]=20Model=20:=20mute?= =?UTF-8?q?=E5=90=8C=E6=9C=9F=E3=81=A7OFF=E6=99=82=E3=81=AB=E3=82=AD?= =?UTF-8?q?=E3=83=A5=E3=83=BC=E3=81=AB=E5=85=A5=E3=81=A3=E3=81=A6=E3=81=84?= =?UTF-8?q?=E3=82=8B=E3=82=82=E3=81=AE=E3=81=AF=E6=96=87=E5=AD=97=E8=B5=B7?= =?UTF-8?q?=E3=81=93=E3=81=97=E3=82=92=E5=87=BA=E5=8A=9B=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/model.py b/model.py index 2cdbd49b..1da98538 100644 --- a/model.py +++ b/model.py @@ -396,9 +396,11 @@ class Model: def stopPutQueueMicAudio(self): if isinstance(self.mic_audio_queue, ConditionalQueue): self.mic_audio_queue.set_flag(False) - while not self.mic_audio_queue.empty(): - self.mic_audio_queue.get() - # self.mic_energy_queue.set_flag(False) + # queueを空にする場合を考慮 + if False: + while not self.mic_audio_queue.empty(): + self.mic_audio_queue.get() + # self.mic_energy_queue.set_flag(False) def changePutQueueMicAudio(self): if config.ENABLE_VRC_MIC_MUTE_SYNC is True: From 1401562ddbda139c61b5db4dd19677984b16a46d Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Tue, 7 May 2024 10:13:10 +0900 Subject: [PATCH 09/14] =?UTF-8?q?=F0=9F=97=91=EF=B8=8F[Remove]=20Model=20:?= =?UTF-8?q?=20=E4=B8=8D=E8=A6=81=E3=81=AA=E3=82=B3=E3=83=BC=E3=83=89(creat?= =?UTF-8?q?eDictOSCReceiveParameters)=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controller.py | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/controller.py b/controller.py index 599963e3..43b11844 100644 --- a/controller.py +++ b/controller.py @@ -914,35 +914,6 @@ def callbackSetEnableSendReceivedMessageToVrc(value): config.ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC = value # ---------------------Speaker2Chatbox--------------------- -def createDictOSCReceiveParameters(): - osc_parameter_prefix = "/avatar/parameters/" - param_MuteSelf = "MuteSelf" - param_Voice = "Voice" - - def change_handler_mute(address, osc_arguments): - if config.ENABLE_VRC_MIC_MUTE_SYNC is True: - if osc_arguments is True and change_handler_mute.status_mute is False: - model.stopPutQueueMicAudio() - change_handler_mute.status_mute = True - elif osc_arguments is False and change_handler_mute.status_mute is True: - model.startPutQueueMicAudio() - change_handler_mute.status_mute = False - - def change_handler_voice(address, osc_arguments): - if config.ENABLE_VRC_MIC_MUTE_SYNC is True: - if change_handler_mute.status_mute is True: - model.startPutQueueMicAudio() - change_handler_mute.status_mute = False - - change_handler_mute.status_mute = False - - dict_filter_and_target = { - osc_parameter_prefix + param_MuteSelf: change_handler_mute, - osc_parameter_prefix + param_Voice: change_handler_voice, - } - return dict_filter_and_target - - # Advanced Settings Tab def callbackSetOscIpAddress(value): if value == "": From 8b866e1577146fc490d2e329b71e6a3161783190 Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Tue, 7 May 2024 10:15:38 +0900 Subject: [PATCH 10/14] =?UTF-8?q?=F0=9F=9A=A7[WIP/TEST]=20Model=20:=20mute?= =?UTF-8?q?=E5=90=8C=E6=9C=9F=E5=87=A6=E7=90=86=E3=81=A7=E6=96=87=E5=AD=97?= =?UTF-8?q?=E8=B5=B7=E3=81=93=E3=81=97=E3=81=AE=E5=90=8C=E6=9C=9F=E3=82=92?= =?UTF-8?q?Queue=E3=81=8B=E3=82=89pause/resume=E3=81=AE=E9=96=A2=E6=95=B0?= =?UTF-8?q?=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model.py | 72 ++++++++++--------- .../transcription/transcription_recorder.py | 4 +- requirements.txt | 2 +- 3 files changed, 41 insertions(+), 37 deletions(-) diff --git a/model.py b/model.py index 1da98538..bd60c615 100644 --- a/model.py +++ b/model.py @@ -9,7 +9,7 @@ from datetime import datetime from logging import getLogger, FileHandler, Formatter, INFO from time import sleep from queue import Queue -from threading import Thread, Event +from threading import Thread from requests import get as requests_get import webbrowser @@ -30,33 +30,30 @@ from config import config class threadFnc(Thread): def __init__(self, fnc, end_fnc=None, daemon=True, *args, **kwargs): - super(threadFnc, self).__init__(daemon=daemon, *args, **kwargs) + super(threadFnc, self).__init__(daemon=daemon, target=fnc, *args, **kwargs) self.fnc = fnc self.end_fnc = end_fnc - self._stop = Event() + self.loop = True + self._pause = False + def stop(self): - self._stop.set() - def stopped(self): - return self._stop.isSet() + self.loop = False + + def pause(self): + self._pause = True + + def resume(self): + self._pause = False + def run(self): - while True: - if self.stopped(): - if callable(self.end_fnc): - self.end_fnc() - return + while self.loop: self.fnc(*self._args, **self._kwargs) + while self._pause: + sleep(0.1) -class ConditionalQueue(Queue): - def __init__(self, flag=True, *args, **kwargs): - super().__init__(*args, **kwargs) - self.flag = flag - - def put(self, item, block=True, timeout=None): - if self.flag is True: - super().put(item, block, timeout) - - def set_flag(self, value): - self.flag = value + if callable(self.end_fnc): + self.end_fnc() + return class Model: _instance = None @@ -325,8 +322,8 @@ class Model: pass return - self.mic_audio_queue = ConditionalQueue() - # self.mic_energy_queue = ConditionalQueue() + self.mic_audio_queue = Queue() + # self.mic_energy_queue = Queue() self.changePutQueueMicAudio() mic_device = choice_mic_device[0] @@ -387,20 +384,27 @@ class Model: # self.mic_get_energy.start() def startPutQueueMicAudio(self): - if isinstance(self.mic_audio_queue, ConditionalQueue): + # キューをクリア + if isinstance(self.mic_audio_queue, Queue): while not self.mic_audio_queue.empty(): self.mic_audio_queue.get() - self.mic_audio_queue.set_flag(True) - # self.mic_energy_queue.set_flag(True) + + # 文字起こしを再開 + # if isinstance(self.mic_print_transcript, threadFnc): + # self.mic_print_transcript.resume() + + # 音声のレコードを再開 + if isinstance(self.mic_audio_recorder, SelectedMicEnergyAndAudioRecorder): + self.mic_audio_recorder.resume() def stopPutQueueMicAudio(self): - if isinstance(self.mic_audio_queue, ConditionalQueue): - self.mic_audio_queue.set_flag(False) - # queueを空にする場合を考慮 - if False: - while not self.mic_audio_queue.empty(): - self.mic_audio_queue.get() - # self.mic_energy_queue.set_flag(False) + # 文字起こしを一時停止 + # if isinstance(self.mic_print_transcript, threadFnc): + # self.mic_print_transcript.pause() + + # 音声のレコードを一時停止 + if isinstance(self.mic_audio_recorder, SelectedMicEnergyAndAudioRecorder): + self.mic_audio_recorder.pause() def changePutQueueMicAudio(self): if config.ENABLE_VRC_MIC_MUTE_SYNC is True: diff --git a/models/transcription/transcription_recorder.py b/models/transcription/transcription_recorder.py index 0128a37b..c5f6af56 100644 --- a/models/transcription/transcription_recorder.py +++ b/models/transcription/transcription_recorder.py @@ -115,9 +115,9 @@ class BaseEnergyAndAudioRecorder: energy_queue.put(energy) if isinstance(energy_queue, Queue): - self.stop = self.recorder.listen_energy_and_audio_in_background(self.source, audioRecordCallback, phrase_time_limit=self.record_timeout, callback_energy=energyRecordCallback) + self.stop, self.pause, self.resume = self.recorder.listen_energy_and_audio_in_background(self.source, audioRecordCallback, phrase_time_limit=self.record_timeout, callback_energy=energyRecordCallback) else: - self.stop = self.recorder.listen_energy_and_audio_in_background(self.source, audioRecordCallback, phrase_time_limit=self.record_timeout) + self.stop, self.pause, self.resume = self.recorder.listen_energy_and_audio_in_background(self.source, audioRecordCallback, phrase_time_limit=self.record_timeout) class SelectedMicEnergyAndAudioRecorder(BaseEnergyAndAudioRecorder): def __init__(self, device, energy_threshold, dynamic_energy_threshold, record_timeout): diff --git a/requirements.txt b/requirements.txt index 9567870c..13fe8df2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,5 +13,5 @@ sentencepiece==0.1.99 ctranslate2==4.1.0 faster-whisper==1.0.1 translators @ git+https://github.com/misyaguziya/translators@5.8.9 -SpeechRecognition @ git+https://github.com/misyaguziya/custom_speech_recognition@3.10.2 +SpeechRecognition @ git+https://github.com/misyaguziya/custom_speech_recognition@3.10.4 tinyoscquery @ git+https://github.com/cyberkitsune/tinyoscquery@0.1.2 \ No newline at end of file From 0e4ad7eec3ade4d63b5f2bb0be6dce8e8df6fd12 Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Tue, 7 May 2024 15:05:43 +0900 Subject: [PATCH 11/14] =?UTF-8?q?=F0=9F=9A=A7[WIP/TEST]=20Model=20:=20pack?= =?UTF-8?q?age=E3=81=AE=E5=87=A6=E7=90=86=E3=81=AB=E5=90=88=E3=82=8F?= =?UTF-8?q?=E3=81=9B=E3=81=A6=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model.py | 2 +- models/transcription/transcription_recorder.py | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/model.py b/model.py index bd60c615..e53e1f23 100644 --- a/model.py +++ b/model.py @@ -486,7 +486,7 @@ class Model: record_timeout=record_timeout, ) # self.speaker_audio_recorder.recordIntoQueue(speaker_audio_queue, speaker_energy_queue) - self.speaker_audio_recorder.recordIntoQueue(speaker_audio_queue ,None) + self.speaker_audio_recorder.recordIntoQueue(speaker_audio_queue, None) self.speaker_transcriber = AudioTranscriber( speaker=True, source=self.speaker_audio_recorder.source, diff --git a/models/transcription/transcription_recorder.py b/models/transcription/transcription_recorder.py index c5f6af56..db1879da 100644 --- a/models/transcription/transcription_recorder.py +++ b/models/transcription/transcription_recorder.py @@ -24,7 +24,7 @@ class BaseRecorder: def record_callback(_, audio): 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.pause, self.resume = self.recorder.listen_in_background(self.source, record_callback, phrase_time_limit=self.record_timeout) class SelectedMicRecorder(BaseRecorder): def __init__(self, device, energy_threshold, dynamic_energy_threshold, record_timeout): @@ -68,7 +68,7 @@ class BaseEnergyRecorder: def recordCallback(_, energy): energy_queue.put(energy) - self.stop = self.recorder.listen_energy_in_background(self.source, recordCallback) + self.stop, self.pause, self.resume = self.recorder.listen_energy_in_background(self.source, recordCallback) class SelectedMicEnergyRecorder(BaseEnergyRecorder): def __init__(self, device): @@ -107,17 +107,14 @@ class BaseEnergyAndAudioRecorder: with self.source: self.recorder.adjust_for_ambient_noise(self.source) - def recordIntoQueue(self, audio_queue, energy_queue): + def recordIntoQueue(self, audio_queue, energy_queue=None): def audioRecordCallback(_, audio): audio_queue.put((audio.get_raw_data(), datetime.now())) def energyRecordCallback(energy): energy_queue.put(energy) - if isinstance(energy_queue, Queue): - self.stop, self.pause, self.resume = self.recorder.listen_energy_and_audio_in_background(self.source, audioRecordCallback, phrase_time_limit=self.record_timeout, callback_energy=energyRecordCallback) - else: - self.stop, self.pause, self.resume = self.recorder.listen_energy_and_audio_in_background(self.source, audioRecordCallback, phrase_time_limit=self.record_timeout) + self.stop, self.pause, self.resume = self.recorder.listen_energy_and_audio_in_background(self.source, audioRecordCallback, phrase_time_limit=self.record_timeout, callback_energy=energyRecordCallback) class SelectedMicEnergyAndAudioRecorder(BaseEnergyAndAudioRecorder): def __init__(self, device, energy_threshold, dynamic_energy_threshold, record_timeout): From d7f48d0366a316d92cf645744617c1d7db8e8fa5 Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Tue, 7 May 2024 15:20:57 +0900 Subject: [PATCH 12/14] =?UTF-8?q?=F0=9F=90=9B[bugfix]=20Model=20:=20callba?= =?UTF-8?q?ck=5Fenergy=E3=82=92=E4=BD=BF=E7=94=A8=E3=81=99=E3=82=8B?= =?UTF-8?q?=E5=A0=B4=E5=90=88=E3=81=AE=E6=9D=A1=E4=BB=B6=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- models/transcription/transcription_recorder.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/models/transcription/transcription_recorder.py b/models/transcription/transcription_recorder.py index db1879da..0e9b147d 100644 --- a/models/transcription/transcription_recorder.py +++ b/models/transcription/transcription_recorder.py @@ -114,7 +114,11 @@ class BaseEnergyAndAudioRecorder: def energyRecordCallback(energy): energy_queue.put(energy) - self.stop, self.pause, self.resume = self.recorder.listen_energy_and_audio_in_background(self.source, audioRecordCallback, phrase_time_limit=self.record_timeout, callback_energy=energyRecordCallback) + self.stop, self.pause, self.resume = self.recorder.listen_energy_and_audio_in_background( + source=self.source, + callback=audioRecordCallback, + phrase_time_limit=self.record_timeout, + callback_energy=energyRecordCallback if energy_queue is not None else None) class SelectedMicEnergyAndAudioRecorder(BaseEnergyAndAudioRecorder): def __init__(self, device, energy_threshold, dynamic_energy_threshold, record_timeout): From 835f4739fd11438071e5b07ffb52531265581999 Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Wed, 8 May 2024 01:29:02 +0900 Subject: [PATCH 13/14] =?UTF-8?q?=F0=9F=90=9B[bugfix]=20Model=20:=20mute?= =?UTF-8?q?=E5=90=8C=E6=9C=9F=E3=81=8C=E5=8B=95=E4=BD=9C=E3=81=97=E3=81=A6?= =?UTF-8?q?=E3=81=84=E3=81=AA=E3=81=84=E5=95=8F=E9=A1=8C=E3=82=92=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 起動時にmuteselfしているかどうか監視するように変更 - VRChatが起動指定な場合にgetOSCParameterValueがエラーになる問題を修正 - config移行の状態遷移によるmute状態の初期化問題を修正 --- controller.py | 8 +++++- model.py | 57 ++++++++++++++++++++++++++++------------- models/osc/osc_tools.py | 18 ++++++++----- 3 files changed, 58 insertions(+), 25 deletions(-) diff --git a/controller.py b/controller.py index 43b11844..b4d2e2c3 100644 --- a/controller.py +++ b/controller.py @@ -858,7 +858,11 @@ def callbackSetEnableAutoExportMessageLogs(value): def callbackSetEnableVrcMicMuteSync(value): print("callbackSetEnableVrcMicMuteSync", value) config.ENABLE_VRC_MIC_MUTE_SYNC = value - model.changePutQueueMicAudio() + if config.ENABLE_VRC_MIC_MUTE_SYNC is True: + model.startCheckMuteSelfStatus() + else: + model.stopCheckMuteSelfStatus() + def callbackSetEnableSendMessageToVrc(value): print("callbackSetEnableSendMessageToVrc", value) @@ -981,6 +985,8 @@ def createMainWindow(splash): # init OSC receive model.startReceiveOSC() + if config.ENABLE_VRC_MIC_MUTE_SYNC is True: + model.startCheckMuteSelfStatus() splash.toProgress(3) # Last one. diff --git a/model.py b/model.py index e53e1f23..5b231868 100644 --- a/model.py +++ b/model.py @@ -77,7 +77,8 @@ class Model: self.translator = Translator() self.keyword_processor = KeywordProcessor() self.mic_audio_queue = None - self.mute_status = False + self.mic_mute_status = None + self.mic_mute_status_check = None def checkCTranslatorCTranslate2ModelWeight(self): return checkCTranslate2Weight(config.PATH_LOCAL, config.CTRANSLATE2_WEIGHT_TYPE) @@ -224,20 +225,37 @@ class Model: def getMuteSelfStatus(): return getOSCParameterValue(address="/avatar/parameters/MuteSelf") + def startCheckMuteSelfStatus(self): + def checkMuteSelfStatus(): + if self.mic_mute_status is not None: + self.stopCheckMuteSelfStatus() + + status = self.getMuteSelfStatus() + if status is not None: + self.mic_mute_status = status + self.stopCheckMuteSelfStatus() + + if not isinstance(self.mic_mute_status_check, threadFnc): + self.mic_mute_status_check = threadFnc(checkMuteSelfStatus) + self.mic_mute_status_check.daemon = True + self.mic_mute_status_check.start() + + def stopCheckMuteSelfStatus(self): + if isinstance(self.mic_mute_status_check, threadFnc): + self.mic_mute_status_check.stop() + self.mic_mute_status_check = None + def startReceiveOSC(self): osc_parameter_prefix = "/avatar/parameters/" param_MuteSelf = "MuteSelf" - self.mute_status = self.getMuteSelfStatus() def change_handler_mute(address, osc_arguments): - if osc_arguments is True and self.mute_status is False: - self.mute_status = True - if config.ENABLE_VRC_MIC_MUTE_SYNC is True: - self.stopPutQueueMicAudio() - elif osc_arguments is False and self.mute_status is True: - self.mute_status = False - if config.ENABLE_VRC_MIC_MUTE_SYNC is True: - self.startPutQueueMicAudio() + if osc_arguments is True and self.mic_mute_status is False: + self.mic_mute_status = osc_arguments + self.changeMicTranscriptStatus() + elif osc_arguments is False and self.mic_mute_status is True: + self.mic_mute_status = osc_arguments + self.changeMicTranscriptStatus() dict_filter_and_target = { osc_parameter_prefix + param_MuteSelf: change_handler_mute, @@ -324,7 +342,6 @@ class Model: self.mic_audio_queue = Queue() # self.mic_energy_queue = Queue() - self.changePutQueueMicAudio() mic_device = choice_mic_device[0] record_timeout = config.INPUT_MIC_RECORD_TIMEOUT @@ -383,7 +400,9 @@ class Model: # self.mic_get_energy.daemon = True # self.mic_get_energy.start() - def startPutQueueMicAudio(self): + self.changeMicTranscriptStatus() + + def resumeMicTranscript(self): # キューをクリア if isinstance(self.mic_audio_queue, Queue): while not self.mic_audio_queue.empty(): @@ -397,7 +416,7 @@ class Model: if isinstance(self.mic_audio_recorder, SelectedMicEnergyAndAudioRecorder): self.mic_audio_recorder.resume() - def stopPutQueueMicAudio(self): + def pauseMicTranscript(self): # 文字起こしを一時停止 # if isinstance(self.mic_print_transcript, threadFnc): # self.mic_print_transcript.pause() @@ -406,14 +425,16 @@ class Model: if isinstance(self.mic_audio_recorder, SelectedMicEnergyAndAudioRecorder): self.mic_audio_recorder.pause() - def changePutQueueMicAudio(self): + def changeMicTranscriptStatus(self): if config.ENABLE_VRC_MIC_MUTE_SYNC is True: - if self.mute_status is True: - self.stopPutQueueMicAudio() + if self.mic_mute_status is True: + self.pauseMicTranscript() + elif self.mic_mute_status is False: + self.resumeMicTranscript() else: - self.startPutQueueMicAudio() + pass else: - self.startPutQueueMicAudio() + self.resumeMicTranscript() def stopMicTranscript(self): if isinstance(self.mic_print_transcript, threadFnc): diff --git a/models/osc/osc_tools.py b/models/osc/osc_tools.py index e7aa7d23..0f0958c3 100644 --- a/models/osc/osc_tools.py +++ b/models/osc/osc_tools.py @@ -49,12 +49,18 @@ def sendChangeVoice(ip_address="127.0.0.1", port=9000): sleep(0.05) def getOSCParameterValue(address, server_name="VRChat-Client"): - browser = OSCQueryBrowser() - sleep(1) - service = browser.find_service_by_name(server_name) - oscq = OSCQueryClient(service) - mute_self_node = oscq.query_node(address) - return mute_self_node.value[0] + value = None + try: + browser = OSCQueryBrowser() + sleep(1) + service = browser.find_service_by_name(server_name) + if service is not None: + oscq = OSCQueryClient(service) + mute_self_node = oscq.query_node(address) + value = mute_self_node.value[0] + except Exception: + pass + return value def receiveOscParameters(dict_filter_and_target, ip_address="127.0.0.1", title="VRCT"): osc_port = get_open_udp_port() From 7535565009acd6408ded4ca900da99a99fd66352 Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Wed, 8 May 2024 02:51:15 +0900 Subject: [PATCH 14/14] =?UTF-8?q?=F0=9F=90=9B[bugfix]=20Model=20:=20mute?= =?UTF-8?q?=E5=90=8C=E6=9C=9F=E5=87=A6=E7=90=86=E3=82=92=E3=83=A1=E3=82=A4?= =?UTF-8?q?=E3=83=B3=E7=94=BB=E9=9D=A2=E3=81=8B=E3=82=89=E3=81=AE=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E3=81=A7=E5=A4=89=E6=9B=B4=E3=81=A7=E3=81=8D=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/model.py b/model.py index 5b231868..fc8ec5da 100644 --- a/model.py +++ b/model.py @@ -228,11 +228,13 @@ class Model: def startCheckMuteSelfStatus(self): def checkMuteSelfStatus(): if self.mic_mute_status is not None: + self.changeMicTranscriptStatus() self.stopCheckMuteSelfStatus() status = self.getMuteSelfStatus() if status is not None: self.mic_mute_status = status + self.changeMicTranscriptStatus() self.stopCheckMuteSelfStatus() if not isinstance(self.mic_mute_status_check, threadFnc):