From 9353ce0e17304a66d31809dcee5735e4cadbfe4c Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Fri, 13 Sep 2024 16:12:29 -0700 Subject: [PATCH 01/15] Troubleshoot missing audio playback --- neon_audio/service.py | 2 +- neon_audio/tts/neon.py | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/neon_audio/service.py b/neon_audio/service.py index 833937e..4993975 100644 --- a/neon_audio/service.py +++ b/neon_audio/service.py @@ -98,7 +98,7 @@ def __init__(self, ready_hook=on_ready, error_hook=on_error, ovos_audio.service.PlaybackThread = NeonPlaybackThread PlaybackService.__init__(self, ready_hook, error_hook, stopping_hook, alive_hook, started_hook, watchdog, bus, - disable_ocp) + disable_ocp, validate_source=False) LOG.debug(f'Initialized tts={self._tts_hash} | ' f'fallback={self._fallback_tts_hash}') create_signal("neon_speak_api") # Create signal so skills use API diff --git a/neon_audio/tts/neon.py b/neon_audio/tts/neon.py index 97951da..00da849 100644 --- a/neon_audio/tts/neon.py +++ b/neon_audio/tts/neon.py @@ -172,6 +172,7 @@ def end_audio(self, listen, message=None): check_for_signal("isSpeaking") def _play(self): + LOG.debug(f"Start playing {self._now_playing}") # wav_file, vis, listen, ident, message ident = self._now_playing[3] message = self._now_playing[4] @@ -180,7 +181,7 @@ def _play(self): ident = message.context.get('ident') or \ message.context.get('session', {}).get('session_id') - super()._play() + PlaybackThread._play(self) # Notify playback is finished LOG.info(f"Played {ident}") self.bus.emit(message.forward(ident)) @@ -192,6 +193,14 @@ def _play(self): **_sort_timing_metrics( message.context['timing'])})) + def pause(self): + LOG.debug(f"Playback thread paused") + PlaybackThread.pause(self) + + def resume(self): + LOG.debug(f"Playback thread resumed") + PlaybackThread.resume(self) + class WrappedTTS(TTS): def __new__(cls, base_engine, *args, **kwargs): @@ -400,6 +409,7 @@ def execute(self, sentence: str, ident: str = None, listen: bool = False, vis = self.viseme(r["phonemes"]) if r["phonemes"] \ else None # queue for playback + LOG.debug(f"Queue playback of: {wav_file}") self.queue.put((wav_file, vis, listen, ident, message)) self.handle_metric({"metric_type": "tts.queued"}) else: From 6f140f3a5348316d0b050dd59bac560a0c618912 Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Fri, 13 Sep 2024 16:20:38 -0700 Subject: [PATCH 02/15] More logging --- neon_audio/service.py | 7 +++++++ neon_audio/tts/neon.py | 1 + 2 files changed, 8 insertions(+) diff --git a/neon_audio/service.py b/neon_audio/service.py index 4993975..35ac709 100644 --- a/neon_audio/service.py +++ b/neon_audio/service.py @@ -31,6 +31,8 @@ import ovos_plugin_manager.templates.tts from threading import Event + +from ovos_bus_client import Message from ovos_utils.log import LOG, log_deprecation from neon_audio.tts import TTSFactory from neon_utils.messagebus_utils import get_messagebus @@ -186,3 +188,8 @@ def handle_get_tts(self, message): def init_messagebus(self): self.bus.on('neon.get_tts', self.handle_get_tts) PlaybackService.init_messagebus(self) + + def execute_tts(self, utterance, ident, listen=False, message: Message = None): + LOG.debug(f"START {utterance}") + PlaybackService.execute_tts(self, utterance, ident, listen, message) + LOG.debug(f"END {utterance}") diff --git a/neon_audio/tts/neon.py b/neon_audio/tts/neon.py index 00da849..dce0170 100644 --- a/neon_audio/tts/neon.py +++ b/neon_audio/tts/neon.py @@ -368,6 +368,7 @@ def execute(self, sentence: str, ident: str = None, listen: bool = False, kwargs: (dict) optional keyword arguments to be passed to TTS engine get_tts method """ + LOG.debug(f"execute: {sentence}") stopwatch = Stopwatch("get_tts", True, self.bus) if message: # Make sure to set the speaking signal now From bcef725d592e12ba0db3c865f5f26c77f82c119d Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Fri, 13 Sep 2024 16:33:31 -0700 Subject: [PATCH 03/15] More logging --- neon_audio/service.py | 5 ----- neon_audio/tts/__init__.py | 1 + 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/neon_audio/service.py b/neon_audio/service.py index 35ac709..bb9cf8e 100644 --- a/neon_audio/service.py +++ b/neon_audio/service.py @@ -188,8 +188,3 @@ def handle_get_tts(self, message): def init_messagebus(self): self.bus.on('neon.get_tts', self.handle_get_tts) PlaybackService.init_messagebus(self) - - def execute_tts(self, utterance, ident, listen=False, message: Message = None): - LOG.debug(f"START {utterance}") - PlaybackService.execute_tts(self, utterance, ident, listen, message) - LOG.debug(f"END {utterance}") diff --git a/neon_audio/tts/__init__.py b/neon_audio/tts/__init__.py index b09f020..40ddcfd 100644 --- a/neon_audio/tts/__init__.py +++ b/neon_audio/tts/__init__.py @@ -60,4 +60,5 @@ def create(config=None): return tts = WrappedTTS(clazz, tts_lang, tts_config) tts.validator.validate() + LOG.debug(f"Initialized tts: {tts.tts_name}") return tts From 9fe0a6a19fc4e994a35831f590c63e5c9de86746 Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Fri, 13 Sep 2024 16:46:52 -0700 Subject: [PATCH 04/15] More logging --- neon_audio/service.py | 1 - neon_audio/tts/neon.py | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/neon_audio/service.py b/neon_audio/service.py index bb9cf8e..8947a40 100644 --- a/neon_audio/service.py +++ b/neon_audio/service.py @@ -32,7 +32,6 @@ from threading import Event -from ovos_bus_client import Message from ovos_utils.log import LOG, log_deprecation from neon_audio.tts import TTSFactory from neon_utils.messagebus_utils import get_messagebus diff --git a/neon_audio/tts/neon.py b/neon_audio/tts/neon.py index dce0170..ed61686 100644 --- a/neon_audio/tts/neon.py +++ b/neon_audio/tts/neon.py @@ -204,6 +204,7 @@ def resume(self): class WrappedTTS(TTS): def __new__(cls, base_engine, *args, **kwargs): + LOG.info(f"Creating wrapped TTS object for {base_engine}") base_engine.execute = cls.execute base_engine.get_multiple_tts = cls.get_multiple_tts # TODO: Below method is only to bridge compatibility From 9edefcf28250d456dec0388095aa3a23af8baf09 Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Fri, 13 Sep 2024 17:07:13 -0700 Subject: [PATCH 05/15] More init troubleshooting --- neon_audio/service.py | 3 +++ neon_audio/tts/__init__.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/neon_audio/service.py b/neon_audio/service.py index 8947a40..ddb30da 100644 --- a/neon_audio/service.py +++ b/neon_audio/service.py @@ -91,11 +91,14 @@ def __init__(self, ready_hook=on_ready, error_hook=on_error, init_signal_bus(bus) init_signal_handlers() from neon_utils.signal_utils import create_signal, check_for_signal + import ovos_audio.service ovos_audio.service.check_for_signal = check_for_signal ovos_plugin_manager.templates.tts.check_for_signal = check_for_signal ovos_plugin_manager.templates.tts.create_signal = create_signal from neon_audio.tts.neon import NeonPlaybackThread + import ovos_audio.playback + ovos_audio.playback.PlaybackThread = NeonPlaybackThread ovos_audio.service.PlaybackThread = NeonPlaybackThread PlaybackService.__init__(self, ready_hook, error_hook, stopping_hook, alive_hook, started_hook, watchdog, bus, diff --git a/neon_audio/tts/__init__.py b/neon_audio/tts/__init__.py index 40ddcfd..39a89bb 100644 --- a/neon_audio/tts/__init__.py +++ b/neon_audio/tts/__init__.py @@ -60,5 +60,5 @@ def create(config=None): return tts = WrappedTTS(clazz, tts_lang, tts_config) tts.validator.validate() - LOG.debug(f"Initialized tts: {tts.tts_name}") + LOG.info(f"Initialized tts: {tts.tts_name}") return tts From 7978d6fbbba1f039e17019fbd6df94aadc5317c0 Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Fri, 13 Sep 2024 17:55:30 -0700 Subject: [PATCH 06/15] Remove patching of dropped imports --- neon_audio/service.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/neon_audio/service.py b/neon_audio/service.py index ddb30da..5510c4f 100644 --- a/neon_audio/service.py +++ b/neon_audio/service.py @@ -85,16 +85,7 @@ def __init__(self, ready_hook=on_ready, error_hook=on_error, from neon_audio.utils import patch_config patch_config(audio_config) bus = bus or get_messagebus() - # Override all the previously loaded signal methods - from neon_utils.signal_utils import init_signal_handlers, \ - init_signal_bus - init_signal_bus(bus) - init_signal_handlers() - from neon_utils.signal_utils import create_signal, check_for_signal - import ovos_audio.service - ovos_audio.service.check_for_signal = check_for_signal - ovos_plugin_manager.templates.tts.check_for_signal = check_for_signal - ovos_plugin_manager.templates.tts.create_signal = create_signal + from neon_utils.signal_utils import create_signal from neon_audio.tts.neon import NeonPlaybackThread import ovos_audio.playback From 48729aae22c4361f8328e43fe2819d6d1b5396bb Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Fri, 13 Sep 2024 17:58:44 -0700 Subject: [PATCH 07/15] Catch and log service init errors --- neon_audio/__main__.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/neon_audio/__main__.py b/neon_audio/__main__.py index 69ceb7e..8a46452 100644 --- a/neon_audio/__main__.py +++ b/neon_audio/__main__.py @@ -58,15 +58,20 @@ def main(*args, **kwargs): check_for_signal("isSpeaking") Lock("audio") setup_locale() - service = NeonPlaybackService(*args, **kwargs) - service.start() - wait_for_exit_signal() + try: + service = NeonPlaybackService(*args, **kwargs) + service.start() + wait_for_exit_signal() + except Exception as e: + LOG.exception(e) + service = None if malloc_running: try: print_malloc(snapshot_malloc()) except Exception as e: LOG.error(e) - service.shutdown() + if service: + service.shutdown() def deprecated_entrypoint(): From 721a865e866c01e84f6aacf01498b85420ed59fc Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Fri, 13 Sep 2024 18:07:57 -0700 Subject: [PATCH 08/15] Patch init failures with logged error --- neon_audio/tts/neon.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/neon_audio/tts/neon.py b/neon_audio/tts/neon.py index ed61686..d82e47a 100644 --- a/neon_audio/tts/neon.py +++ b/neon_audio/tts/neon.py @@ -31,6 +31,7 @@ import os from os.path import dirname +from threading import Thread, Event from time import time from json_database import JsonStorageXDG @@ -153,7 +154,22 @@ def _sort_timing_metrics(timings: dict) -> dict: class NeonPlaybackThread(PlaybackThread): def __init__(self, queue, bus=None): LOG.info("Initializing NeonPlaybackThread") - PlaybackThread.__init__(self, queue, bus=bus) + try: + PlaybackThread.__init__(self, queue, bus=bus) + except TypeError: + LOG.error("Failed to call PlaybackThread init; patching...") + from ovos_audio.transformers import TTSTransformersService + Thread.__init__(self, daemon=True) + self.queue = queue or TTS.queue + self._terminated = False + self._processing_queue = False + self._do_playback = Event() + self.enclosure = None + self.p = None + self.bus = bus or None + self._now_playing = None + self._started = Event() + self.tts_transform = TTSTransformersService(self.bus) def begin_audio(self, message: Message = None): # TODO: Mark signals for deprecation From 12b4a3b525d16105370d68f4bbb4d63f62f01d50 Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Fri, 13 Sep 2024 18:16:23 -0700 Subject: [PATCH 09/15] Troubleshooting PlaybackThread init --- neon_audio/service.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/neon_audio/service.py b/neon_audio/service.py index 5510c4f..3aae4dd 100644 --- a/neon_audio/service.py +++ b/neon_audio/service.py @@ -87,13 +87,14 @@ def __init__(self, ready_hook=on_ready, error_hook=on_error, bus = bus or get_messagebus() from neon_utils.signal_utils import create_signal - from neon_audio.tts.neon import NeonPlaybackThread - import ovos_audio.playback - ovos_audio.playback.PlaybackThread = NeonPlaybackThread - ovos_audio.service.PlaybackThread = NeonPlaybackThread PlaybackService.__init__(self, ready_hook, error_hook, stopping_hook, alive_hook, started_hook, watchdog, bus, disable_ocp, validate_source=False) + self.playback_thread.join() + del self.playback_thread + from neon_audio.tts.neon import NeonPlaybackThread + from ovos_plugin_manager.tts import TTS + self.playback_thread = NeonPlaybackThread(TTS.queue, self.bus) LOG.debug(f'Initialized tts={self._tts_hash} | ' f'fallback={self._fallback_tts_hash}') create_signal("neon_speak_api") # Create signal so skills use API @@ -181,3 +182,6 @@ def handle_get_tts(self, message): def init_messagebus(self): self.bus.on('neon.get_tts', self.handle_get_tts) PlaybackService.init_messagebus(self) + self.bus.remove("speak", PlaybackService.handle_speak) + self.bus.on("speak", self.handle_speak) + LOG.info("Initialized messagebus") From ef778e4d0aa4dc96fcc78c33d3b07d49b86dd6c9 Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Fri, 13 Sep 2024 18:25:22 -0700 Subject: [PATCH 10/15] Add log to troubleshoot service startup Update playback thread init --- neon_audio/__main__.py | 1 + neon_audio/service.py | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/neon_audio/__main__.py b/neon_audio/__main__.py index 8a46452..f9e67f5 100644 --- a/neon_audio/__main__.py +++ b/neon_audio/__main__.py @@ -60,6 +60,7 @@ def main(*args, **kwargs): setup_locale() try: service = NeonPlaybackService(*args, **kwargs) + LOG.info("Service init completed") service.start() wait_for_exit_signal() except Exception as e: diff --git a/neon_audio/service.py b/neon_audio/service.py index 3aae4dd..4458dbe 100644 --- a/neon_audio/service.py +++ b/neon_audio/service.py @@ -90,7 +90,6 @@ def __init__(self, ready_hook=on_ready, error_hook=on_error, PlaybackService.__init__(self, ready_hook, error_hook, stopping_hook, alive_hook, started_hook, watchdog, bus, disable_ocp, validate_source=False) - self.playback_thread.join() del self.playback_thread from neon_audio.tts.neon import NeonPlaybackThread from ovos_plugin_manager.tts import TTS From 846c83b8e8b07005ee93cd61341f96736c46ebb6 Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Mon, 16 Sep 2024 10:42:51 -0700 Subject: [PATCH 11/15] Remove deprecated `lang` arg passed to TTS module init Remove init patch added for debugging --- neon_audio/tts/__init__.py | 3 +-- neon_audio/tts/neon.py | 19 +------------------ 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/neon_audio/tts/__init__.py b/neon_audio/tts/__init__.py index 39a89bb..3ae24f0 100644 --- a/neon_audio/tts/__init__.py +++ b/neon_audio/tts/__init__.py @@ -53,12 +53,11 @@ def create(config=None): "en-us") tts_config = get_tts_config(config) - tts_lang = tts_config["lang"] clazz = OVOSTTSFactory.get_class(tts_config) if not clazz: LOG.error(f"Could not find plugin: {tts_config.get('module')}") return - tts = WrappedTTS(clazz, tts_lang, tts_config) + tts = WrappedTTS(clazz, config=tts_config) tts.validator.validate() LOG.info(f"Initialized tts: {tts.tts_name}") return tts diff --git a/neon_audio/tts/neon.py b/neon_audio/tts/neon.py index d82e47a..f51cb32 100644 --- a/neon_audio/tts/neon.py +++ b/neon_audio/tts/neon.py @@ -31,7 +31,6 @@ import os from os.path import dirname -from threading import Thread, Event from time import time from json_database import JsonStorageXDG @@ -154,22 +153,7 @@ def _sort_timing_metrics(timings: dict) -> dict: class NeonPlaybackThread(PlaybackThread): def __init__(self, queue, bus=None): LOG.info("Initializing NeonPlaybackThread") - try: - PlaybackThread.__init__(self, queue, bus=bus) - except TypeError: - LOG.error("Failed to call PlaybackThread init; patching...") - from ovos_audio.transformers import TTSTransformersService - Thread.__init__(self, daemon=True) - self.queue = queue or TTS.queue - self._terminated = False - self._processing_queue = False - self._do_playback = Event() - self.enclosure = None - self.p = None - self.bus = bus or None - self._now_playing = None - self._started = Event() - self.tts_transform = TTSTransformersService(self.bus) + PlaybackThread.__init__(self, queue, bus=bus) def begin_audio(self, message: Message = None): # TODO: Mark signals for deprecation @@ -332,7 +316,6 @@ def get_multiple_tts(self, message, **kwargs) -> dict: for request in tts_requested: tts_lang = kwargs["lang"] = request["language"] # Check if requested tts lang matches internal (text) lang - # TODO: `self.lang` should come from the incoming message if tts_lang.split("-")[0] != skill_lang.split("-")[0]: self.cached_translations.setdefault(tts_lang, {}) From 35993dd95285d58dcf67d89d738bf6d7a614d809 Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Mon, 16 Sep 2024 11:06:39 -0700 Subject: [PATCH 12/15] Loosen ovos-audio dependency to troubleshoot neon-core dependency resolution --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 24cd5a3..39ad367 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,4 +1,4 @@ -ovos-audio~=0.2 +ovos-audio~=0.0,>=0.0.2 ovos-utils~=0.0,>=0.0.35 ovos-config~=0.0,>=0.0.10 phoneme-guesser~=0.1 From cc159b323e7a6c33ea48841d83728bd2ed26a51a Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Mon, 16 Sep 2024 11:17:52 -0700 Subject: [PATCH 13/15] Update dependencies to allow resolution with neon-core --- requirements/requirements.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 39ad367..413b0ae 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -2,14 +2,14 @@ ovos-audio~=0.0,>=0.0.2 ovos-utils~=0.0,>=0.0.35 ovos-config~=0.0,>=0.0.10 phoneme-guesser~=0.1 -ovos-plugin-manager~=0.0,>=0.0.26 +ovos-plugin-manager~=0.0,>=0.0.26a16 neon-utils[network]~=1.9 click~=8.0 click-default-group~=1.2 -ovos-bus-client~=0.0.3 +ovos-bus-client~=0.0,>=0.0.3 # Default OCP backend + plugins -ovos-plugin-common-play~=0.1 +ovos-plugin-common-play~=0.0,>=0.0.6 ovos-ocp-m3u-plugin~=0.0.1 ovos-ocp-rss-plugin~=0.0.2 ovos-ocp-files-plugin~=0.13 From 505e248df92fdd321cb0621847e92fcf09f455d1 Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Mon, 16 Sep 2024 11:27:36 -0700 Subject: [PATCH 14/15] Include `ovos-audio` dependencies in TTS plugin installation --- neon_audio/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/neon_audio/utils.py b/neon_audio/utils.py index 24227f6..2af4d14 100644 --- a/neon_audio/utils.py +++ b/neon_audio/utils.py @@ -85,6 +85,7 @@ def install_tts_plugin(plugin: str) -> bool: _, tmp_file = mkstemp() with open(tmp_file, 'w') as f: constraints = '\n'.join(get_package_dependencies("neon-audio")) + constraints += '\n'.join(get_package_dependencies("ovos-audio")) f.write(constraints) LOG.info(f"Constraints={constraints}") LOG.info(f"Requested installation of plugin: {plugin}") From ef74324879ee7b86de3b02697aa16bf71dba7fae Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Mon, 16 Sep 2024 11:30:06 -0700 Subject: [PATCH 15/15] Fix typo in dependency handling change --- neon_audio/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/neon_audio/utils.py b/neon_audio/utils.py index 2af4d14..c864432 100644 --- a/neon_audio/utils.py +++ b/neon_audio/utils.py @@ -74,6 +74,7 @@ def build_extra_dependency_list(config: Union[dict, Configuration], additional: return dependencies + @deprecated("Replaced by `neon_utils.packaging_utils.install_packages_from_pip`", "2.0.0") def install_tts_plugin(plugin: str) -> bool: """ @@ -85,7 +86,7 @@ def install_tts_plugin(plugin: str) -> bool: _, tmp_file = mkstemp() with open(tmp_file, 'w') as f: constraints = '\n'.join(get_package_dependencies("neon-audio")) - constraints += '\n'.join(get_package_dependencies("ovos-audio")) + constraints += '\n' + '\n'.join(get_package_dependencies("ovos-audio")) f.write(constraints) LOG.info(f"Constraints={constraints}") LOG.info(f"Requested installation of plugin: {plugin}")