diff --git a/src/calibre/gui2/tts2/develop.py b/src/calibre/gui2/tts2/develop.py index 07d0f04ae2..dfcd5e2650 100644 --- a/src/calibre/gui2/tts2/develop.py +++ b/src/calibre/gui2/tts2/develop.py @@ -9,7 +9,7 @@ from calibre.gui2.main_window import MainWindow from calibre.gui2.tts2.manager import TTSManager TEXT = '''\ -Demonstration of DOCX support in calibre +Demonstration 😹 🐈 of DOCX support in calibre This document demonstrates the ability of the calibre DOCX Input plugin to convert the various typographic features in a Microsoft Word (2007 and newer) document. Convert this document to a modern ebook format, such as AZW3 for Kindles or EPUB for other ebook readers, diff --git a/src/calibre/gui2/tts2/qt.py b/src/calibre/gui2/tts2/qt.py index f96aba9956..a3ac7fa32d 100644 --- a/src/calibre/gui2/tts2/qt.py +++ b/src/calibre/gui2/tts2/qt.py @@ -11,6 +11,8 @@ class QtTTSBackend(TTSBackend): def __init__(self, engine_name: str = '', parent: QObject|None = None): super().__init__(parent) + self.speaking_text = '' + self.last_word_offset = 0 self._qt_reload_after_configure(engine_name) @property @@ -37,6 +39,8 @@ class QtTTSBackend(TTSBackend): self.tts.stop() def say(self, text: str) -> None: + self.last_word_offset = 0 + self.speaking_text = text self.tts.say(text) def error_message(self) -> str: @@ -90,7 +94,12 @@ class QtTTSBackend(TTSBackend): self._current_settings = settings def _saying_word(self, word: str, utterance_id: int, start: int, length: int) -> None: - self.saying.emit(start, length) + # Qt's word tracking is broken with non-BMP unicode chars, the + # start and length values are totally wrong, so track manually + idx = self.speaking_text.find(word, self.last_word_offset) + if idx > -1: + self.saying.emit(idx, len(word)) + self.last_word_offset = idx + len(word) def _state_changed(self, state: QTextToSpeech.State) -> None: self.state_changed.emit(state) diff --git a/src/calibre/gui2/tts2/types.py b/src/calibre/gui2/tts2/types.py index 345861cb7e..73c1a7c71c 100644 --- a/src/calibre/gui2/tts2/types.py +++ b/src/calibre/gui2/tts2/types.py @@ -180,9 +180,9 @@ def default_engine_name() -> str: return 'sapi' if tweaks.get('prefer_winsapi') else 'winrt' if ismacos: return 'darwin' - if 'flite' in available_engines(): - return 'flite' - return 'speechd' + if 'speechd' in available_engines(): + return 'speechd' + return 'flite' class TTSBackend(QObject):