Skip to content
This repository was archived by the owner on Sep 8, 2024. It is now read-only.

Commit ddcedae

Browse files
author
Ryan Sipes
authored
Merge pull request #174 from MycroftAI/revert-173-revert-172-feature/issues-128
Revert "Revert "Listener improvements (Fixes #128)""
2 parents 4e75906 + 159ece5 commit ddcedae

File tree

9 files changed

+229
-239
lines changed

9 files changed

+229
-239
lines changed

mycroft/client/enclosure/enclosure.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,16 +171,17 @@ def __init_serial(self):
171171

172172
def __register_events(self):
173173
self.client.on('mycroft.paired', self.__update_events)
174-
self.client.on('recognizer_loop:wakeword', self.eyes.blink)
175174
self.__register_mouth_events()
176175

177176
def __register_mouth_events(self):
178-
self.client.on('recognizer_loop:listening', self.mouth.listen)
177+
self.client.on('recognizer_loop:record_begin', self.mouth.listen)
178+
self.client.on('recognizer_loop:record_end', self.mouth.reset)
179179
self.client.on('recognizer_loop:audio_output_start', self.mouth.talk)
180180
self.client.on('recognizer_loop:audio_output_end', self.mouth.reset)
181181

182182
def __remove_mouth_events(self):
183-
self.client.remove('recognizer_loop:listening', self.mouth.listen)
183+
self.client.remove('recognizer_loop:record_begin', self.mouth.listen)
184+
self.client.remove('recognizer_loop:record_end', self.mouth.reset)
184185
self.client.remove('recognizer_loop:audio_output_start',
185186
self.mouth.talk)
186187
self.client.remove('recognizer_loop:audio_output_end',

mycroft/client/speech/listener.py

Lines changed: 16 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,12 @@
2424
import speech_recognition as sr
2525

2626
from mycroft.client.speech.local_recognizer import LocalRecognizer
27-
from mycroft.client.speech.mic import MutableMicrophone, Recognizer
27+
from mycroft.client.speech.mic import MutableMicrophone, ResponsiveRecognizer
2828
from mycroft.client.speech.recognizer_wrapper import \
2929
RemoteRecognizerWrapperFactory
30-
from mycroft.client.speech.word_extractor import WordExtractor
3130
from mycroft.configuration import ConfigurationManager
3231
from mycroft.messagebus.message import Message
33-
from mycroft.metrics import MetricsAggregator, Stopwatch
32+
from mycroft.metrics import MetricsAggregator
3433
from mycroft.session import SessionManager
3534
from mycroft.util import CerberusAccessDenied
3635
from mycroft.util.log import getLogger
@@ -62,8 +61,7 @@ def run(self):
6261
self.recognizer.adjust_for_ambient_noise(source)
6362
while self.state.running:
6463
try:
65-
self.emitter.emit("recognizer_loop:listening")
66-
audio = self.recognizer.listen(source)
64+
audio = self.recognizer.listen(source, self.emitter)
6765
self.queue.put(audio)
6866
except IOError, ex:
6967
# NOTE: Audio stack on raspi is slightly different, throws
@@ -105,73 +103,27 @@ def _audio_length(audio):
105103
audio.sample_rate * audio.sample_width)
106104

107105
def read_audio(self):
108-
timer = Stopwatch()
109-
audio = self.queue.get()
110-
self.metrics.timer("mycroft.recognizer.audio.length_s",
111-
self._audio_length(audio))
112-
self.queue.task_done()
113-
timer.start()
106+
audio_data = self.queue.get()
114107

115108
if self.state.sleeping:
116-
self.process_wake_up(audio)
117-
elif self.state.skip_wakeword:
118-
self.process_skip_wake_word(audio)
109+
self.try_wake_up(audio_data)
119110
else:
120-
self.process_wake_word(audio, timer)
111+
self.process_audio(audio_data)
121112

122-
self.metrics.flush()
123-
124-
def process_wake_up(self, audio):
113+
def try_wake_up(self, audio):
125114
if self.wakeup_recognizer.is_recognized(audio.frame_data,
126115
self.metrics):
127116
SessionManager.touch()
128117
self.state.sleeping = False
129118
self.__speak("I'm awake.") # TODO: Localization
130119
self.metrics.increment("mycroft.wakeup")
131120

132-
def process_wake_word(self, audio, timer):
133-
hyp = self.mycroft_recognizer.transcribe(audio.frame_data,
134-
self.metrics)
135-
136-
if self.mycroft_recognizer.contains(hyp):
137-
extractor = WordExtractor(audio, self.mycroft_recognizer,
138-
self.metrics)
139-
timer.lap()
140-
extractor.calculate_range()
141-
self.metrics.timer("mycroft.recognizer.extractor.time_s",
142-
timer.lap())
143-
audio_before = extractor.get_audio_data_before()
144-
self.metrics.timer("mycroft.recognizer.audio_extracted.length_s",
145-
self._audio_length(audio_before))
146-
audio_after = extractor.get_audio_data_after()
147-
self.metrics.timer("mycroft.recognizer.audio_extracted.length_s",
148-
self._audio_length(audio_after))
149-
150-
SessionManager.touch()
151-
payload = {
152-
'utterance': hyp.hypstr,
153-
'session': SessionManager.get().session_id,
154-
'pos_begin': extractor.begin,
155-
'pos_end': extractor.end
156-
}
157-
self.emitter.emit("recognizer_loop:wakeword", payload)
158-
159-
try:
160-
self.transcribe([audio_before, audio_after])
161-
except sr.UnknownValueError:
162-
self.__speak("Go ahead")
163-
self.state.skip_wakeword = True
164-
self.metrics.increment("mycroft.wakeword")
165-
166-
def process_skip_wake_word(self, audio):
167-
SessionManager.touch()
121+
def process_audio(self, audio):
168122
try:
169123
self.transcribe([audio])
170-
except sr.UnknownValueError:
124+
except sr.UnknownValueError: # TODO: Localization
171125
logger.warn("Speech Recognition could not understand audio")
172126
self.__speak("Sorry, I didn't catch that.")
173-
self.metrics.increment("mycroft.recognizer.error")
174-
self.state.skip_wakeword = False
175127

176128
def __speak(self, utterance):
177129
payload = {
@@ -184,18 +136,18 @@ def _create_remote_stt_runnable(self, audio, utterances):
184136
def runnable():
185137
try:
186138
text = self.remote_recognizer.transcribe(
187-
audio, metrics=self.metrics).lower()
139+
audio, metrics=self.metrics).lower()
188140
except sr.UnknownValueError:
189141
pass
190142
except sr.RequestError as e:
191143
logger.error(
192-
"Could not request results from Speech Recognition "
193-
"service; {0}".format(e))
144+
"Could not request results from Speech Recognition "
145+
"service; {0}".format(e))
194146
except CerberusAccessDenied as e:
195147
logger.error("AccessDenied from Cerberus proxy.")
196148
self.__speak(
197-
"Your device is not registered yet. To start pairing, "
198-
"login at cerberus dot mycroft dot A.I")
149+
"Your device is not registered yet. To start pairing, "
150+
"login at cerberus dot mycroft dot A.I")
199151
utterances.append("pair my device")
200152
except Exception as e:
201153
logger.error("Unexpected exception: {0}".format(e))
@@ -253,7 +205,7 @@ def __init__(self, channels=int(speech_config.get('channels')),
253205
self.mycroft_recognizer = LocalRecognizer(sample_rate, lang)
254206
# TODO - localization
255207
self.wakeup_recognizer = LocalRecognizer(sample_rate, lang, "wake up")
256-
self.remote_recognizer = Recognizer()
208+
self.remote_recognizer = ResponsiveRecognizer(self.mycroft_recognizer)
257209
self.state = RecognizerLoopState()
258210

259211
def start_async(self):
@@ -270,7 +222,7 @@ def start_async(self):
270222
self.wakeup_recognizer,
271223
self.mycroft_recognizer,
272224
RemoteRecognizerWrapperFactory.wrap_recognizer(
273-
self.remote_recognizer)).start()
225+
self.remote_recognizer)).start()
274226

