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()
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())