예제 #1
0
 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")
예제 #2
0
    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")
예제 #3
0
파일: wake.py 프로젝트: swipswaps/rhasspy
    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")
예제 #4
0
    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")
예제 #5
0
파일: wake.py 프로젝트: swipswaps/rhasspy
    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")
예제 #6
0
파일: wake.py 프로젝트: swipswaps/rhasspy
    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")
예제 #7
0
    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")
예제 #8
0
 def to_stopped(self, from_state: str) -> None:
     """Transition to stopped state."""
     # Stop recording
     self.send(self.recorder, StopStreaming(self.myAddress))