From 9ed40010fafd7384b4cfb2a006dd923b36089551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=85ke=20Forslund?= Date: Thu, 7 Dec 2017 20:34:32 +0100 Subject: [PATCH] Fix lock around speech. the lock could be taken by a waiting thread between sentences in a multi-sentenced utterance. This locking method will allow the entire utterance to be synthezised before handling next. --- mycroft/audio/speech.py | 68 ++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/mycroft/audio/speech.py b/mycroft/audio/speech.py index 3299ba4ed7..d2f2e39829 100644 --- a/mycroft/audio/speech.py +++ b/mycroft/audio/speech.py @@ -45,38 +45,40 @@ def handle_speak(event): Configuration.init(ws) global _last_stop_signal - # Mild abuse of the signal system to allow other processes to detect - # when TTS is happening. See mycroft.util.is_speaking() + with lock: + # Mild abuse of the signal system to allow other processes to detect + # when TTS is happening. See mycroft.util.is_speaking() - utterance = event.data['utterance'] - if event.data.get('expect_response', False): - # When expect_response is requested, the listener will be restarted - # at the end of the next bit of spoken audio. - ws.once('recognizer_loop:audio_output_end', _start_listener) + utterance = event.data['utterance'] + if event.data.get('expect_response', False): + # When expect_response is requested, the listener will be restarted + # at the end of the next bit of spoken audio. + ws.once('recognizer_loop:audio_output_end', _start_listener) - # This is a bit of a hack for Picroft. The analog audio on a Pi blocks - # for 30 seconds fairly often, so we don't want to break on periods - # (decreasing the chance of encountering the block). But we will - # keep the split for non-Picroft installs since it give user feedback - # faster on longer phrases. - # - # TODO: Remove or make an option? This is really a hack, anyway, - # so we likely will want to get rid of this when not running on Mimic - if not config.get('enclosure', {}).get('platform') == "picroft": - start = time.time() - chunks = re.split(r'(? start or check_for_signal('buttonPress'): - break - else: - mute_and_speak(utterance) + # This is a bit of a hack for Picroft. The analog audio on a Pi blocks + # for 30 seconds fairly often, so we don't want to break on periods + # (decreasing the chance of encountering the block). But we will + # keep the split for non-Picroft installs since it give user feedback + # faster on longer phrases. + # + # TODO: Remove or make an option? This is really a hack, anyway, + # so we likely will want to get rid of this when not running on Mimic + if not config.get('enclosure', {}).get('platform') == "picroft": + start = time.time() + chunks = re.split(r'(? start or + check_for_signal('buttonPress')): + break + else: + mute_and_speak(utterance) def mute_and_speak(utterance): @@ -88,7 +90,6 @@ def mute_and_speak(utterance): """ global tts_hash - lock.acquire() # update TTS object if configuration has changed if tts_hash != hash(str(config.get('tts', ''))): global tts @@ -101,10 +102,7 @@ def mute_and_speak(utterance): tts_hash = hash(str(config.get('tts', ''))) LOG.info("Speak: " + utterance) - try: - tts.execute(utterance) - finally: - lock.release() + tts.execute(utterance) def handle_stop(event):