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, WakeupMessage):
            # 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, timeout = self.process_data(data)

                if finished:
                    # Stop recording
                    self.send(self.recorder, StopStreaming(self.myAddress))

                    # Response
                    self.send(self.receiver,
                              VoiceCommand(self.buffer, timeout, self.handle))

                    self.buffer = bytes()
                    self.transition("loaded")
示例#3
0
    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 = False
            while len(chunk) > 0:
                index = self.process_data(chunk)
                if index > 0:
                    detected = True
                    break

                audio_data = audio_data[self.chunk_size:]
                chunk = audio_data[:self.chunk_size]

            if detected:
                # Detected
                self._logger.debug("Hotword detected (%s)", self.model_name)
                detected_event = WakeWordDetected(self.model_name,
                                                  audio_data_info=message.info)
                for receiver in self.receivers:
                    self.send(receiver, detected_event)
            elif self.not_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):
            self.receivers.remove(message.receiver or sender)
            if len(self.receivers) == 0:
                if message.record:
                    self.send(self.recorder, StopStreaming(self.myAddress))
                self.transition("loaded")
    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
    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 len(chunk) > 0:
                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):
            self.receivers.remove(message.receiver or sender)
            if len(self.receivers) == 0:
                # 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")
示例#6
0
    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]
                        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):
                self.receivers.remove(message.receiver or sender)
                if len(self.receivers) == 0:
                    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)
        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, AudioData):
            audio_data = message.data
            chunk = audio_data[:self.chunk_size]
            detected = []
            while len(chunk) > 0:
                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)
            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):
            self.receivers.remove(message.receiver or sender)
            if len(self.receivers) == 0:
                if message.record:
                    self.send(self.recorder, StopStreaming(self.myAddress))
                self.transition("loaded")
示例#8
0
    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:
                        # Pass downstream to receivers
                        self._logger.debug("Hotword detected (%s)",
                                           keyword_index)
                        result = WakeWordDetected(str(keyword_index))
                        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):
            self.receivers.remove(message.receiver or sender)
            if len(self.receivers) == 0:
                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")
 def to_stopped(self, from_state: str) -> None:
     """Transition to stopped state."""
     # Stop recording
     self.send(self.recorder, StopStreaming(self.myAddress))