-
Notifications
You must be signed in to change notification settings - Fork 721
/
live_portaudio.c
122 lines (115 loc) · 3.93 KB
/
live_portaudio.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/* Example of simple PocketSphinx speech segmentation.
*
* MIT license (c) 2022, see LICENSE for more information.
*
* Author: David Huggins-Daines <[email protected]>
*/
/**
* @example live_portaudio.c
* @brief Speech recognition with live audio input and endpointing.
*
* This file shows how to use PocketSphinx with microphone input using
* PortAudio (v19 and above).
*
* To compile it, assuming you have built the library as in
* \ref unix_install "these directions", you can run:
*
* cmake --build build --target live_portaudio
*
* Alternately, if PocketSphinx is installed system-wide, you can run:
*
* gcc -o live_portaudio live_portaudio.c \
* $(pkg-config --libs --cflags pocketsphinx portaudio-2.0)
*
*
*/
#include <portaudio.h>
#include <pocketsphinx.h>
#include <signal.h>
static int global_done = 0;
static void
catch_sig(int signum)
{
(void)signum;
global_done = 1;
}
int
main(int argc, char *argv[])
{
PaStream *stream;
PaError err;
ps_decoder_t *decoder;
ps_config_t *config;
ps_endpointer_t *ep;
short *frame;
size_t frame_size;
(void)argc; (void)argv;
config = ps_config_init(NULL);
ps_default_search_args(config);
if ((err = Pa_Initialize()) != paNoError)
E_FATAL("Failed to initialize PortAudio: %s\n",
Pa_GetErrorText(err));
if ((decoder = ps_init(config)) == NULL)
E_FATAL("PocketSphinx decoder init failed\n");
if ((ep = ps_endpointer_init(0, 0.0, 0, 0, 0)) == NULL)
E_FATAL("PocketSphinx endpointer init failed\n");
frame_size = ps_endpointer_frame_size(ep);
if ((frame = malloc(frame_size * sizeof(frame[0]))) == NULL)
E_FATAL_SYSTEM("Failed to allocate frame");
if ((err = Pa_OpenDefaultStream(&stream, 1, 0, paInt16,
ps_config_int(config, "samprate"),
frame_size, NULL, NULL)) != paNoError)
E_FATAL("Failed to open PortAudio stream: %s\n",
Pa_GetErrorText(err));
if ((err = Pa_StartStream(stream)) != paNoError)
E_FATAL("Failed to start PortAudio stream: %s\n",
Pa_GetErrorText(err));
if (signal(SIGINT, catch_sig) == SIG_ERR)
E_FATAL_SYSTEM("Failed to set SIGINT handler");
while (!global_done) {
const int16 *speech;
int prev_in_speech = ps_endpointer_in_speech(ep);
if ((err = Pa_ReadStream(stream, frame, frame_size)) != paNoError) {
E_ERROR("Error in PortAudio read: %s\n",
Pa_GetErrorText(err));
break;
}
speech = ps_endpointer_process(ep, frame);
if (speech != NULL) {
const char *hyp;
if (!prev_in_speech) {
fprintf(stderr, "Speech start at %.2f\n",
ps_endpointer_speech_start(ep));
fflush(stderr); /* For broken MSYS2 terminal */
ps_start_utt(decoder);
}
if (ps_process_raw(decoder, speech, frame_size, FALSE, FALSE) < 0)
E_FATAL("ps_process_raw() failed\n");
if ((hyp = ps_get_hyp(decoder, NULL)) != NULL) {
fprintf(stderr, "PARTIAL RESULT: %s\n", hyp);
fflush(stderr);
}
if (!ps_endpointer_in_speech(ep)) {
fprintf(stderr, "Speech end at %.2f\n",
ps_endpointer_speech_end(ep));
fflush(stderr);
ps_end_utt(decoder);
if ((hyp = ps_get_hyp(decoder, NULL)) != NULL) {
printf("%s\n", hyp);
fflush(stdout);
}
}
}
}
if ((err = Pa_StopStream(stream)) != paNoError)
E_FATAL("Failed to stop PortAudio stream: %s\n",
Pa_GetErrorText(err));
if ((err = Pa_Terminate()) != paNoError)
E_FATAL("Failed to terminate PortAudio: %s\n",
Pa_GetErrorText(err));
free(frame);
ps_endpointer_free(ep);
ps_free(decoder);
ps_config_free(config);
return 0;
}