test_porcupine.py
Go to the documentation of this file.
1 #
2 # Copyright 2018-2022 Picovoice Inc.
3 #
4 # You may not use this file except in compliance with the license. A copy of the license is located in the "LICENSE"
5 # file accompanying this source.
6 #
7 # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8 # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9 # specific language governing permissions and limitations under the License.
10 #
11 
12 import struct
13 import sys
14 import unittest
15 import wave
16 
17 from porcupine import Porcupine
18 from util import *
19 
20 
21 class PorcupineTestCase(unittest.TestCase):
22  @staticmethod
23  def __append_language(s, language):
24  if language == 'en':
25  return s
26  return "%s_%s" % (s, language)
27 
28  @staticmethod
29  def __read_file(file_name, sample_rate):
30  wav_file = wave.open(file_name, mode="rb")
31  channels = wav_file.getnchannels()
32  num_frames = wav_file.getnframes()
33 
34  if wav_file.getframerate() != sample_rate:
35  raise ValueError(
36  "Audio file should have a sample rate of %d, got %d" % (sample_rate, wav_file.getframerate()))
37 
38  samples = wav_file.readframes(num_frames)
39  wav_file.close()
40 
41  frames = struct.unpack('h' * num_frames * channels, samples)
42 
43  if channels == 2:
44  print("Picovoice processes single-channel audio but stereo file is provided. Processing left channel only.")
45 
46  return frames[::channels]
47 
48  @classmethod
49  def __pv_model_path_by_language(cls, relative, language):
50  model_path_subdir = cls.__append_language('lib/common/porcupine_params', language)
51  return os.path.join(os.path.dirname(__file__), relative, '%s.pv' % model_path_subdir)
52 
53  @classmethod
54  def __pv_keyword_paths_by_language(cls, relative, language):
55  keyword_files_root = cls.__append_language('resources/keyword_files', language)
56  keyword_files_dir = \
57  os.path.join(os.path.dirname(__file__), relative, keyword_files_root, pv_keyword_files_subdir())
58 
59  res = dict()
60  for x in os.listdir(keyword_files_dir):
61  res[x.rsplit('_')[0]] = os.path.join(keyword_files_dir, x)
62 
63  return res
64 
65  def run_porcupine(self, language, keywords, ground_truth, audio_file_name=None):
66  if audio_file_name is None:
67  _audio_file_name_prefix = self.__append_language('multiple_keywords', language)
68  audio_file_name = '%s.wav' % _audio_file_name_prefix
69  keyword_paths = list()
70  for x in keywords:
71  keyword_paths.append(self.__pv_keyword_paths_by_language('../..', language)[x])
72 
73  porcupine = Porcupine(
74  access_key=sys.argv[1],
75  library_path=pv_library_path('../..'),
76  model_path=self.__pv_model_path_by_language('../..', language),
77  keyword_paths=keyword_paths,
78  sensitivities=[0.5] * len(keyword_paths))
79 
80  audio = self.__read_file(
81  os.path.join(os.path.dirname(__file__), '../../resources/audio_samples/', audio_file_name),
82  porcupine.sample_rate)
83 
84  num_frames = len(audio) // porcupine.frame_length
85  results = []
86  for i in range(num_frames):
87  frame = audio[i * porcupine.frame_length:(i + 1) * porcupine.frame_length]
88  result = porcupine.process(frame)
89  if result >= 0:
90  results.append(result)
91 
92  porcupine.delete()
93 
94  self.assertEqual(results, ground_truth)
95 
97  self.run_porcupine(
98  language='en',
99  keywords=['porcupine'],
100  ground_truth=[0],
101  audio_file_name='porcupine.wav')
102 
104  keywords = [
105  'americano', 'blueberry', 'bumblebee', 'grapefruit',
106  'grasshopper', 'picovoice', 'porcupine', 'terminator'
107  ]
108  self.run_porcupine(
109  language='en',
110  keywords=keywords,
111  ground_truth=[6, 0, 1, 2, 3, 4, 5, 6, 7])
112 
114  self.run_porcupine(
115  language='es',
116  keywords=['manzana'],
117  ground_truth=[0],
118  audio_file_name='manzana.wav')
119 
121  self.run_porcupine(
122  language='es',
123  keywords=['emparedado', 'leopardo', 'manzana'],
124  ground_truth=[0, 1, 2])
125 
127  self.run_porcupine(
128  language='de',
129  keywords=['heuschrecke'],
130  ground_truth=[0],
131  audio_file_name='heuschrecke.wav')
132 
134  self.run_porcupine(
135  language='de',
136  keywords=['ananas', 'heuschrecke', 'leguan', 'stachelschwein'],
137  ground_truth=[0, 1, 2, 3])
138 
140  self.run_porcupine(
141  language='fr',
142  keywords=['mon chouchou'],
143  ground_truth=[0],
144  audio_file_name='mon_chouchou.wav')
145 
147  self.run_porcupine(
148  language='fr',
149  keywords=['framboise', 'mon chouchou', 'parapluie'],
150  ground_truth=[0, 1, 0, 2])
151 
152 
153 if __name__ == '__main__':
154  if len(sys.argv) != 2:
155  print("usage: test_porcupine.py ${AccessKey}")
156  exit(1)
157 
158  unittest.main(argv=sys.argv[:1])
python.test_porcupine.PorcupineTestCase.__read_file
def __read_file(file_name, sample_rate)
Definition: test_porcupine.py:29
python.util.pv_keyword_files_subdir
def pv_keyword_files_subdir()
Definition: porcupine/binding/python/util.py:111
python.test_porcupine.PorcupineTestCase.test_multiple_keywords_fr
def test_multiple_keywords_fr(self)
Definition: test_porcupine.py:146
python.test_porcupine.PorcupineTestCase.test_single_keyword
def test_single_keyword(self)
Definition: test_porcupine.py:96
python.test_porcupine.PorcupineTestCase.__append_language
def __append_language(s, language)
Definition: test_porcupine.py:23
python.test_porcupine.PorcupineTestCase.run_porcupine
def run_porcupine(self, language, keywords, ground_truth, audio_file_name=None)
Definition: test_porcupine.py:65
python.util.pv_library_path
def pv_library_path(relative)
Definition: porcupine/binding/python/util.py:80
python.test_porcupine.PorcupineTestCase.test_single_keyword_fr
def test_single_keyword_fr(self)
Definition: test_porcupine.py:139
python.test_porcupine.PorcupineTestCase.test_multiple_keywords_es
def test_multiple_keywords_es(self)
Definition: test_porcupine.py:120
python.test_porcupine.PorcupineTestCase.test_single_keyword_es
def test_single_keyword_es(self)
Definition: test_porcupine.py:113
python.test_porcupine.PorcupineTestCase.test_multiple_keywords
def test_multiple_keywords(self)
Definition: test_porcupine.py:103
python.test_porcupine.PorcupineTestCase
Definition: test_porcupine.py:21
python.test_porcupine.PorcupineTestCase.__pv_model_path_by_language
def __pv_model_path_by_language(cls, relative, language)
Definition: test_porcupine.py:49
python.test_porcupine.PorcupineTestCase.__pv_keyword_paths_by_language
def __pv_keyword_paths_by_language(cls, relative, language)
Definition: test_porcupine.py:54
python.porcupine.Porcupine
Definition: porcupine.py:65
python.test_porcupine.PorcupineTestCase.test_single_keyword_de
def test_single_keyword_de(self)
Definition: test_porcupine.py:126
python.test_porcupine.PorcupineTestCase.test_multiple_keywords_de
def test_multiple_keywords_de(self)
Definition: test_porcupine.py:133


picovoice_driver
Author(s):
autogenerated on Fri Apr 1 2022 02:14:55