macOS: Workaround for Apple being unable to resume speech after changing the voice

This commit is contained in:
Kovid Goyal 2020-12-07 15:50:46 +05:30
parent c8306289f9
commit ed4a397de1
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 24 additions and 2 deletions

View File

@ -166,6 +166,7 @@ class Client:
text = self.current_marked_text[idx:]
self.ensure_state(use_ssml=True)
self.ssip_client.speak(wrap_in_ssml(text), callback=self.current_callback)
resume_after_configure = resume
def stop(self):
self.current_callback = self.current_marked_text = self.last_mark = None

View File

@ -21,6 +21,7 @@ class Client:
self.default_system_rate = self.nsss.get_current_rate()
self.default_system_voice = self.nsss.get_current_voice()
self.current_callback = None
self.current_marked_text = self.last_mark = None
self.dispatch_on_main_thread = dispatch_on_main_thread
self.status = {'synthesizing': False, 'paused': False}
self.apply_settings(settings)
@ -38,6 +39,7 @@ class Client:
from calibre_extensions.cocoa import MARK, END
event = None
if message_type == MARK:
self.last_mark = data
if data == self.END_MARK:
event = Event(EventType.end)
self.status = {'synthesizing': False, 'paused': False}
@ -56,6 +58,7 @@ class Client:
def speak_simple_text(self, text):
self.current_callback = None
self.current_marked_text = self.last_mark = None
self.nsss.speak(self.escape_marked_text(text))
self.status = {'synthesizing': True, 'paused': False}
@ -64,6 +67,8 @@ class Client:
# on macOS didFinishSpeaking is never called for some reason, so work
# around it by adding an extra, special mark at the end
text += self.mark_template.format(self.END_MARK)
self.current_marked_text = text
self.last_mark = None
self.nsss.speak(text)
self.status = {'synthesizing': True, 'paused': False}
self.current_callback(Event(EventType.begin))
@ -82,6 +87,19 @@ class Client:
if self.current_callback is not None:
self.current_callback(Event(EventType.resume))
def resume_after_configure(self):
if self.status['paused'] and self.last_mark is not None and self.current_marked_text:
mark = self.mark_template.format(self.last_mark)
idx = self.current_marked_text.find(mark)
if idx == -1:
text = self.current_marked_text
else:
text = self.current_marked_text[idx:]
self.nsss.speak(text)
self.status = {'synthesizing': True, 'paused': False}
if self.current_callback is not None:
self.current_callback(Event(EventType.resume))
def stop(self):
self.nsss.stop()

View File

@ -100,6 +100,9 @@ class TTS(QObject):
def resume(self, data):
self.tts_client.resume()
def resume_after_configure(self, data):
self.tts_client.resume_after_configure()
def callback(self, event):
data = event.data
if event.type is event.type.mark:

View File

@ -137,7 +137,8 @@ class ReadAloud:
def play(self):
if self.state is PAUSED:
ui_operations.tts('resume')
ui_operations.tts('resume_after_configure' if self.waiting_for_configure else 'resume')
self.waiting_for_configure = False
self.state = PLAYING
elif self.state is STOPPED:
self.send_message('play')
@ -203,7 +204,6 @@ class ReadAloud:
self.view.show_next_spine_item()
elif which is 'configured':
if self.waiting_for_configure:
self.waiting_for_configure = False
self.play()
if data is not None:
pass