c/porcupine_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 <math.h>
14 #include <signal.h>
15 #include <stdio.h>
16 #include <stdlib.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_porcupine.h"
29 #include "pv_recorder.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  {"keyword_path", required_argument, NULL, 'k'},
94  {"sensitivity", required_argument, NULL, 't'},
95  {"access_key", required_argument, NULL, 'a'},
96  {"audio_device_index", required_argument, NULL, 'd'}
97 };
98 
99 static void print_usage(const char *program_name) {
100  fprintf(stderr, "Usage : %s -l LIBRARY_PATH -m MODEL_PATH -k KEYWORD_PATH -t SENSTIVITY -a ACCESS_KEY -d AUDIO_DEVICE_INDEX\n"
101  " %s [-s, --show_audio_devices]\n", program_name, program_name);
102 }
103 
104 void interrupt_handler(int _) {
105  (void) _;
106  is_interrupted = true;
107 }
108 
109 void show_audio_devices(void) {
110  char **devices = NULL;
111  int32_t count = 0;
112 
114  if (status != PV_RECORDER_STATUS_SUCCESS) {
115  fprintf(stderr, "Failed to get audio devices with: %s.\n", pv_recorder_status_to_string(status));
116  exit(1);
117  }
118 
119  fprintf(stdout, "Printing devices...\n");
120  for (int32_t i = 0; i < count; i++) {
121  fprintf(stdout, "index: %d, name: %s\n", i, devices[i]);
122  }
123 
125 }
126 
127 int main(int argc, char *argv[]) {
128  signal(SIGINT, interrupt_handler);
129 
130  const char *library_path = NULL;
131  const char *model_path = NULL;
132  const char *keyword_path = NULL;
133  float sensitivity = 0.5f;
134  const char *access_key = NULL;
135  int32_t device_index = -1;
136 
137  int c;
138  while ((c = getopt_long(argc, argv, "sl:m:k:t:a:d:", long_options, NULL)) != -1) {
139  switch (c) {
140  case 's':
142  return 0;
143  case 'l':
144  library_path = optarg;
145  break;
146  case 'm':
147  model_path = optarg;
148  break;
149  case 'k':
150  keyword_path = optarg;
151  break;
152  case 't':
153  sensitivity = strtof(optarg, NULL);
154  break;
155  case 'a':
156  access_key = optarg;
157  break;
158  case 'd':
159  device_index = (int32_t) strtol(optarg, NULL, 10);
160  break;
161  default:
162  exit(1);
163  }
164  }
165 
166  if (!library_path || !model_path || !keyword_path || !access_key) {
167  print_usage(argv[0]);
168  exit(1);
169  }
170 
171  void *porcupine_library = open_dl(library_path);
172  if (!porcupine_library) {
173  fprintf(stderr, "failed to open library.\n");
174  exit(1);
175  }
176 
177  const char *(*pv_status_to_string_func)(pv_status_t) = load_symbol(porcupine_library, "pv_status_to_string");
178  if (!pv_status_to_string_func) {
179  print_dl_error("failed to load 'pv_status_to_string'");
180  exit(1);
181  }
182 
183  int32_t (*pv_sample_rate_func)() = load_symbol(porcupine_library, "pv_sample_rate");
184  if (!pv_sample_rate_func) {
185  print_dl_error("failed to load 'pv_sample_rate'");
186  exit(1);
187  }
188 
189  pv_status_t (*pv_porcupine_init_func)(const char *, const char *, int32_t, const char *const *, const float *, pv_porcupine_t **)
190  = load_symbol(porcupine_library, "pv_porcupine_init");
191  if (!pv_porcupine_init_func) {
192  print_dl_error("failed to load 'pv_porcupine_init'");
193  exit(1);
194  }
195 
196  void (*pv_porcupine_delete_func)(pv_porcupine_t *) = load_symbol(porcupine_library, "pv_porcupine_delete");
197  if (!pv_porcupine_delete_func) {
198  print_dl_error("failed to load 'pv_porcupine_delete'");
199  exit(1);
200  }
201 
202  pv_status_t (*pv_porcupine_process_func)(pv_porcupine_t *, const int16_t *, int32_t *)
203  = load_symbol(porcupine_library, "pv_porcupine_process");
204  if (!pv_porcupine_process_func) {
205  print_dl_error("failed to load 'pv_porcupine_process'");
206  exit(1);
207  }
208 
209  int32_t (*pv_porcupine_frame_length_func)() = load_symbol(porcupine_library, "pv_porcupine_frame_length");
210  if (!pv_porcupine_frame_length_func) {
211  print_dl_error("failed to load 'pv_porcupine_frame_length'");
212  exit(1);
213  }
214 
215  const char *(*pv_porcupine_version_func)() = load_symbol(porcupine_library, "pv_porcupine_version");
216  if (!pv_porcupine_version_func) {
217  print_dl_error("failed to load 'pv_porcupine_version'");
218  exit(1);
219  }
220 
221  pv_porcupine_t *porcupine = NULL;
222  pv_status_t porcupine_status = pv_porcupine_init_func(access_key, model_path, 1, &keyword_path, &sensitivity, &porcupine);
223  if (porcupine_status != PV_STATUS_SUCCESS) {
224  fprintf(stderr, "'pv_porcupine_init' failed with '%s'\n", pv_status_to_string_func(porcupine_status));
225  exit(1);
226  }
227 
228  fprintf(stdout, "V%s\n\n", pv_porcupine_version_func());
229 
230  const int32_t frame_length = pv_porcupine_frame_length_func();
231  pv_recorder_t *recorder = NULL;
232  pv_recorder_status_t recorder_status = pv_recorder_init(device_index, frame_length, 100, true, &recorder);
233  if (recorder_status != PV_RECORDER_STATUS_SUCCESS) {
234  fprintf(stderr, "Failed to initialize device with %s.\n", pv_recorder_status_to_string(recorder_status));
235  exit(1);
236  }
237 
238  const char *selected_device = pv_recorder_get_selected_device(recorder);
239  fprintf(stdout, "Selected device: %s.\n", selected_device);
240 
241  fprintf(stdout, "Start recording...\n");
242  recorder_status = pv_recorder_start(recorder);
243  if (recorder_status != PV_RECORDER_STATUS_SUCCESS) {
244  fprintf(stderr, "Failed to start device with %s.\n", pv_recorder_status_to_string(recorder_status));
245  exit(1);
246  }
247 
248  int16_t *pcm = malloc(frame_length * sizeof(int16_t));
249  if (!pcm) {
250  fprintf(stderr, "Failed to allocate pcm memory.\n");
251  exit(1);
252  }
253 
254  while (!is_interrupted) {
255  recorder_status = pv_recorder_read(recorder, pcm);
256  if (recorder_status != PV_RECORDER_STATUS_SUCCESS) {
257  fprintf(stderr, "Failed to read with %s.\n", pv_recorder_status_to_string(recorder_status));
258  exit(1);
259  }
260 
261  int32_t keyword_index = -1;
262  porcupine_status = pv_porcupine_process_func(porcupine, pcm, &keyword_index);
263  if (porcupine_status != PV_STATUS_SUCCESS) {
264  fprintf(stderr, "'pv_porcupine_process' failed with '%s'\n", pv_status_to_string_func(porcupine_status));
265  exit(1);
266  }
267 
268  if (keyword_index != -1) {
269  fprintf(stdout, "keyword detected\n");
270  fflush(stdout);
271  }
272  }
273  fprintf(stdout, "\n");
274 
275  recorder_status = pv_recorder_stop(recorder);
276  if (recorder_status != PV_RECORDER_STATUS_SUCCESS) {
277  fprintf(stderr, "Failed to stop device with %s.\n", pv_recorder_status_to_string(recorder_status));
278  exit(1);
279  }
280 
281  free(pcm);
282  pv_recorder_delete(recorder);
283  pv_porcupine_delete_func(porcupine);
284  close_dl(porcupine_library);
285 
286  return 0;
287 }
is_interrupted
static volatile bool is_interrupted
Definition: c/porcupine_demo_mic.c:31
main
int main(int argc, char *argv[])
Definition: c/porcupine_demo_mic.c:127
print_usage
static void print_usage(const char *program_name)
Definition: c/porcupine_demo_mic.c:99
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
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
long_options
static struct option long_options[]
Definition: c/porcupine_demo_mic.c:89
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
pv_recorder_status_t
pv_recorder_status_t
Definition: porcupine/demo/c/pvrecorder/include/pv_recorder.h:31
print_dl_error
static void print_dl_error(const char *message)
Definition: c/porcupine_demo_mic.c:75
PV_STATUS_SUCCESS
@ PV_STATUS_SUCCESS
Definition: porcupine/include/picovoice.h:34
pv_status_t
pv_status_t
Definition: porcupine/include/picovoice.h:33
show_audio_devices
void show_audio_devices(void)
Definition: c/porcupine_demo_mic.c:109
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
count
size_t count
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/tests/test_common/ma_test_common.c:31
close_dl
static void close_dl(void *handle)
Definition: c/porcupine_demo_mic.c:61
pv_recorder
Definition: porcupine/demo/c/pvrecorder/src/pv_recorder.c:28
load_symbol
static void * load_symbol(void *handle, const char *symbol)
Definition: c/porcupine_demo_mic.c:47
interrupt_handler
void interrupt_handler(int _)
Definition: c/porcupine_demo_mic.c:104
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
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
open_dl
static void * open_dl(const char *dl_path)
Definition: c/porcupine_demo_mic.c:33


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