def listen(self, duration=9, timeout=3):
        vad.reset()

        self.listen_countdown[0] = (duration * self.sample_rate +
                                    self.frames_per_buffer -
                                    1) / self.frames_per_buffer
        self.listen_countdown[1] = (timeout * self.sample_rate +
                                    self.frames_per_buffer -
                                    1) / self.frames_per_buffer

        self.listen_queue.queue.clear()
        self.status |= self.listening_mask
        self.start()
        pixel_ring.listen()

        logger.info('Start listening')

        def _listen():
            try:
                data = self.listen_queue.get(timeout=timeout)
                while data and not self.quit_event.is_set():
                    yield data
                    data = self.listen_queue.get(timeout=timeout)
            except Queue.Empty:
                pass

            self.stop()

        return _listen()
Exemple #2
0
    def listen(self, duration=9, timeout=1):
        vad.reset()

        self.listen_countdown[0] = duration * self.buffers_per_sec
        self.listen_countdown[1] = timeout * self.buffers_per_sec

        self.listen_queue.queue.clear()
        self.status |= self.listening_mask
        self.start()

        logger.info('Start listening')
        self.start_speeking = 0

        def _listen():
            try:
                data = self.listen_queue.get(timeout=3)
                while data and not self.quit_event.is_set():
                    yield data
                    data = self.listen_queue.get(timeout=3)
            except Queue.Empty:
                pass

            self.stop()

        return _listen()
    def start(self,
              detected_callback=play_audio_file,
              interrupt_check=lambda: False,
              sleep_time=0.03):
        """
        Start the voice detector. For every `sleep_time` second it checks the
        audio buffer for triggering keywords. If detected, then call
        corresponding function in `detected_callback`, which can be a single
        function (single model) or a list of callback functions (multiple
        models). Every loop it also calls `interrupt_check` -- if it returns
        True, then breaks from the loop and return.

        :param detected_callback: a function or list of functions. The number of
                                  items must match the number of models in
                                  `decoder_model`.
        :param interrupt_check: a function that returns True if the main loop
                                needs to stop.
        :param float sleep_time: how much time in second every loop waits.
        :return: None
        """
        if interrupt_check():
            logger.debug("detect voice return")
            return

        tc = type(detected_callback)
        if tc is not list:
            detected_callback = [detected_callback]
        if len(detected_callback) == 1 and self.num_hotwords > 1:
            detected_callback *= self.num_hotwords

        assert self.num_hotwords == len(detected_callback), \
            "Error: hotwords in your models (%d) do not match the number of " \
            "callbacks (%d)" % (self.num_hotwords, len(detected_callback))

        logger.debug("detecting...")

        while True:
            if interrupt_check():
                logger.debug("detect voice break")
                break
            data = self.ring_buffer.get()
            if len(data) == 0:
                time.sleep(sleep_time)
                continue

            ans = self.detector.RunDetection(data)
            if ans == -1:
                logger.warning(
                    "Error initializing streams or reading audio data")
            elif ans > 0:
                message = "Keyword " + str(ans) + " detected at time: "
                message += time.strftime("%Y-%m-%d %H:%M:%S",
                                         time.localtime(time.time()))
                logger.info(message)
                play_audio_file(fname=DETECT_DING)
                callback = detected_callback[ans - 1]
                if callback is not None:
                    listen = True
                    listen_history = []
                    cnt = 0
                    VAD_DELAY = 0.2
                    MAX_CNT = int(3 / VAD_DELAY)
                    vad_trig = False
                    vad.reset()
                    while listen:
                        data = self.ring_buffer.get()
                        active = vad.is_speech(data)
                        if active and cnt > 1:
                            vad_trig = True
                        ans = self.detector.RunDetection(data)
                        logger.info("Detection status: %d, VAD: %s" %
                                    (ans, active))
                        if ans == 1:
                            listen_history = []
                            continue
                        elif ans == 0:
                            listen_history.extend(data)
                            cnt += 1
                            if cnt > MAX_CNT:
                                listen = False
                            elif vad_trig and not active:
                                listen = False
                        elif ans == -2:
                            if not vad_trig:
                                listen_history = []
                                cnt += 1
                                if cnt > MAX_CNT:
                                    listen = False
                                # elif vad_trig and not active:
                                #     listen_history.extend(data)
                                else:
                                    time.sleep(VAD_DELAY)
                                    continue
                            listen = False
                        time.sleep(VAD_DELAY)
                    if len(listen_history) > 0:
                        callback(listen_history,
                                 rate=self.detector.SampleRate())