respeaker-rpi0/porcupine_demo_mic.c
Go to the documentation of this file.
1 /*
2  Copyright 2018-2020 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 <signal.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 
16 #include <alsa/asoundlib.h>
17 #include <dlfcn.h>
18 
19 #include <wiringPi.h>
20 #include <wiringPiSPI.h>
21 
22 #include "pv_porcupine.h"
23 
24 static const uint8_t OFF_RGB[3] = {0, 0, 0};
25 static const uint8_t BLUE_RGB[3] = {0, 0, 255};
26 static const uint8_t GREEN_RGB[3] = {0, 255, 0};
27 static const uint8_t ORANGE_RGB[3] = {255, 128, 0};
28 static const uint8_t PINK_RGB[3] = {255, 51, 153};
29 static const uint8_t PURPLE_RGB[3] = {128, 0, 128};
30 static const uint8_t RED_RGB[3] = {255, 0, 0};
31 static const uint8_t WHITE_RGB[3] = {255, 255, 255};
32 static const uint8_t YELLOW_RGB[3] = {255, 255, 51};
33 
34 static volatile bool is_interrupted = false;
35 
36 static void set_color(const uint8_t rgb[3]) {
37  for(int32_t i = 0; i < 4; i++) {
38  uint8_t zero = 0x00;
39  wiringPiSPIDataRW(0, &zero, 1);
40  }
41 
42  static const uint32_t BRIGHTNESS = 1;
43  for(int32_t i = 0; i < 12; i++) {
44  uint8_t led_frame[4];
45  led_frame[0] = 0b11100000 | (0b00011111 & BRIGHTNESS);
46  led_frame[1] = rgb[2];
47  led_frame[2] = rgb[1];
48  led_frame[3] = rgb[0];
49  wiringPiSPIDataRW(0, led_frame, 4);
50  }
51 
52  for(int32_t i = 0; i < 4; i++) {
53  uint8_t zero = 0x00;
54  wiringPiSPIDataRW(0, &zero, 1);
55  }
56 }
57 
58 void interrupt_handler(int _) {
59  (void) _;
60  is_interrupted = true;
61 }
62 
63 int main(int argc, char *argv[]) {
64  if (argc != 15) {
65  fprintf(
66  stderr,
67  "usage : %s access_key library_path model_path sensitivity input_audio_device alexa_keyword_path "
68  "computer_keyword_path hey_google_keyword_path hey_siri_keyword_path jarvis_keyword_path "
69  "picovoice_keyword_path porcupine_keyword_path bumblebee_keyword_path terminator_keyword_path\n", argv[0]);
70  exit(1);
71  }
72 
73  signal(SIGINT, interrupt_handler);
74 
75  const char *access_key = argv[1];
76  const char *library_path = argv[2];
77  const char *model_path = argv[3];
78  const float sensitivity = (float) atof(argv[4]);
79  const char *input_audio_device = argv[5];
80  const char **keyword_paths = (const char **) &argv[6];
81  const int32_t num_keywords = 9;
82 
83  void *porcupine_library = dlopen(library_path, RTLD_NOW);
84  if (!porcupine_library) {
85  fprintf(stderr, "failed to open library.\n");
86  exit(1);
87  }
88 
89  char *error = NULL;
90 
91  const char *(*pv_status_to_string_func)(pv_status_t) = dlsym(porcupine_library, "pv_status_to_string");
92  if ((error = dlerror()) != NULL) {
93  fprintf(stderr, "failed to load 'pv_status_to_string' with '%s'.\n", error);
94  exit(1);
95  }
96 
97  int32_t (*pv_sample_rate_func)() = dlsym(porcupine_library, "pv_sample_rate");
98  if ((error = dlerror()) != NULL) {
99  fprintf(stderr, "failed to load 'pv_sample_rate' with '%s'.\n", error);
100  exit(1);
101  }
102 
103  pv_status_t (*pv_porcupine_init_func)(const char *, const char *, int32_t, const char *const *, const float *, pv_porcupine_t **) =
104  dlsym(porcupine_library, "pv_porcupine_init");
105  if ((error = dlerror()) != NULL) {
106  fprintf(stderr, "failed to load 'pv_porcupine_init' with '%s'.\n", error);
107  exit(1);
108  }
109 
110  void (*pv_porcupine_delete_func)(pv_porcupine_t *) = dlsym(porcupine_library, "pv_porcupine_delete");
111  if ((error = dlerror()) != NULL) {
112  fprintf(stderr, "failed to load 'pv_porcupine_delete' with '%s'.\n", error);
113  exit(1);
114  }
115 
116  pv_status_t (*pv_porcupine_process_func)(pv_porcupine_t *, const int16_t *, int32_t *) =
117  dlsym(porcupine_library, "pv_porcupine_process");
118  if ((error = dlerror()) != NULL) {
119  fprintf(stderr, "failed to load 'pv_porcupine_process' with '%s'.\n", error);
120  exit(1);
121  }
122 
123  int32_t (*pv_porcupine_frame_length_func)() = dlsym(porcupine_library, "pv_porcupine_frame_length");
124  if ((error = dlerror()) != NULL) {
125  fprintf(stderr, "failed to load 'pv_porcupine_frame_length' with '%s'.\n", error);
126  exit(1);
127  }
128 
129  pv_porcupine_t *porcupine = NULL;
130  float sensitivities[num_keywords];
131  for (int32_t i = 0; i < num_keywords; i++) {
132  sensitivities[i] = sensitivity;
133  }
134  pv_status_t status = pv_porcupine_init_func(access_key, model_path, num_keywords, keyword_paths, sensitivities, &porcupine);
135  if (status != PV_STATUS_SUCCESS) {
136  fprintf(stderr, "'pv_porcupine_init' failed with '%s'\n", pv_status_to_string_func(status));
137  exit(1);
138  }
139 
140  snd_pcm_t *alsa_handle = NULL;
141  int error_code = snd_pcm_open(&alsa_handle, input_audio_device, SND_PCM_STREAM_CAPTURE, 0);
142  if (error_code != 0) {
143  fprintf(stderr, "'snd_pcm_open' failed with '%s'\n", snd_strerror(error_code));
144  exit(1);
145  }
146 
147  snd_pcm_hw_params_t *hardware_params = NULL;
148  error_code = snd_pcm_hw_params_malloc(&hardware_params);
149  if (error_code != 0) {
150  fprintf(stderr, "'snd_pcm_hw_params_malloc' failed with '%s'\n", snd_strerror(error_code));
151  exit(1);
152  }
153 
154  error_code = snd_pcm_hw_params_any(alsa_handle, hardware_params);
155  if (error_code != 0) {
156  fprintf(stderr, "'snd_pcm_hw_params_any' failed with '%s'\n", snd_strerror(error_code));
157  exit(1);
158  }
159 
160  error_code = snd_pcm_hw_params_set_access(alsa_handle, hardware_params, SND_PCM_ACCESS_RW_INTERLEAVED);
161  if (error_code != 0) {
162  fprintf(stderr, "'snd_pcm_hw_params_set_access' failed with '%s'\n", snd_strerror(error_code));
163  exit(1);
164  }
165 
166  error_code = snd_pcm_hw_params_set_format(alsa_handle, hardware_params, SND_PCM_FORMAT_S16_LE);
167  if (error_code != 0) {
168  fprintf(stderr, "'snd_pcm_hw_params_set_format' failed with '%s'\n", snd_strerror(error_code));
169  exit(1);
170  }
171 
172  error_code = snd_pcm_hw_params_set_rate(alsa_handle, hardware_params, pv_sample_rate_func(), 0);
173  if (error_code != 0) {
174  fprintf(stderr, "'snd_pcm_hw_params_set_rate' failed with '%s'\n", snd_strerror(error_code));
175  exit(1);
176  }
177 
178  error_code = snd_pcm_hw_params_set_channels(alsa_handle, hardware_params, 1);
179  if (error_code != 0) {
180  fprintf(stderr, "'snd_pcm_hw_params_set_channels' failed with '%s'\n", snd_strerror(error_code));
181  exit(1);
182  }
183 
184  error_code = snd_pcm_hw_params(alsa_handle, hardware_params);
185  if (error_code != 0) {
186  fprintf(stderr, "'snd_pcm_hw_params' failed with '%s'\n", snd_strerror(error_code));
187  exit(1);
188  }
189 
190  snd_pcm_hw_params_free(hardware_params);
191 
192  error_code = snd_pcm_prepare(alsa_handle);
193  if (error_code != 0) {
194  fprintf(stderr, "'snd_pcm_prepare' failed with '%s'\n", snd_strerror(error_code));
195  exit(1);
196  }
197 
198  const int32_t frame_length = pv_porcupine_frame_length_func();
199 
200  int16_t *pcm = malloc(frame_length * sizeof(int16_t));
201  if (!pcm) {
202  fprintf(stderr, "failed to allocate memory for audio buffer\n");
203  exit(1);
204  }
205 
206  wiringPiSetup();
207  if(wiringPiSPISetup(0, 6000000) < 0) {
208  fprintf(stderr, "failed to setup SPI interface\n");
209  exit(1);
210  }
211 
212  pinMode(21, OUTPUT);
213  digitalWrite(21, HIGH);
214 
215  fprintf(stdout, "[Listening]\n");
216 
217  while (!is_interrupted) {
218  const int count = snd_pcm_readi(alsa_handle, pcm, frame_length);
219  if (count < 0) {
220  fprintf(stderr, "'snd_pcm_readi' failed with '%s'\n", snd_strerror(count));
221  exit(1);
222  } else if (count != frame_length) {
223  fprintf(stderr, "read %d frames instead of %d\n", count, frame_length);
224  exit(1);
225  }
226 
227  int32_t keyword_index = -1;
228  status = pv_porcupine_process_func(porcupine, pcm, &keyword_index);
229  if (status != PV_STATUS_SUCCESS) {
230  fprintf(stderr, "'pv_porcupine_process' failed with '%s'\n", pv_status_to_string_func(status));
231  exit(1);
232  }
233  if (keyword_index != -1) {
234  static const char *KEYWORDS[] = {
235  "Alexa",
236  "Computer",
237  "Hey Google",
238  "Hey Siri",
239  "Jarvis",
240  "Picovoice",
241  "Porcupine",
242  "Bumblebee",
243  "Terminator"
244  };
245 
246  fprintf(stdout, "detected '%s'\n", KEYWORDS[keyword_index]);
247 
248  static const char *COLORS[] = {
249  "yellow",
250  "white",
251  "red",
252  "purple",
253  "pink",
254  "green",
255  "blue",
256  "orange",
257  "off"
258  };
259 
260  switch (keyword_index) {
261  case 0:
263  break;
264  case 1:
266  break;
267  case 2:
269  break;
270  case 3:
272  break;
273  case 4:
275  break;
276  case 5:
278  break;
279  case 6:
281  break;
282  case 7:
284  break;
285  case 8:
287  break;
288  }
289  }
290  }
291 
292  free(pcm);
293  snd_pcm_close(alsa_handle);
294  pv_porcupine_delete_func(porcupine);
295  dlclose(porcupine_library);
296 
297  return 0;
298 }
PINK_RGB
static const uint8_t PINK_RGB[3]
Definition: respeaker-rpi0/porcupine_demo_mic.c:28
main
int main(int argc, char *argv[])
Definition: respeaker-rpi0/porcupine_demo_mic.c:63
NULL
#define NULL
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/speex_resampler/thirdparty/resample.c:92
is_interrupted
static volatile bool is_interrupted
Definition: respeaker-rpi0/porcupine_demo_mic.c:34
PV_STATUS_SUCCESS
@ PV_STATUS_SUCCESS
Definition: porcupine/include/picovoice.h:34
python.KEYWORDS
KEYWORDS
Definition: porcupine/binding/python/__init__.py:33
PURPLE_RGB
static const uint8_t PURPLE_RGB[3]
Definition: respeaker-rpi0/porcupine_demo_mic.c:29
pv_status_t
pv_status_t
Definition: porcupine/include/picovoice.h:33
count
size_t count
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/tests/test_common/ma_test_common.c:31
YELLOW_RGB
static const uint8_t YELLOW_RGB[3]
Definition: respeaker-rpi0/porcupine_demo_mic.c:32
pv_porcupine_t
struct pv_porcupine pv_porcupine_t
Definition: include/pv_porcupine.h:33
set_color
static void set_color(const uint8_t rgb[3])
Definition: respeaker-rpi0/porcupine_demo_mic.c:36
BLUE_RGB
static const uint8_t BLUE_RGB[3]
Definition: respeaker-rpi0/porcupine_demo_mic.c:25
python.test_porcupine.argv
argv
Definition: test_porcupine.py:158
interrupt_handler
void interrupt_handler(int _)
Definition: respeaker-rpi0/porcupine_demo_mic.c:58
GREEN_RGB
static const uint8_t GREEN_RGB[3]
Definition: respeaker-rpi0/porcupine_demo_mic.c:26
error
static int error(vorb *f, enum STBVorbisError e)
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/stb_vorbis.c:896
ORANGE_RGB
static const uint8_t ORANGE_RGB[3]
Definition: respeaker-rpi0/porcupine_demo_mic.c:27
WHITE_RGB
static const uint8_t WHITE_RGB[3]
Definition: respeaker-rpi0/porcupine_demo_mic.c:31
RED_RGB
static const uint8_t RED_RGB[3]
Definition: respeaker-rpi0/porcupine_demo_mic.c:30
OFF_RGB
static const uint8_t OFF_RGB[3]
Definition: respeaker-rpi0/porcupine_demo_mic.c:24


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