def in_listening(self, message: Any, sender: RhasspyActor) -> None: """Handle messages in listening state.""" if isinstance(message, AudioData): self.buffer += message.data elif isinstance(message, WakeupMessage): if message.payload == self.timeout_id: # Timeout self._logger.warning("Timeout") self.send(self.recorder, StopStreaming(self.myAddress)) self.send( self.receiver, VoiceCommand(self.buffer, timeout=True, handle=self.handle), ) self.transition("started") elif isinstance(message, MqttMessage): if message.topic == self.stop_topic: # stopListening payload_json = json.loads(message.payload) if payload_json.get("siteId", "default") in self.site_ids: self._logger.debug("Received stopListening") self.send(self.recorder, StopStreaming(self.myAddress)) self.send( self.receiver, VoiceCommand(self.buffer, handle=self.handle) ) self.transition("started")
def in_listening(self, message: Any, sender: RhasspyActor) -> None: """Handle messages in listening state.""" if isinstance(message, AudioData): if not self.decoder_started: assert self.decoder is not None self.decoder.start_utt() self.decoder_started = True audio_data = message.data chunk = audio_data[:self.chunk_size] detected = False while chunk: result = self.process_data(chunk) if result is not None: detected = True self._logger.debug("Hotword detected (%s)", self.keyphrase) detected_msg = WakeWordDetected( self.keyphrase, audio_data_info=message.info) for receiver in self.receivers: self.send(receiver, detected_msg) break audio_data = audio_data[self.chunk_size:] chunk = audio_data[:self.chunk_size] # End utterance if detected and self.decoder_started: assert self.decoder is not None self.decoder.end_utt() self.decoder_started = False if not detected and self.not_detected: # Report non-detection not_detected_msg = WakeWordNotDetected( self.keyphrase, audio_data_info=message.info) for receiver in self.receivers: self.send(receiver, not_detected_msg) elif isinstance(message, StopListeningForWakeWord): if message.clear_all: self.receivers.clear() else: try: self.receivers.remove(message.receiver or sender) except ValueError: pass if not self.receivers: # End utterance if self.decoder_started: assert self.decoder is not None self.decoder.end_utt() self.decoder_started = False if message.record: self.send(self.recorder, StopStreaming(self.myAddress)) self.transition("loaded") elif isinstance(message, PauseListeningForWakeWord): self.transition("paused")
def in_listening(self, message: Any, sender: RhasspyActor) -> None: """Handle messages in listening state.""" if isinstance(message, AudioData): audio_data = message.data chunk = audio_data[: self.chunk_size] detected = [] while chunk: for detector_index, result_index in enumerate(self.process_data(chunk)): if result_index > 0: detected.append(detector_index) if detected: # Don't process the rest of the audio data if hotword has # already been detected. break audio_data = audio_data[self.chunk_size :] chunk = audio_data[: self.chunk_size] # Handle results if detected: # Detected detected_names = [self.model_names[i] for i in detected] self._logger.debug("Hotword(s) detected: %s", detected_names) # Send events for model_name in detected_names: detected_event = WakeWordDetected( model_name, audio_data_info=message.info ) for receiver in self.receivers: self.send(receiver, detected_event) if self.single_detection: # Only allow for a single hotword to be detected break elif self.not_detected: # Not detected for model_name in self.model_names: not_detected_event = WakeWordNotDetected( model_name, audio_data_info=message.info ) for receiver in self.receivers: self.send(receiver, not_detected_event) elif isinstance(message, StopListeningForWakeWord): if message.clear_all: self.receivers.clear() else: try: self.receivers.remove(message.receiver or sender) except ValueError: pass if not self.receivers: if message.record: self.send(self.recorder, StopStreaming(self.myAddress)) self.transition("loaded") elif isinstance(message, PauseListeningForWakeWord): self.transition("paused")
def in_listening(self, message: Any, sender: RhasspyActor) -> None: """Handle messages in listening state.""" if isinstance(message, AudioData): assert self.receiver is not None self.transition("started") self.send(self.recorder, StopStreaming(self.myAddress)) self._logger.debug("Received %s byte(s) of audio data", len(message.data)) self.send(self.receiver, VoiceCommand(message.data, self.handle)) elif isinstance(message, WakeupMessage): # Timeout self._logger.warning("Timeout") self.send(self.recorder, StopStreaming(self.myAddress)) self.send( self.receiver, VoiceCommand(bytes(), timeout=True, handle=self.handle) ) self.transition("started")
def in_listening(self, message: Any, sender: RhasspyActor) -> None: """Handle messages in listening state.""" if isinstance(message, AudioData): self.audio_buffer += message.data num_chunks = len(self.audio_buffer) // self.chunk_size if num_chunks > 0: assert self.handle is not None for _ in range(num_chunks): chunk = self.audio_buffer[: self.chunk_size] unpacked_chunk = struct.unpack_from(self.chunk_format, chunk) self.audio_buffer = self.audio_buffer[self.chunk_size :] # Process chunk keyword_index = self.handle.process(unpacked_chunk) if keyword_index: if len(self.keyword_paths) == 1: keyword_index = 0 wakeword_name = str(keyword_index) if keyword_index < len(self.keyword_paths): wakeword_name = self.keyword_paths[keyword_index].stem # Pass downstream to receivers self._logger.debug("Hotword detected (%s)", keyword_index) result = WakeWordDetected(wakeword_name) for receiver in self.receivers: self.send(receiver, result) elif isinstance(message, WakeWordDetected): # Pass downstream to receivers self._logger.debug("Hotword detected (%s)", message.name) for receiver in self.receivers: self.send(receiver, message) elif isinstance(message, WakeWordNotDetected): # Pass downstream to receivers for receiver in self.receivers: self.send(receiver, message) elif isinstance(message, StopListeningForWakeWord): if message.clear_all: self.receivers.clear() else: try: self.receivers.remove(message.receiver or sender) except ValueError: pass if not self.receivers: if message.record: self.send(self.recorder, StopStreaming(self.myAddress)) if self.handle is not None: self.handle.delete() self.handle = None self.transition("started") elif isinstance(message, PauseListeningForWakeWord): self.transition("paused")
def in_listening(self, message: Any, sender: RhasspyActor) -> None: """Handle messages in listening state.""" try: if isinstance(message, AudioData): self.audio_info = message.info self.detected = False self.audio_buffer += message.data num_chunks = len(self.audio_buffer) // self.chunk_size if num_chunks > 0: assert self.stream is not None self.prediction_sem = threading.Semaphore() for _ in range(num_chunks): chunk = self.audio_buffer[: self.chunk_size] if chunk: self.stream.write(chunk) self.audio_buffer = self.audio_buffer[self.chunk_size :] if self.send_not_detected: # Wait for all chunks to finish processing for _ in range(num_chunks): self.prediction_sem.acquire(timeout=0.1) # Wait a little bit for the precise engine to finish processing time.sleep(self.chunk_delay) if not self.detected: # Not detected not_detected_event = WakeWordNotDetected( self.model_name, audio_data_info=message.info ) for receiver in self.receivers: self.send(receiver, not_detected_event) elif isinstance(message, StopListeningForWakeWord): if message.clear_all: self.receivers.clear() else: try: self.receivers.remove(message.receiver or sender) except ValueError: pass if not self.receivers: if message.record: self.send(self.recorder, StopStreaming(self.myAddress)) self.transition("loaded") elif isinstance(message, str): # Detected self._logger.debug("Hotword detected (%s)", self.model_name) detected_event = WakeWordDetected( self.model_name, audio_data_info=self.audio_info ) for receiver in self.receivers: self.send(receiver, detected_event) elif isinstance(message, PauseListeningForWakeWord): self.transition("paused") except Exception: self._logger.exception("in_listening")
def in_listening(self, message: Any, sender: RhasspyActor) -> None: """Handle messages in listening state.""" if isinstance(message, WakeupMessage): if message.payload == self.timeout_id: # Timeout self._logger.warning("Timeout") self.send(self.recorder, StopStreaming(self.myAddress)) self.send( self.receiver, VoiceCommand( self.buffer or bytes(), timeout=True, handle=self.handle ), ) self.buffer = bytes() self.transition("loaded") elif isinstance(message, AudioData): self.chunk += message.data if len(self.chunk) >= self.chunk_size: # Ensure audio data is properly chunked (for webrtcvad) data = self.chunk[: self.chunk_size] self.chunk = self.chunk[self.chunk_size :] # Process chunk finished = self.process_data(data) if finished: # Stop recording self.send(self.recorder, StopStreaming(self.myAddress)) # Response self.send( self.receiver, VoiceCommand(self.buffer, timeout=False, handle=self.handle), ) self.buffer = bytes() self.transition("loaded")
def to_stopped(self, from_state: str) -> None: """Transition to stopped state.""" # Stop recording self.send(self.recorder, StopStreaming(self.myAddress))