21 wav_file = wave.open(file_name, mode=
"rb")
22 channels = wav_file.getnchannels()
23 num_frames = wav_file.getnframes()
25 if wav_file.getframerate() != sample_rate:
26 raise ValueError(
"Audio file should have a sample rate of %d. got %d" % (sample_rate, wav_file.getframerate()))
28 samples = wav_file.readframes(num_frames)
31 frames = struct.unpack(
'h' * num_frames * channels, samples)
34 print(
"Picovoice processes single-channel audio but stereo file is provided. Processing left channel only.")
36 return frames[::channels]
40 parser = argparse.ArgumentParser()
42 parser.add_argument(
'--access_key',
43 help=
'AccessKey obtained from Picovoice Console (https://picovoice.ai/console/)',
46 parser.add_argument(
'--input_audio_path', help=
'Absolute path to input audio file.', required=
True)
51 help=
'List of default keywords for detection. Available keywords: %s' %
', '.join(sorted(pvporcupine.KEYWORDS)),
52 choices=sorted(list(pvporcupine.KEYWORDS)),
58 help=
"Absolute paths to keyword model files. If not set it will be populated from `--keywords` argument")
60 parser.add_argument(
'--library_path', help=
'Absolute path to dynamic library.', default=pvporcupine.LIBRARY_PATH)
64 help=
'Absolute path to the file containing model parameters.',
65 default=pvporcupine.MODEL_PATH)
70 help=
"Sensitivities for detecting keywords. Each value should be a number within [0, 1]. A higher " +
71 "sensitivity results in fewer misses at the cost of increasing the false alarm rate. If not set 0.5 " +
76 args = parser.parse_args()
78 if args.keyword_paths
is None:
79 if args.keywords
is None:
80 raise ValueError(
"Either `--keywords` or `--keyword_paths` must be set.")
82 keyword_paths = [pvporcupine.KEYWORD_PATHS[x]
for x
in args.keywords]
84 keyword_paths = args.keyword_paths
86 if args.sensitivities
is None:
87 args.sensitivities = [0.5] * len(keyword_paths)
89 if len(keyword_paths) != len(args.sensitivities):
90 raise ValueError(
'Number of keywords does not match the number of sensitivities.')
93 porcupine = pvporcupine.create(
94 access_key=args.access_key,
95 library_path=args.library_path,
96 model_path=args.model_path,
97 keyword_paths=keyword_paths,
98 sensitivities=args.sensitivities)
99 except pvporcupine.PorcupineInvalidArgumentError
as e:
100 print(f
"One or more arguments provided to Porcupine is invalid: {args}")
101 print(f
"If all other arguments seem valid, ensure that '{args.access_key}' is a valid AccessKey")
103 except pvporcupine.PorcupineActivationError
as e:
104 print(
"AccessKey activation error")
106 except pvporcupine.PorcupineActivationLimitError
as e:
107 print(f
"AccessKey '{args.access_key}' has reached it's temporary device limit")
109 except pvporcupine.PorcupineActivationRefusedError
as e:
110 print(f
"AccessKey '{args.access_key}' refused")
112 except pvporcupine.PorcupineActivationThrottledError
as e:
113 print(f
"AccessKey '{args.access_key}' has been throttled")
115 except pvporcupine.PorcupineError
as e:
116 print(f
"Failed to initialize Porcupine")
119 audio =
read_file(args.input_audio_path, porcupine.sample_rate)
122 for x
in keyword_paths:
123 keyword_phrase_part = os.path.basename(x).replace(
'.ppn',
'').split(
'_')
124 if len(keyword_phrase_part) > 6:
125 keywords.append(
' '.join(keyword_phrase_part[0:-6]))
127 keywords.append(keyword_phrase_part[0])
129 num_frames = len(audio) // porcupine.frame_length
130 for i
in range(num_frames):
131 frame = audio[i * porcupine.frame_length:(i + 1) * porcupine.frame_length]
132 result = porcupine.process(frame)
135 "Detected '%s' at %.2f sec" %
136 (keywords[result], float(i * porcupine.frame_length) / float(porcupine.sample_rate)))
141 if __name__ ==
'__main__':