From caac4527e9423bf47035e9f90033b416aa7344b7 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Mon, 20 Jan 2020 20:08:19 +1000 Subject: [PATCH] add a proof of concept TTS implementation on Mac --- qt/aqt/sound.py | 4 ++++ qt/aqt/tts.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 qt/aqt/tts.py diff --git a/qt/aqt/sound.py b/qt/aqt/sound.py index e110b0e19..1475cf519 100644 --- a/qt/aqt/sound.py +++ b/qt/aqt/sound.py @@ -647,6 +647,10 @@ def setup_audio(base_folder: str) -> None: mpv.args.append("--include=" + base_folder) av_player.players.append(mpv) + if isMac: + from aqt.tts import MacTTSPlayer + + av_player.players.append(MacTTSPlayer()) # Legacy audio interface ########################################################################## diff --git a/qt/aqt/tts.py b/qt/aqt/tts.py new file mode 100644 index 000000000..9230c7170 --- /dev/null +++ b/qt/aqt/tts.py @@ -0,0 +1,42 @@ +""" +todo +""" + +import subprocess +from concurrent.futures import Future +from typing import Callable, cast + +from anki.sound import AVTag, TTSTag +from aqt.sound import OnDoneCallback, Player +from aqt.taskman import TaskManager + + +class TTSPlayer(Player): # pylint: disable=abstract-method + def can_play(self, tag: AVTag) -> bool: + return isinstance(tag, TTSTag) + + +class MacTTSPlayer(TTSPlayer): + _taskman = TaskManager() + + def play(self, tag: AVTag, on_done: Callable[[], None]) -> None: + ttag = cast(TTSTag, tag) + self._taskman.run( + lambda: self._play(ttag), lambda ret: self._on_done(ret, on_done) + ) + + def _play(self, tag: TTSTag) -> None: + ret = subprocess.run( + ["say", "-v", "Alex", "-f", "-"], + input=tag.text, + encoding="utf8", + check=True, + ) + + def _on_done(self, ret: Future, cb: OnDoneCallback) -> None: + # will raise on error + ret.result() + cb() + + def stop(self): + pass