rhino_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 <string.h>
16 #include <sys/time.h>
17 
18 #if defined(_WIN32) || defined(_WIN64)
19 
20 #include <windows.h>
21 
22 #else
23 
24 #include <dlfcn.h>
25 
26 #endif
27 
28 #define DR_WAV_IMPLEMENTATION
29 
30 #include "dr_wav.h"
31 
32 #include "pv_rhino.h"
33 
34 static void *open_dl(const char *dl_path) {
35 
36 #if defined(_WIN32) || defined(_WIN64)
37 
38  return LoadLibrary(dl_path);
39 
40 #else
41 
42  return dlopen(dl_path, RTLD_NOW);
43 
44 #endif
45 
46 }
47 
48 static void *load_symbol(void *handle, const char *symbol) {
49 
50 #if defined(_WIN32) || defined(_WIN64)
51 
52  return GetProcAddress((HMODULE) handle, symbol);
53 
54 #else
55 
56  return dlsym(handle, symbol);
57 
58 #endif
59 
60 }
61 
62 static void close_dl(void *handle) {
63 
64 #if defined(_WIN32) || defined(_WIN64)
65 
66  FreeLibrary((HMODULE) handle);
67 
68 #else
69 
70  dlclose(handle);
71 
72 #endif
73 
74 }
75 
76 static void print_dl_error(const char *message) {
77 
78 #if defined(_WIN32) || defined(_WIN64)
79 
80  fprintf(stderr, "%s with code '%lu'.\n", message, GetLastError());
81 
82 #else
83 
84  fprintf(stderr, "%s with '%s'.\n", message, dlerror());
85 
86 #endif
87 
88 }
89 
90 static struct option long_options[] = {
91  {"library_path", required_argument, NULL, 'l'},
92  {"model_path", required_argument, NULL, 'm'},
93  {"context_path", required_argument, NULL, 'c'},
94  {"sensitivity", required_argument, NULL, 't'},
95  {"require_endpoint", required_argument, NULL, 'e'},
96  {"access_key", required_argument, NULL, 'a'},
97  {"wav_path", required_argument, NULL, 'w'}
98 };
99 
100 void print_usage(const char *program_name) {
101  fprintf(stderr,
102  "Usage : %s -l LIBRARY_PATH -m MODEL_PATH -c CONTEXT_PATH -t SENSTIVITY -a ACCESS_KEY -w WAV_PATH [-e, --require_endpoint (true,false)]\n",
103  program_name);
104 }
105 
106 int main(int argc, char *argv[]) {
107  const char *library_path = NULL;
108  const char *model_path = NULL;
109  const char *context_path = NULL;
110  const char *access_key = NULL;
111  const char *wav_path = NULL;
112  float sensitivity = 0.5f;
113  bool require_endpoint = false;
114 
115  int c;
116  while ((c = getopt_long(argc, argv, "e:l:m:c:t:a:w:", long_options, NULL)) != -1) {
117  switch (c) {
118  case 'l':
119  library_path = optarg;
120  break;
121  case 'm':
122  model_path = optarg;
123  break;
124  case 'c':
125  context_path = optarg;
126  break;
127  case 't':
128  sensitivity = strtof(optarg, NULL);
129  break;
130  case 'e':
131  require_endpoint = (strcmp(optarg, "false") != 0);
132  break;
133  case 'a':
134  access_key = optarg;
135  break;
136  case 'w':
137  wav_path = optarg;
138  break;
139  default:
140  exit(1);
141  }
142  }
143 
144  if (!library_path || !model_path || !context_path || !access_key) {
145  print_usage(argv[0]);
146  exit(1);
147  }
148 
149  void *rhino_library = open_dl(library_path);
150  if (!rhino_library) {
151  fprintf(stderr, "failed to open library.\n");
152  exit(1);
153  }
154 
155  const char *(*pv_status_to_string_func)(pv_status_t) = load_symbol(rhino_library, "pv_status_to_string");
156  if (!pv_status_to_string_func) {
157  print_dl_error("failed to load 'pv_status_to_string'");
158  exit(1);
159  }
160 
161  int32_t (*pv_sample_rate_func)() = load_symbol(rhino_library, "pv_sample_rate");
162  if (!pv_sample_rate_func) {
163  print_dl_error("failed to load 'pv_sample_rate'");
164  exit(1);
165  }
166 
167  pv_status_t (*pv_rhino_init_func)(
168  const char *,
169  const char *,
170  const char *,
171  float,
172  bool,
173  pv_rhino_t **) =
174  load_symbol(rhino_library, "pv_rhino_init");
175  if (!pv_rhino_init_func) {
176  print_dl_error("failed to load 'pv_rhino_init'");
177  exit(1);
178  }
179 
180  void (*pv_rhino_delete_func)(pv_rhino_t *) = load_symbol(rhino_library, "pv_rhino_delete");
181  if (!pv_rhino_delete_func) {
182  print_dl_error("failed to load 'pv_rhino_delete'");
183  exit(1);
184  }
185 
186  pv_status_t (*pv_rhino_process_func)(pv_rhino_t *, const int16_t *, bool *) =
187  load_symbol(rhino_library, "pv_rhino_process");
188  if (!pv_rhino_process_func) {
189  print_dl_error("failed to load 'pv_rhino_process'");
190  exit(1);
191  }
192 
193  pv_status_t (*pv_rhino_is_understood_func)(const pv_rhino_t *, bool *) =
194  load_symbol(rhino_library, "pv_rhino_is_understood");
195  if (!pv_rhino_is_understood_func) {
196  print_dl_error("failed to load 'pv_rhino_is_understood'");
197  exit(1);
198  }
199 
201  (*pv_rhino_get_intent_func)(const pv_rhino_t *, const char **, int32_t *, const char ***, const char ***) =
202  load_symbol(rhino_library, "pv_rhino_get_intent");
203  if (!pv_rhino_get_intent_func) {
204  print_dl_error("failed to load 'pv_rhino_get_intent'");
205  exit(1);
206  }
207 
208  pv_status_t (*pv_rhino_free_slots_and_values_func)(const pv_rhino_t *, const char **, const char **) =
209  load_symbol(rhino_library, "pv_rhino_free_slots_and_values");
210  if (!pv_rhino_free_slots_and_values_func) {
211  print_dl_error("failed to load 'pv_rhino_free_slots_and_values'");
212  exit(1);
213  }
214 
215  int32_t (*pv_rhino_frame_length_func)() = load_symbol(rhino_library, "pv_rhino_frame_length");
216  if (!pv_rhino_frame_length_func) {
217  print_dl_error("failed to load 'pv_rhino_frame_length'n");
218  exit(1);
219  }
220 
221  const char *(*pv_rhino_version_func)() = load_symbol(rhino_library, "pv_rhino_version");
222  if (!pv_rhino_version_func) {
223  print_dl_error("failed to load 'pv_rhino_version'");
224  exit(1);
225  }
226 
227  drwav f;
228 
229  if (!drwav_init_file(&f, wav_path, NULL)) {
230  fprintf(stderr, "failed to open wav file at '%s'.", wav_path);
231  exit(1);
232  }
233 
234  if (f.sampleRate != (uint32_t) pv_sample_rate_func()) {
235  fprintf(stderr, "audio sample rate should be %d\n.", pv_sample_rate_func());
236  exit(1);
237  }
238 
239  if (f.bitsPerSample != 16) {
240  fprintf(stderr, "audio format should be 16-bit\n.");
241  exit(1);
242  }
243 
244  if (f.channels != 1) {
245  fprintf(stderr, "audio should be single-channel.\n");
246  exit(1);
247  }
248 
249  int16_t *pcm = calloc(pv_rhino_frame_length_func(), sizeof(int16_t));
250  if (!pcm) {
251  fprintf(stderr, "failed to allocate memory for audio frame.\n");
252  exit(1);
253  }
254 
255  pv_rhino_t *rhino = NULL;
256  pv_status_t status = pv_rhino_init_func(
257  access_key,
258  model_path,
259  context_path,
260  sensitivity,
261  require_endpoint,
262  &rhino);
263  if (status != PV_STATUS_SUCCESS) {
264  fprintf(stderr, "'pv_rhino_init' failed with '%s'\n", pv_status_to_string_func(status));
265  exit(1);
266  }
267 
268  fprintf(stdout, "Picovoice Rhino Speech-to-Intent (%s) :\n\n", pv_rhino_version_func());
269 
270  double total_cpu_time_usec = 0;
271  double total_processed_time_usec = 0;
272  int32_t frame_index = 0;
273 
274  while ((int32_t) drwav_read_pcm_frames_s16(&f, pv_rhino_frame_length_func(), pcm) == pv_rhino_frame_length_func()) {
275  struct timeval before;
276  gettimeofday(&before, NULL);
277 
278  bool is_finalized = false;
279  status = pv_rhino_process_func(rhino, pcm, &is_finalized);
280  if (status != PV_STATUS_SUCCESS) {
281  fprintf(stderr, "'pv_rhino_process' failed with '%s'\n", pv_status_to_string_func(status));
282  exit(1);
283  }
284 
285  if (is_finalized) {
286  bool is_understood = false;
287  status = pv_rhino_is_understood_func(rhino, &is_understood);
288  if (status != PV_STATUS_SUCCESS) {
289  fprintf(stderr, "'pv_rhino_is_understood'failed with '%s'\n", pv_status_to_string_func(status));
290  exit(1);
291  }
292 
293  const char *intent = NULL;
294  int32_t num_slots = 0;
295  const char **slots = NULL;
296  const char **values = NULL;
297 
298  if (is_understood) {
299  status = pv_rhino_get_intent_func(rhino, &intent, &num_slots, &slots, &values);
300  if (status != PV_STATUS_SUCCESS) {
301  fprintf(stderr, "'pv_rhino_get_intent' failed with '%s'\n", pv_status_to_string_func(status));
302  exit(1);
303  }
304  }
305 
306  fprintf(stdout, "{\n");
307  fprintf(stdout, " 'is_understood' : '%s',\n", is_understood ? "true" : "false");
308  if (is_understood) {
309  fprintf(stdout, " 'intent' : '%s'\n", intent);
310  if (num_slots > 0) {
311  fprintf(stdout, " 'slots' : {\n");
312  for (int32_t i = 0; i < num_slots; i++) {
313  fprintf(stdout, " '%s' : '%s',\n", slots[i], values[i]);
314  }
315  fprintf(stdout, " }\n");
316  }
317  }
318  fprintf(stdout, "}\n\n");
319 
320  if (is_understood) {
321  status = pv_rhino_free_slots_and_values_func(rhino, slots, values);
322  if (status != PV_STATUS_SUCCESS) {
323  fprintf(stderr, "'pv_rhino_free_slots_and_values' failed with '%s'\n",
324  pv_status_to_string_func(status));
325  exit(1);
326  }
327  }
328 
329  break;
330  }
331 
332  struct timeval after;
333  gettimeofday(&after, NULL);
334 
335  total_cpu_time_usec +=
336  (double) (after.tv_sec - before.tv_sec) * 1e6 + (double) (after.tv_usec - before.tv_usec);
337  total_processed_time_usec += (pv_rhino_frame_length_func() * 1e6) / pv_sample_rate_func();
338  frame_index++;
339  }
340 
341  const double real_time_factor = total_cpu_time_usec / total_processed_time_usec;
342  fprintf(stdout, "real time factor : %.3f\n", real_time_factor);
343 
344  free(pcm);
345  drwav_uninit(&f);
346  pv_rhino_delete_func(rhino);
347  close_dl(rhino_library);
348 
349  return 0;
350 }
NULL
#define NULL
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/speex_resampler/thirdparty/resample.c:92
open_dl
static void * open_dl(const char *dl_path)
Definition: rhino_demo_file.c:34
main
int main(int argc, char *argv[])
Definition: rhino_demo_file.c:106
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
print_dl_error
static void print_dl_error(const char *message)
Definition: rhino_demo_file.c:76
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
long_options
static struct option long_options[]
Definition: rhino_demo_file.c:90
close_dl
static void close_dl(void *handle)
Definition: rhino_demo_file.c:62
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
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
print_usage
void print_usage(const char *program_name)
Definition: rhino_demo_file.c:100
python.test_porcupine.argv
argv
Definition: test_porcupine.py:158
pv_rhino_t
struct pv_rhino pv_rhino_t
Definition: include/pv_rhino.h:34
load_symbol
static void * load_symbol(void *handle, const char *symbol)
Definition: rhino_demo_file.c:48


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