Return status from wakeword as tuple

- Return the data from the wakeword as a tuple.
- Extract post wakeword actions from wait for wakeword method
pull/2589/head
Åke Forslund 2020-05-12 20:32:02 +02:00
parent 567e08809a
commit dbf2bf45b1
1 changed files with 32 additions and 20 deletions

View File

@ -15,7 +15,7 @@
import audioop
from time import sleep, time as get_time
from collections import deque
from collections import deque, namedtuple
import datetime
import json
import os
@ -47,6 +47,10 @@ from mycroft.util.log import LOG
from .data_structures import RollingMean, CyclicAudioBuffer
WakeWordData = namedtuple('WakeWordData',
['audio', 'found', 'stopped', 'end_audio'])
class MutableStream:
def __init__(self, wrapped_stream, format, muted=False):
assert wrapped_stream is not None
@ -436,9 +440,7 @@ class ResponsiveRecognizer(speech_recognition.Recognizer):
return False
def stop(self):
"""
Signal stop and exit waiting state.
"""
"""Signal stop and exit waiting state."""
self._stop_signaled = True
def _compile_metadata(self):
@ -501,14 +503,13 @@ class ResponsiveRecognizer(speech_recognition.Recognizer):
with open(filename, 'wb') as f:
f.write(audio.get_wav_data())
def _handle_wakeword_found(self, audio_data, source, emitter):
def _handle_wakeword_found(self, audio_data, source):
"""Perform actions to be triggered after a wakeword is found.
This includes: emit event on messagebus that a wakeword is heard,
store wakeword to disk if configured and sending the wakeword data
to the cloud in case the user has opted into the data sharing.
"""
self._send_wakeword_info(emitter)
# Save and upload positive wake words as appropriate
upload_allowed = (self.config['opt_in'] and not self.upload_disabled)
if (self.save_wake_words or upload_allowed):
@ -521,7 +522,7 @@ class ResponsiveRecognizer(speech_recognition.Recognizer):
if upload_allowed:
self._upload_wakeword(audio, metadata)
def _wait_until_wake_word(self, source, sec_per_buffer, emitter):
def _wait_until_wake_word(self, source, sec_per_buffer):
"""Listen continuously on source until a wake word is spoken
Args:
@ -585,10 +586,9 @@ class ResponsiveRecognizer(speech_recognition.Recognizer):
said_wake_word = \
self.wake_word_recognizer.found_wake_word(audio_data)
if said_wake_word:
self._handle_wakeword_found(audio_data, source, emitter)
return ww_frames
self._listen_triggered = False
return WakeWordData(audio_data, said_wake_word,
self._stopped, ww_frames)
@staticmethod
def _create_audio_data(raw_data, source):
@ -598,6 +598,17 @@ class ResponsiveRecognizer(speech_recognition.Recognizer):
"""
return AudioData(raw_data, source.SAMPLE_RATE, source.SAMPLE_WIDTH)
def mute_and_confirm_listening(self, source):
audio_file = resolve_resource_file(
self.config.get('sounds').get('start_listening'))
if audio_file:
source.mute()
play_wav(audio_file).wait()
source.unmute()
return True
else:
return False
def listen(self, source, emitter, stream=None):
"""Listens for chunks of audio that Mycroft should perform STT on.
@ -629,22 +640,23 @@ class ResponsiveRecognizer(speech_recognition.Recognizer):
self.adjust_for_ambient_noise(source, 1.0)
LOG.debug("Waiting for wake word...")
ww_frames = self._wait_until_wake_word(source, sec_per_buffer, emitter)
ww_data = self._wait_until_wake_word(source, sec_per_buffer)
self._listen_triggered = False
if self._stop_signaled:
ww_frames = None
if ww_data.found:
# If the wakeword was heard send it
self._send_wakeword_info(emitter)
self._handle_wakeword_found(ww_data.audio, source)
ww_frames = ww_data.end_audio
if ww_data.stopped:
# If the waiting returned from a stop signal
return
LOG.debug("Recording...")
# If enabled, play a wave file with a short sound to audibly
# indicate recording has begun.
if self.config.get('confirm_listening'):
audio_file = resolve_resource_file(
self.config.get('sounds').get('start_listening'))
if audio_file:
source.mute()
play_wav(audio_file).wait()
source.unmute()
if self.mute_and_confirm_listening(source):
# Clear frames from wakeword detctions since they're
# irrelevant after mute - play wav - unmute sequence
ww_frames = None