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.pull/1293/head
parent
8c8691e51c
commit
9ed40010fa
|
@ -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'(?<!\w\.\w.)(?<![A-Z][a-z]\.)(?<=\.|\?)\s',
|
||||
utterance)
|
||||
for chunk in chunks:
|
||||
try:
|
||||
mute_and_speak(chunk)
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except:
|
||||
LOG.error('Error in mute_and_speak', exc_info=True)
|
||||
if _last_stop_signal > 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'(?<!\w\.\w.)(?<![A-Z][a-z]\.)(?<=\.|\?)\s',
|
||||
utterance)
|
||||
for chunk in chunks:
|
||||
try:
|
||||
mute_and_speak(chunk)
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except:
|
||||
LOG.error('Error in mute_and_speak', exc_info=True)
|
||||
if (_last_stop_signal > 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):
|
||||
|
|
Loading…
Reference in New Issue