9 import speech_recognition as sr
11 logger = logging.getLogger(__file__)
14 class HotwordListener(object):
20 input_device_index=None,
21 library_path=pvporcupine.LIBRARY_PATH,
22 model_path=pvporcupine.MODEL_PATH,
24 self._queue = command_queue
25 self._library_path = library_path
26 self._model_path = model_path
27 self._keyword_paths = keyword_paths
28 self._sensitivities = sensitivities
29 self._input_device_index = input_device_index
31 def listen_forever(self):
33 for x in self._keyword_paths:
34 keywords.append(os.path.basename(x).replace(".ppn", "").split("_")[0])
40 porcupine = pvporcupine.create(
41 library_path=self._library_path,
42 model_path=self._model_path,
43 keyword_paths=self._keyword_paths,
44 sensitivities=self._sensitivities,
46 recognizer = sr.Recognizer()
47 pa = pyaudio.PyAudio()
49 audio_stream = pa.open(
50 rate=porcupine.sample_rate,
52 format=pyaudio.paInt16,
54 frames_per_buffer=porcupine.frame_length,
55 input_device_index=self._input_device_index,
58 logger.info("Listening {")
59 for keyword, sensitivity in zip(keywords, self._sensitivities):
60 logger.info(" %s (%.2f)" % (keyword, sensitivity))
64 raw = audio_stream.read(
65 porcupine.frame_length, exception_on_overflow=False
67 pcm = struct.unpack_from("h" * porcupine.frame_length, raw)
68 result = porcupine.process(pcm)
70 cmd = "aplay /var/www/kiosk/attention.wav"
72 "Running %s (attention tone) because I heard the wake-word", cmd
76 ">>>>>>>>>>>>> Detected wakeword %s" % keywords[result]
80 0, int(porcupine.sample_rate / porcupine.frame_length * 4)
82 raw += audio_stream.read(
83 porcupine.frame_length, exception_on_overflow=False
86 f">>>>>>>>>>>>>> Recognizing command... {len(raw)} bytes"
88 speech = sr.AudioData(
89 frame_data=bytes(raw),
90 sample_rate=porcupine.sample_rate,
91 sample_width=2, # 16 bits
93 command = recognizer.recognize_google(speech)
94 logger.debug(">>>>>>>>>>>>> Google says command was %s" % command)
95 logger.info("Enqueued command=%s", command)
96 self._queue.put(command)
99 logger.exception("Stopping listener because of unexpected exception!")
101 except KeyboardInterrupt:
102 logger.exception("Stopping listener because of ^C!")
105 logger.debug("Cleaning up... one sec...")
106 if porcupine is not None:
109 if audio_stream is not None:
116 def show_audio_devices(cls):
117 fields = ("index", "name", "defaultSampleRate", "maxInputChannels")
118 pa = pyaudio.PyAudio()
119 for i in range(pa.get_device_count()):
120 info = pa.get_device_info_by_index(i)
121 print(", ".join("'%s': '%s'" % (k, str(info[k])) for k in fields))
126 keyword_paths = [pvporcupine.KEYWORD_PATHS[x] for x in ["blueberry", "bumblebee"]]
127 sensitivities = [0.85, 0.95]
135 if __name__ == "__main__":