porcupine_demo_file.c
Go to the documentation of this file.
1 /*
2  Copyright 2018-2021 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 #include <getopt.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <sys/time.h>
16 
17 #if defined(_WIN32) || defined(_WIN64)
18 
19 #include <windows.h>
20 
21 #else
22 
23 #include <dlfcn.h>
24 
25 #endif
26 
27 #define DR_WAV_IMPLEMENTATION
28 
29 #include "dr_wav.h"
30 
31 #include "pv_porcupine.h"
32 
33 static void *open_dl(const char *dl_path) {
34 
35 #if defined(_WIN32) || defined(_WIN64)
36 
37  return LoadLibrary(dl_path);
38 
39 #else
40 
41  return dlopen(dl_path, RTLD_NOW);
42 
43 #endif
44 
45 }
46 
47 static void *load_symbol(void *handle, const char *symbol) {
48 
49 #if defined(_WIN32) || defined(_WIN64)
50 
51  return GetProcAddress((HMODULE) handle, symbol);
52 
53 #else
54 
55  return dlsym(handle, symbol);
56 
57 #endif
58 
59 }
60 
61 static void close_dl(void *handle) {
62 
63 #if defined(_WIN32) || defined(_WIN64)
64 
65  FreeLibrary((HMODULE) handle);
66 
67 #else
68 
69  dlclose(handle);
70 
71 #endif
72 
73 }
74 
75 static void print_dl_error(const char *message) {
76 
77 #if defined(_WIN32) || defined(_WIN64)
78 
79  fprintf(stderr, "%s with code '%lu'.\n", message, GetLastError());
80 
81 #else
82 
83  fprintf(stderr, "%s with '%s'.\n", message, dlerror());
84 
85 #endif
86 
87 }
88 
89 static struct option long_options[] = {
90  {"library_path", required_argument, NULL, 'l'},
91  {"model_path", required_argument, NULL, 'm'},
92  {"keyword_path", required_argument, NULL, 'k'},
93  {"sensitivity", required_argument, NULL, 't'},
94  {"access_key", required_argument, NULL, 'a'},
95  {"wav_path", required_argument, NULL, 'w'}
96 };
97 
98 void print_usage(const char *program_name) {
99  fprintf(stderr, "Usage : %s -l LIBRARY_PATH -m MODEL_PATH -k KEYWORD_PATH -t SENSITIVITY -a ACCESS_KEY -w WAV_PATH\n", program_name);
100 }
101 
102 int main(int argc, char *argv[]) {
103  const char *library_path = NULL;
104  const char *model_path = NULL;
105  const char *keyword_path = NULL;
106  float sensitivity = 0.5;
107  const char *access_key = NULL;
108  const char *wav_path = NULL;
109 
110  int c;
111  while ((c = getopt_long(argc, argv, "l:m:k:t:a:w:", long_options, NULL)) != -1) {
112  switch (c) {
113  case 'l':
114  library_path = optarg;
115  break;
116  case 'm':
117  model_path = optarg;
118  break;
119  case 'k':
120  keyword_path = optarg;
121  break;
122  case 't':
123  sensitivity = strtof(optarg, NULL);
124  break;
125  case 'a':
126  access_key = optarg;
127  break;
128  case 'w':
129  wav_path = optarg;
130  break;
131  default:
132  exit(1);
133  }
134  }
135 
136  if (!library_path || !model_path || !keyword_path || !access_key) {
137  print_usage(argv[0]);
138  exit(1);
139  }
140 
141  void *porcupine_library = open_dl(library_path);
142  if (!porcupine_library) {
143  fprintf(stderr, "failed to open library\n");
144  exit(1);
145  }
146 
147  const char *(*pv_status_to_string_func)(pv_status_t) = load_symbol(porcupine_library, "pv_status_to_string");
148  if (!pv_status_to_string_func) {
149  print_dl_error("failed to load 'pv_status_to_string' with '%s'");
150  exit(1);
151  }
152 
153  int32_t (*pv_sample_rate_func)() = load_symbol(porcupine_library, "pv_sample_rate");
154  if (!pv_sample_rate_func) {
155  print_dl_error("failed to load 'pv_sample_rate'");
156  exit(1);
157  }
158 
159  pv_status_t (*pv_porcupine_init_func)(const char *, const char *, int32_t, const char *const *, const float *, pv_porcupine_t **)
160  = load_symbol(porcupine_library, "pv_porcupine_init");
161  if (!pv_porcupine_init_func) {
162  print_dl_error("failed to load 'pv_porcupine_init'");
163  exit(1);
164  }
165 
166  void (*pv_porcupine_delete_func)(pv_porcupine_t *) = load_symbol(porcupine_library, "pv_porcupine_delete");
167  if (!pv_porcupine_delete_func) {
168  print_dl_error("failed to load 'pv_porcupine_delete'");
169  exit(1);
170  }
171 
172  pv_status_t (*pv_porcupine_process_func)(pv_porcupine_t *, const int16_t *, int32_t *) =
173  load_symbol(porcupine_library, "pv_porcupine_process");
174  if (!pv_porcupine_process_func) {
175  print_dl_error("failed to load 'pv_porcupine_process'");
176  exit(1);
177  }
178 
179  int32_t (*pv_porcupine_frame_length_func)() = load_symbol(porcupine_library, "pv_porcupine_frame_length");
180  if (!pv_porcupine_frame_length_func) {
181  print_dl_error("failed to load 'pv_porcupine_frame_length' with '%s'.\n");
182  exit(1);
183  }
184 
185  const char *(*pv_porcupine_version_func)() = load_symbol(porcupine_library, "pv_porcupine_version");
186  if (!pv_porcupine_version_func) {
187  print_dl_error("failed to load 'pv_porcupine_version'");
188  exit(1);
189  }
190 
191  drwav f;
192 
193  if (!drwav_init_file(&f, wav_path, NULL)) {
194  fprintf(stderr, "failed to open wav file at '%s'.", wav_path);
195  exit(1);
196  }
197 
198  if (f.sampleRate != (uint32_t) pv_sample_rate_func()) {
199  fprintf(stderr, "audio sample rate should be %d\n.", pv_sample_rate_func());
200  exit(1);
201  }
202 
203  if (f.bitsPerSample != 16) {
204  fprintf(stderr, "audio format should be 16-bit\n.");
205  exit(1);
206  }
207 
208  if (f.channels != 1) {
209  fprintf(stderr, "audio should be single-channel.\n");
210  exit(1);
211  }
212 
213  int16_t *pcm = calloc(pv_porcupine_frame_length_func(), sizeof(int16_t));
214  if (!pcm) {
215  fprintf(stderr, "failed to allocate memory for audio frame.\n");
216  exit(1);
217  }
218 
219  pv_porcupine_t *porcupine = NULL;
220  pv_status_t status = pv_porcupine_init_func(access_key, model_path, 1, &keyword_path, &sensitivity, &porcupine);
221  if (status != PV_STATUS_SUCCESS) {
222  fprintf(stderr, "'pv_porcupine_init' failed with '%s'\n", pv_status_to_string_func(status));
223  exit(1);
224  }
225 
226  fprintf(stdout, "V%s\n\n", pv_porcupine_version_func());
227 
228  double total_cpu_time_usec = 0;
229  double total_processed_time_usec = 0;
230  int32_t frame_index = 0;
231 
232  while ((int32_t) drwav_read_pcm_frames_s16(&f, pv_porcupine_frame_length_func(), pcm) == pv_porcupine_frame_length_func()) {
233  struct timeval before;
234  gettimeofday(&before, NULL);
235 
236  int32_t keyword_index = -1;
237  status = pv_porcupine_process_func(porcupine, pcm, &keyword_index);
238  if (status != PV_STATUS_SUCCESS) {
239  fprintf(stderr, "'pv_porcupine_process' failed with '%s'\n", pv_status_to_string_func(status));
240  exit(1);
241  }
242 
243  struct timeval after;
244  gettimeofday(&after, NULL);
245 
246  if (keyword_index != -1) {
247  fprintf(stdout, "detected at %.1f seconds\n", (double) frame_index * pv_porcupine_frame_length_func() / pv_sample_rate_func());
248  }
249 
250  total_cpu_time_usec +=
251  (double) (after.tv_sec - before.tv_sec) * 1e6 + (double) (after.tv_usec - before.tv_usec);
252  total_processed_time_usec += (pv_porcupine_frame_length_func() * 1e6) / pv_sample_rate_func();
253  frame_index++;
254  }
255 
256  const double real_time_factor = total_cpu_time_usec / total_processed_time_usec;
257  fprintf(stdout, "real time factor : %.3f\n", real_time_factor);
258 
259  free(pcm);
260  drwav_uninit(&f);
261  pv_porcupine_delete_func(porcupine);
262  close_dl(porcupine_library);
263 
264  return 0;
265 }
long_options
static struct option long_options[]
Definition: porcupine_demo_file.c:89
open_dl
static void * open_dl(const char *dl_path)
Definition: porcupine_demo_file.c:33
main
int main(int argc, char *argv[])
Definition: porcupine_demo_file.c:102
NULL
#define NULL
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/speex_resampler/thirdparty/resample.c:92
print_dl_error
static void print_dl_error(const char *message)
Definition: porcupine_demo_file.c:75
drwav_read_pcm_frames_s16
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s16(drwav *pWav, drwav_uint64 framesToRead, drwav_int16 *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50013
load_symbol
static void * load_symbol(void *handle, const char *symbol)
Definition: porcupine_demo_file.c:47
f
f
PV_STATUS_SUCCESS
@ PV_STATUS_SUCCESS
Definition: porcupine/include/picovoice.h:34
pv_status_t
pv_status_t
Definition: porcupine/include/picovoice.h:33
close_dl
static void close_dl(void *handle)
Definition: porcupine_demo_file.c:61
drwav_init_file
DRWAV_API drwav_bool32 drwav_init_file(drwav *pWav, const char *filename, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48943
print_usage
void print_usage(const char *program_name)
Definition: porcupine_demo_file.c:98
drwav_uninit
DRWAV_API drwav_result drwav_uninit(drwav *pWav)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49216
drwav
Definition: porcupine/demo/c/dr_libs/dr_wav.h:805
pv_porcupine_t
struct pv_porcupine pv_porcupine_t
Definition: include/pv_porcupine.h:33
python.test_porcupine.argv
argv
Definition: test_porcupine.py:158


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