275227
def stop(self):
276228
self.state.running = False

mycroft/client/speech/local_recognizer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,5 @@ def is_recognized(self, byte_data, metrics):
5959
hyp = self.transcribe(byte_data, metrics)
6060
return hyp and self.key_phrase in hyp.hypstr.lower()
6161

62-
def contains(self, hypothesis):
62+
def found_wake_word(self, hypothesis):
6363
return hypothesis and self.key_phrase in hypothesis.hypstr.lower()

mycroft/client/speech/main.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@
3535
config = ConfigurationManager.get()
3636

3737

38-
def handle_listening():
39-
logger.info("Listening...")
40-
client.emit(Message('recognizer_loop:listening'))
38+
def handle_record_begin():
39+
logger.info("Begin Recording...")
40+
client.emit(Message('recognizer_loop:record_begin'))
4141

4242

43-
def handle_wakeword(event):
44-
logger.info("Wakeword Detected: " + event['utterance'])
45-
client.emit(Message('recognizer_loop:wakeword', event))
43+
def handle_record_end():
44+
logger.info("End Recording...")
45+
client.emit(Message('recognizer_loop:record_end'))
4646

4747

4848
def handle_utterance(event):
@@ -93,9 +93,9 @@ def main():
9393
if device_index:
9494
device_index = int(device_index)
9595
loop = RecognizerLoop(device_index=device_index)
96-
loop.on('recognizer_loop:listening', handle_listening)
97-
loop.on('recognizer_loop:wakeword', handle_wakeword)
9896
loop.on('recognizer_loop:utterance', handle_utterance)
97+
loop.on('recognizer_loop:record_begin', handle_record_begin)
98+
loop.on('recognizer_loop:record_end', handle_record_end)
9999
loop.on('speak', handle_speak)
100100
client.on('speak', handle_speak)
101101
client.on(

0 commit comments

Comments
 (0)