rhino_demo_mic.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 <signal.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.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 #include "pv_recorder.h"
29 #include "pv_rhino.h"
30 
31 static volatile bool is_interrupted = false;
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  {"show_audio_devices", no_argument, NULL, 's'},
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  {"audio_device_index", required_argument, NULL, 'd'}
98 };
99 
100 static 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 -d AUDIO_DEVICE_INDEX [-e, --require_endpoint (true,false)]\n"
103  " %s [-s, --show_audio_devices]\n", program_name, program_name);
104 }
105 
106 void interrupt_handler(int _) {
107  (void) _;
108  is_interrupted = true;
109 }
110 
111 void show_audio_devices(void) {
112  char **devices = NULL;
113  int32_t count = 0;
114 
116  if (status != PV_RECORDER_STATUS_SUCCESS) {
117  fprintf(stderr, "Failed to get audio devices with: %s.\n", pv_recorder_status_to_string(status));
118  exit(1);
119  }
120 
121  fprintf(stdout, "Printing devices...\n");
122  for (int32_t i = 0; i < count; i++) {
123  fprintf(stdout, "index: %d, name: %s\n", i, devices[i]);
124  }
125 
127 }
128 
129 int main(int argc, char *argv[]) {
130  signal(SIGINT, interrupt_handler);
131 
132  const char *library_path = NULL;
133  const char *model_path = NULL;
134  const char *context_path = NULL;
135  float sensitivity = 0.5f;
136  bool require_endpoint = false;
137  const char *access_key = NULL;
138  int32_t device_index = -1;
139 
140  int c;
141  while ((c = getopt_long(argc, argv, "se:l:m:c:t:a:d:", long_options, NULL)) != -1) {
142  switch (c) {
143  case 's':
145  return 0;
146  case 'l':
147  library_path = optarg;
148  break;
149  case 'm':
150  model_path = optarg;
151  break;
152  case 'c':
153  context_path = optarg;
154  break;
155  case 't':
156  sensitivity = strtof(optarg, NULL);
157  break;
158  case 'e':
159  require_endpoint = (strcmp(optarg, "false") != 0);
160  break;
161  case 'a':
162  access_key = optarg;
163  break;
164  case 'd':
165  device_index = (int32_t) strtol(optarg, NULL, 10);
166  break;
167  default:
168  exit(1);
169  }
170  }
171 
172  if (!library_path || !model_path || !context_path || !access_key) {
173  print_usage(argv[0]);
174  exit(1);
175  }
176 
177  void *rhino_library = open_dl(library_path);
178  if (!rhino_library) {
179  fprintf(stderr, "failed to open library.\n");
180  exit(1);
181  }
182 
183  const char *(*pv_status_to_string_func)(pv_status_t) = load_symbol(rhino_library, "pv_status_to_string");
184  if (!pv_status_to_string_func) {
185  print_dl_error("failed to load 'pv_status_to_string'");
186  exit(1);
187  }
188 
189  int32_t (*pv_sample_rate_func)() = load_symbol(rhino_library, "pv_sample_rate");
190  if (!pv_sample_rate_func) {
191  print_dl_error("failed to load 'pv_sample_rate'");
192  exit(1);
193  }
194 
195  pv_status_t (*pv_rhino_init_func)(
196  const char *,
197  const char *,
198  const char *,
199  float,
200  bool,
201  pv_rhino_t **) =
202  load_symbol(rhino_library, "pv_rhino_init");
203  if (!pv_rhino_init_func) {
204  print_dl_error("failed to load 'pv_rhino_init'");
205  exit(1);
206  }
207 
208  void (*pv_rhino_delete_func)(pv_rhino_t *) = load_symbol(rhino_library, "pv_rhino_delete");
209  if (!pv_rhino_delete_func) {
210  print_dl_error("failed to load 'pv_rhino_delete'");
211  exit(1);
212  }
213 
214  pv_status_t (*pv_rhino_process_func)(pv_rhino_t *, const int16_t *, bool *) =
215  load_symbol(rhino_library, "pv_rhino_process");
216  if (!pv_rhino_process_func) {
217  print_dl_error("failed to load 'pv_rhino_process'");
218  exit(1);
219  }
220 
221  pv_status_t (*pv_rhino_is_understood_func)(const pv_rhino_t *, bool *) =
222  load_symbol(rhino_library, "pv_rhino_is_understood");
223  if (!pv_rhino_is_understood_func) {
224  print_dl_error("failed to load 'pv_rhino_is_understood'");
225  exit(1);
226  }
227 
229  (*pv_rhino_get_intent_func)(const pv_rhino_t *, const char **, int32_t *, const char ***, const char ***) =
230  load_symbol(rhino_library, "pv_rhino_get_intent");
231  if (!pv_rhino_get_intent_func) {
232  print_dl_error("failed to load 'pv_rhino_get_intent'");
233  exit(1);
234  }
235 
236  pv_status_t (*pv_rhino_free_slots_and_values_func)(const pv_rhino_t *, const char **, const char **) =
237  load_symbol(rhino_library, "pv_rhino_free_slots_and_values");
238  if (!pv_rhino_free_slots_and_values_func) {
239  print_dl_error("failed to load 'pv_rhino_free_slots_and_values'");
240  exit(1);
241  }
242 
243  pv_status_t (*pv_rhino_reset_func)(pv_rhino_t *) =
244  load_symbol(rhino_library, "pv_rhino_reset");
245  if (!pv_rhino_reset_func) {
246  print_dl_error("failed to load 'pv_rhino_reset'");
247  exit(1);
248  }
249 
250  pv_status_t (*pv_rhino_context_info_func)(const pv_rhino_t *, const char **) =
251  load_symbol(rhino_library, "pv_rhino_context_info");
252  if (!pv_rhino_context_info_func) {
253  print_dl_error("failed to load 'pv_rhino_context_info'");
254  exit(1);
255  }
256 
257  int32_t (*pv_rhino_frame_length_func)() = load_symbol(rhino_library, "pv_rhino_frame_length");
258  if (!pv_rhino_frame_length_func) {
259  print_dl_error("failed to load 'pv_rhino_frame_length'n");
260  exit(1);
261  }
262 
263  const char *(*pv_rhino_version_func)() = load_symbol(rhino_library, "pv_rhino_version");
264  if (!pv_rhino_version_func) {
265  print_dl_error("failed to load 'pv_rhino_version'");
266  exit(1);
267  }
268 
269  pv_rhino_t *rhino = NULL;
270  pv_status_t status = pv_rhino_init_func(
271  access_key,
272  model_path,
273  context_path,
274  sensitivity,
275  require_endpoint,
276  &rhino);
277  if (status != PV_STATUS_SUCCESS) {
278  fprintf(stderr, "'pv_rhino_init' failed with '%s'\n", pv_status_to_string_func(status));
279  exit(1);
280  }
281 
282  fprintf(stdout, "Picovoice Rhino Speech-to-Intent (%s)\n\n", pv_rhino_version_func());
283 
284  const int32_t frame_length = pv_rhino_frame_length_func();
285  pv_recorder_t *recorder = NULL;
286  pv_recorder_status_t recorder_status = pv_recorder_init(device_index, frame_length, 100, true, &recorder);
287  if (recorder_status != PV_RECORDER_STATUS_SUCCESS) {
288  fprintf(stderr, "Failed to initialize device with %s.\n", pv_recorder_status_to_string(recorder_status));
289  exit(1);
290  }
291 
292  const char *context_info = NULL;
293  status = pv_rhino_context_info_func(rhino, &context_info);
294  if (status != PV_STATUS_SUCCESS) {
295  fprintf(stderr, "'pv_rhino_context_info' failed with '%s'\n", pv_status_to_string_func(status));
296  exit(1);
297  }
298  fprintf(stdout, "%s\n\n", context_info);
299 
300  const char *selected_device = pv_recorder_get_selected_device(recorder);
301  fprintf(stdout, "Selected device: %s.\n", selected_device);
302  fprintf(stdout, "Listening...\n\n");
303 
304  recorder_status = pv_recorder_start(recorder);
305  if (recorder_status != PV_RECORDER_STATUS_SUCCESS) {
306  fprintf(stderr, "Failed to start device with %s.\n", pv_recorder_status_to_string(recorder_status));
307  exit(1);
308  }
309 
310  int16_t *pcm = malloc(frame_length * sizeof(int16_t));
311  if (!pcm) {
312  fprintf(stderr, "Failed to allocate pcm memory.\n");
313  exit(1);
314  }
315 
316  while (!is_interrupted) {
317 
318  recorder_status = pv_recorder_read(recorder, pcm);
319  if (recorder_status != PV_RECORDER_STATUS_SUCCESS) {
320  fprintf(stderr, "Failed to read with %s.\n", pv_recorder_status_to_string(recorder_status));
321  exit(1);
322  }
323 
324  bool is_finalized = false;
325  status = pv_rhino_process_func(
326  rhino,
327  pcm,
328  &is_finalized);
329 
330  if (status != PV_STATUS_SUCCESS) {
331  fprintf(stderr, "'pv_rhino_process' failed with '%s'\n", pv_status_to_string_func(status));
332  exit(1);
333  }
334 
335  if (is_finalized) {
336  bool is_understood = false;
337  status = pv_rhino_is_understood_func(rhino, &is_understood);
338  if (status != PV_STATUS_SUCCESS) {
339  fprintf(stderr, "'pv_rhino_is_understood' failed with '%s'\n",
340  pv_status_to_string_func(status));
341  exit(1);
342  }
343 
344  const char *intent = NULL;
345  int32_t num_slots = 0;
346  const char **slots = NULL;
347  const char **values = NULL;
348 
349  if (is_understood) {
350  status = pv_rhino_get_intent_func(
351  rhino,
352  &intent,
353  &num_slots,
354  &slots,
355  &values);
356  if (status != PV_STATUS_SUCCESS) {
357  fprintf(stderr, "'pv_rhino_get_intent' failed with '%s'\n",
358  pv_status_to_string_func(status));
359  exit(1);
360  }
361  }
362 
363  fprintf(stdout, "{\n");
364  fprintf(stdout, " 'is_understood' : '%s',\n", is_understood ? "true" : "false");
365  if (is_understood) {
366  fprintf(stdout, " 'intent' : '%s',\n", intent);
367  if (num_slots > 0) {
368  fprintf(stdout, " 'slots' : {\n");
369  for (int32_t i = 0; i < num_slots; i++) {
370  fprintf(stdout, " '%s' : '%s',\n", slots[i], values[i]);
371  }
372  fprintf(stdout, " }\n");
373  }
374  }
375  fprintf(stdout, "}\n");
376  fflush(stdout);
377 
378  if (is_understood) {
379  status = pv_rhino_free_slots_and_values_func(rhino, slots, values);
380  if (status != PV_STATUS_SUCCESS) {
381  fprintf(stderr, "'pv_rhino_free_slots_and_values' failed with '%s'\n",
382  pv_status_to_string_func(status));
383  exit(1);
384  }
385  }
386 
387  status = pv_rhino_reset_func(rhino);
388  if (status != PV_STATUS_SUCCESS) {
389  fprintf(stderr, "'pv_rhino_reset' failed with '%s'\n",
390  pv_status_to_string_func(status));
391  exit(1);
392  }
393  }
394  }
395  fprintf(stdout, "\n");
396 
397  recorder_status = pv_recorder_stop(recorder);
398  if (recorder_status != PV_RECORDER_STATUS_SUCCESS) {
399  fprintf(stderr, "Failed to stop device with %s.\n", pv_recorder_status_to_string(recorder_status));
400  exit(1);
401  }
402 
403  free(pcm);
404  pv_recorder_delete(recorder);
405  pv_rhino_delete_func(rhino);
406  close_dl(rhino_library);
407 
408  return 0;
409 }
interrupt_handler
void interrupt_handler(int _)
Definition: rhino_demo_mic.c:106
NULL
#define NULL
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/speex_resampler/thirdparty/resample.c:92
pv_recorder_delete
PV_API void pv_recorder_delete(pv_recorder_t *object)
Definition: porcupine/demo/c/pvrecorder/src/pv_recorder.c:162
show_audio_devices
void show_audio_devices(void)
Definition: rhino_demo_mic.c:111
pv_recorder_init
PV_API pv_recorder_status_t pv_recorder_init(int32_t device_index, int32_t frame_length, int32_t buffer_size_msec, bool log_overflow, pv_recorder_t **object)
Definition: porcupine/demo/c/pvrecorder/src/pv_recorder.c:51
pv_recorder_free_device_list
PV_API void pv_recorder_free_device_list(int32_t count, char **devices)
Definition: porcupine/demo/c/pvrecorder/src/pv_recorder.c:314
pv_recorder_read
PV_API pv_recorder_status_t pv_recorder_read(pv_recorder_t *object, int16_t *pcm)
Definition: porcupine/demo/c/pvrecorder/src/pv_recorder.c:213
is_interrupted
static volatile bool is_interrupted
Definition: rhino_demo_mic.c:31
long_options
static struct option long_options[]
Definition: rhino_demo_mic.c:89
close_dl
static void close_dl(void *handle)
Definition: rhino_demo_mic.c:61
pv_recorder_stop
PV_API pv_recorder_status_t pv_recorder_stop(pv_recorder_t *object)
Definition: porcupine/demo/c/pvrecorder/src/pv_recorder.c:192
load_symbol
static void * load_symbol(void *handle, const char *symbol)
Definition: rhino_demo_mic.c:47
pv_recorder_status_t
pv_recorder_status_t
Definition: porcupine/demo/c/pvrecorder/include/pv_recorder.h:31
PV_STATUS_SUCCESS
@ PV_STATUS_SUCCESS
Definition: porcupine/include/picovoice.h:34
pv_status_t
pv_status_t
Definition: porcupine/include/picovoice.h:33
pv_recorder_get_selected_device
const PV_API char * pv_recorder_get_selected_device(pv_recorder_t *object)
Definition: porcupine/demo/c/pvrecorder/src/pv_recorder.c:249
main
int main(int argc, char *argv[])
Definition: rhino_demo_mic.c:129
count
size_t count
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/tests/test_common/ma_test_common.c:31
pv_recorder
Definition: porcupine/demo/c/pvrecorder/src/pv_recorder.c:28
open_dl
static void * open_dl(const char *dl_path)
Definition: rhino_demo_mic.c:33
print_dl_error
static void print_dl_error(const char *message)
Definition: rhino_demo_mic.c:75
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
pv_recorder_status_to_string
const PV_API char * pv_recorder_status_to_string(pv_recorder_status_t status)
Definition: porcupine/demo/c/pvrecorder/src/pv_recorder.c:323
pv_recorder_start
PV_API pv_recorder_status_t pv_recorder_start(pv_recorder_t *object)
Definition: porcupine/demo/c/pvrecorder/src/pv_recorder.c:172
PV_RECORDER_STATUS_SUCCESS
@ PV_RECORDER_STATUS_SUCCESS
Definition: porcupine/demo/c/pvrecorder/include/pv_recorder.h:32
pv_recorder_get_audio_devices
PV_API pv_recorder_status_t pv_recorder_get_audio_devices(int32_t *count, char ***devices)
Definition: porcupine/demo/c/pvrecorder/src/pv_recorder.c:256
print_usage
static void print_usage(const char *program_name)
Definition: rhino_demo_mic.c:100


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