diff --git a/README-DEVELOPMENT.md b/README-DEVELOPMENT.md index 8df9733..660c1a7 100644 --- a/README-DEVELOPMENT.md +++ b/README-DEVELOPMENT.md @@ -100,7 +100,7 @@ git status - **Runtime**: python3, pygobject-3.0, pluggy, AT-SPI2 - **Build**: meson, ninja, gettext -- **Optional**: dasbus (for D-Bus service), BrlTTY, speech-dispatcher +- **Optional**: dasbus (for D-Bus service), BrlTTY, speech-dispatcher, piper-tts Install build dependencies on Arch Linux: ```bash diff --git a/README.md b/README.md index 70ee6ee..7965f9e 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,10 @@ toolkit, OpenOffice/LibreOffice, Gecko, WebKitGtk, and KDE Qt toolkit. * **python-speechd** - Python bindings for Speech Dispatcher (recommended) * **gstreamer-1.0** - GStreamer streaming media framework (for sounds) +* **piper-tts** - Piper neural text-to-speech engine (optional) + +Piper voice models are typically stored under `~/.local/share/piper/voices` or +`/usr/share/piper-voices`. ### Braille Support (Optional) diff --git a/pyproject.toml b/pyproject.toml index 01e59ee..210fdf3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,7 @@ dependencies = [ "pygobject>=3.18", "brlapi; extra == 'braille'", "python-speechd; extra == 'speech'", + "piper-tts; extra == 'piper'", "louis; extra == 'braille'" ] diff --git a/src/cthulhu/piper_audio_player.py b/src/cthulhu/piper_audio_player.py index 7f29e5f..c0744e4 100644 --- a/src/cthulhu/piper_audio_player.py +++ b/src/cthulhu/piper_audio_player.py @@ -80,6 +80,8 @@ class PiperAudioPlayer: if not _gstreamerAvailable: return False + self._resetPipeline() + try: self._pipeline = Gst.Pipeline.new("piper-audio") @@ -148,6 +150,15 @@ class PiperAudioPlayer: debug.printMessage(debug.LEVEL_WARNING, msg, True) return False + def _resetPipeline(self): + """Reset the GStreamer pipeline and related elements.""" + if self._pipeline is not None: + self._pipeline.set_state(Gst.State.NULL) + self._pipeline = None + self._appsrc = None + self._volume = None + self._initialized = False + def _onMessage(self, bus, message): """Handle GStreamer bus messages.""" if message.type == Gst.MessageType.EOS: @@ -173,8 +184,8 @@ class PiperAudioPlayer: """ if sampleRate != self._sampleRate: self._sampleRate = sampleRate - self._initialized = False self.stop() + self._resetPipeline() self._init() def setVolume(self, volumeLevel): @@ -239,7 +250,6 @@ class PiperAudioPlayer: with self._lock: self._playing = True - stopRequested = False self._completionCallback = completionCallback @@ -289,9 +299,4 @@ class PiperAudioPlayer: def shutdown(self): """Shut down the audio player and release resources.""" self.stop() - self._initialized = False - if self._pipeline is not None: - self._pipeline.set_state(Gst.State.NULL) - self._pipeline = None - self._appsrc = None - self._volume = None + self._resetPipeline() diff --git a/src/cthulhu/piper_voice_manager.py b/src/cthulhu/piper_voice_manager.py index bf288d7..c68e01a 100644 --- a/src/cthulhu/piper_voice_manager.py +++ b/src/cthulhu/piper_voice_manager.py @@ -79,15 +79,19 @@ class PiperVoiceManager: VOICE_SEARCH_PATHS = [ "~/.local/share/piper/voices", + "~/.local/share/piper-voices", "~/.local/share/piper-tts/voices", "~/.config/piper/voices", + "~/.config/piper-tts/voices", "$XDG_DATA_HOME/piper/voices", + "$XDG_DATA_HOME/piper-voices", "$XDG_DATA_HOME/piper-tts/voices", "$XDG_DATA_HOME/cthulhu/piper-voices", "/usr/share/piper/voices", "/usr/share/piper-voices", "/usr/share/piper-tts/voices", "/usr/local/share/piper/voices", + "/usr/local/share/piper-voices", "/usr/local/share/piper-tts/voices", ]