def test_process_multiple(self): keyword_file_names = ['alexa', 'americano', 'avocado', 'blueberry', 'bumblebee', 'caterpillar', 'christina', 'dragonfly', 'flamingo', 'francesca', 'grapefruit', 'grasshopper', 'iguana', 'picovoice', 'pineapple', 'porcupine', 'raspberry', 'terminator', 'vancouver'] keyword_file_paths = [ self._abs_path('../../resources/keyword_files/%s_%s.ppn' % (name, self._keyword_file_extension())) for name in keyword_file_names] porcupine = Porcupine( library_path=self._library_path(), model_file_path=self._abs_path('../../lib/common/porcupine_params.pv'), keyword_file_paths=keyword_file_paths, sensitivities=[0.5] * len(keyword_file_paths)) audio, sample_rate = soundfile.read( self._abs_path('../../resources/audio_samples/multiple_keywords.wav'), dtype='int16') assert sample_rate == porcupine.sample_rate num_frames = len(audio) // porcupine.frame_length results = [] for i in range(num_frames): frame = audio[i * porcupine.frame_length:(i + 1) * porcupine.frame_length] result = porcupine.process(frame) if result >= 0: results.append(result) self.assertEqual(results, [15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]) porcupine.delete()
def test_process(self): porcupine = Porcupine( library_path=self._library_path(), model_file_path=self._abs_path('../../lib/common/porcupine_params.pv'), keyword_file_path=self._abs_path('../../resources/keyword_files/porcupine_%s.ppn' % self._keyword_file_extension()), sensitivity=0.5) audio, sample_rate = soundfile.read( self._abs_path('../../resources/audio_samples/porcupine.wav'), dtype='int16') assert sample_rate == porcupine.sample_rate num_frames = len(audio) // porcupine.frame_length results = [] for i in range(num_frames): frame = audio[i * porcupine.frame_length:(i + 1) * porcupine.frame_length] results.append(porcupine.process(frame)) porcupine.delete() self.assertEqual(sum(results), 1)
def _run(input_audio_file_path, library_path, model_file_path, keyword_file_paths, sensitivity): """ Monitors an input audio file for occurances of keywords for which keyword files are provided and prints their occurrence time (in seconds from start of file). :param input_audio_file_path: Absolute path to input audio file. The file should have a sample rate of 16000 and be single-channel. :param library_path: Absolute path to Porcupine's dynamic library. :param model_file_path: Absolute path to the model parameter file. :param keyword_file_paths: List of absolute paths to keyword files. :param sensitivity: Sensitivity parameter. For more information refer to 'include/pv_porcupine.h'. It uses the same sensitivity value for all keywords. :return: """ num_keywords = len(keyword_file_paths) porcupine = Porcupine( library_path=library_path, model_file_path=model_file_path, keyword_file_paths=keyword_file_paths, sensitivities=[sensitivity] * num_keywords) def _frame_index_to_sec(frame_index): return float(frame_index * porcupine.frame_length) / float(porcupine.sample_rate) audio, sample_rate = soundfile.read(input_audio_file_path, dtype='int16') assert sample_rate == porcupine.sample_rate num_frames = len(audio) // porcupine.frame_length for i in range(num_frames): frame = audio[i * porcupine.frame_length:(i + 1) * porcupine.frame_length] result = porcupine.process(frame) if num_keywords == 1 and result: print('detected keyword at time %f' % _frame_index_to_sec(i)) elif num_keywords > 1 and result >= 0: print('detected keyword index %d at time %f' % (result, _frame_index_to_sec(i))) porcupine.delete()
def run(self): """ Creates an input audio stream, initializes wake word detection (Porcupine) object, and monitors the audio stream for occurrences of the wake word(s). It prints the time of detection for each occurrence and index of wake word. """ num_keywords = len(self._keyword_file_paths) keyword_names = \ [os.path.basename(x).replace('.ppn', '').replace('_tiny', '').split('_')[0] for x in self._keyword_file_paths] print('listening for: "friday"') #for keyword_name, sensitivity in zip(keyword_names, sensitivities): # print('- %s (sensitivity: %f)' % (keyword_name, sensitivity)) porcupine = None pa = None audio_stream = None try: porcupine = Porcupine( library_path=self._library_path, model_file_path=self._model_file_path, keyword_file_paths=self._keyword_file_paths, sensitivities=self._sensitivities) pa = pyaudio.PyAudio() audio_stream = pa.open( rate=porcupine.sample_rate, channels=1, format=pyaudio.paInt16, input=True, frames_per_buffer=porcupine.frame_length, input_device_index=self._input_device_index) while True: pcm = audio_stream.read(porcupine.frame_length) pcm = struct.unpack_from("h" * porcupine.frame_length, pcm) if self._output_path is not None: self._recorded_frames.append(pcm) result = porcupine.process(pcm) if num_keywords == 1 and result: #######WORD DETECTED print('[%s] detected keyword' % str(datetime.now())) #playbeep() #speechrec.startdetection() p = multiprocessing.Process(target=speechrec.startdetection()) p.start() # Wait for 10 seconds or until process finishes p.join(2) # If thread is still active if p.is_alive() and audresp.speechtext=="": print("running... let's kill it...") # Terminate p.terminate() p.join() elif num_keywords > 1 and result >= 0: print('[%s] detected %s' % (str(datetime.now()), keyword_names[result])) except KeyboardInterrupt: print('stopping ...') finally: if porcupine is not None: porcupine.delete() if audio_stream is not None: audio_stream.close() if pa is not None: pa.terminate() if self._output_path is not None and len(self._recorded_frames) > 0: recorded_audio = np.concatenate(self._recorded_frames, axis=0).astype(np.int16) soundfile.write(self._output_path, recorded_audio, samplerate=porcupine.sample_rate, subtype='PCM_16')
def run(self): """ Creates an input audio stream, initializes wake word detection (Porcupine) object, and monitors the audio stream for occurrences of the wake word(s). It prints the time of detection for each occurrence and index of wake word. """ num_keywords = len(self._keyword_file_paths) keyword_names = list() for x in self._keyword_file_paths: keyword_names.append( os.path.basename(x).replace('.ppn', '').replace('_compressed', '').split('_')[0]) print('listening for:') for keyword_name, sensitivity in zip(keyword_names, self._sensitivities): print('- %s (sensitivity: %f)' % (keyword_name, sensitivity)) porcupine = None pa = None audio_stream = None try: porcupine = Porcupine(library_path=self._library_path, model_file_path=self._model_file_path, keyword_file_paths=self._keyword_file_paths, sensitivities=self._sensitivities) pa = pyaudio.PyAudio() audio_stream = pa.open(rate=porcupine.sample_rate, channels=1, format=pyaudio.paInt16, input=True, frames_per_buffer=porcupine.frame_length, input_device_index=self._input_device_index) while True: pcm = audio_stream.read(porcupine.frame_length) pcm = struct.unpack_from("h" * porcupine.frame_length, pcm) if self._output_path is not None: self._recorded_frames.append(pcm) result = porcupine.process(pcm) if num_keywords == 1 and result: print('[%s] detected keyword' % str(datetime.now())) elif num_keywords > 1 and result >= 0: print('[%s] detected %s' % (str(datetime.now()), keyword_names[result])) except KeyboardInterrupt: print('stopping ...') finally: if porcupine is not None: porcupine.delete() if audio_stream is not None: audio_stream.close() if pa is not None: pa.terminate() if self._output_path is not None and len( self._recorded_frames) > 0: recorded_audio = np.concatenate(self._recorded_frames, axis=0).astype(np.int16) soundfile.write(self._output_path, recorded_audio, samplerate=porcupine.sample_rate, subtype='PCM_16')
class PorcupineTestCase(unittest.TestCase): _porcupine = None def setUp(self): self._porcupine = Porcupine( library_path=self._library_path(), model_file_path=self._abs_path( '../../lib/common/porcupine_params.pv'), keyword_file_path=self._abs_path( '../../resources/keyword_files/porcupine_%s.ppn' % self._keyword_file_extension()), sensitivity=0.5) def tearDown(self): self._porcupine.delete() def test_process(self): audio, sample_rate = soundfile.read( self._abs_path('../../resources/audio_samples/porcupine.wav'), dtype='int16') assert sample_rate == self._porcupine.sample_rate num_frames = len(audio) // self._porcupine.frame_length results = [] for i in range(num_frames): frame = audio[i * self._porcupine.frame_length:(i + 1) * self._porcupine.frame_length] results.append(self._porcupine.process(frame)) self.assertEqual(sum(results), 1) @staticmethod def _abs_path(rel_path): return os.path.join(os.path.dirname(__file__), rel_path) @staticmethod def _keyword_file_extension(): system = platform.system() machine = platform.machine() if system == 'Linux' and (machine == 'x86_64' or machine == 'i386'): return 'linux' elif system == 'Darwin': return 'mac' elif system == 'Linux' and machine.startswith('arm'): return 'raspberrypi' raise NotImplementedError('Porcupine is not supported on %s/%s yet!' % (system, machine)) @staticmethod def _library_path(): system = platform.system() machine = platform.machine() if system == 'Darwin': return os.path.join( os.path.dirname(__file__), '../../lib/mac/%s/libpv_porcupine.dylib' % machine) elif system == 'Linux': if machine == 'x86_64' or machine == 'i386': return os.path.join( os.path.dirname(__file__), '../../lib/linux/%s/libpv_porcupine.so' % machine) elif machine.startswith('arm'): return os.path.join( os.path.dirname(__file__), '../../lib/raspberry-pi/libpv_porcupine.so') raise NotImplementedError('Porcupine is not supported on %s/%s yet!' % (system, machine))