76 #include <alsa/asoundlib.h>
84 #define AUDIO_FORMAT SND_PCM_SFMT_S16_LE
86 #define SPS_EPSILON 200
88 #define DEFAULT_DEVICE "default"
98 setparams(int32 sps, snd_pcm_t * handle)
100 snd_pcm_hw_params_t *hwparams;
101 unsigned int out_sps, buffer_time, period_time;
104 snd_pcm_hw_params_alloca(&hwparams);
105 err = snd_pcm_hw_params_any(handle, hwparams);
107 fprintf(stderr,
"Can not configure this PCM device: %s\n",
113 snd_pcm_hw_params_set_access(handle, hwparams,
114 SND_PCM_ACCESS_RW_INTERLEAVED);
117 "Failed to set PCM device to interleaved: %s\n",
123 snd_pcm_hw_params_set_format(handle, hwparams, SND_PCM_FORMAT_S16);
126 "Failed to set PCM device to 16-bit signed PCM: %s\n",
131 err = snd_pcm_hw_params_set_channels(handle, hwparams, 1);
133 fprintf(stderr,
"Failed to set PCM device to mono: %s\n",
140 snd_pcm_hw_params_set_rate_near(handle, hwparams, &out_sps, NULL);
142 fprintf(stderr,
"Failed to set sampling rate: %s\n",
146 if (abs(out_sps - sps) > SPS_EPSILON) {
148 "Available samping rate %d is too far from requested %d\n",
154 err = snd_pcm_hw_params_get_buffer_time_max(hwparams, &buffer_time, 0);
155 period_time = buffer_time / 4;
156 err = snd_pcm_hw_params_set_period_time_near(handle, hwparams,
159 fprintf(stderr,
"Failed to set period time to %u: %s\n",
160 period_time, snd_strerror(err));
163 err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams,
166 fprintf(stderr,
"Failed to set buffer time to %u: %s\n",
167 buffer_time, snd_strerror(err));
171 err = snd_pcm_hw_params(handle, hwparams);
173 fprintf(stderr,
"Failed to set hwparams: %s\n", snd_strerror(err));
177 err = snd_pcm_nonblock(handle, 1);
179 fprintf(stderr,
"Failed to set non-blocking mode: %s\n",
195 dev = DEFAULT_DEVICE;
197 err = snd_pcm_open(&dspH, dev, SND_PCM_STREAM_CAPTURE, 0);
200 "Error opening audio device %s for capture: %s\n",
201 dev, snd_strerror(err));
205 if (setparams(sps, dspH) < 0) {
209 fprintf(stderr,
"calloc(%d) failed\n", (
int)
sizeof(
ad_rec_t));
214 handle->recording = 0;
216 handle->bps =
sizeof(int16);
237 if (handle->dspH == NULL)
238 return AD_ERR_NOT_OPEN;
240 if (handle->recording) {
241 if (ad_stop_rec(handle) < 0)
244 snd_pcm_close(handle->dspH);
256 if (handle->dspH == NULL)
257 return AD_ERR_NOT_OPEN;
259 if (handle->recording)
262 err = snd_pcm_prepare(handle->dspH);
264 fprintf(stderr,
"snd_pcm_prepare failed: %s\n", snd_strerror(err));
267 err = snd_pcm_start(handle->dspH);
269 fprintf(stderr,
"snd_pcm_start failed: %s\n", snd_strerror(err));
272 handle->recording = 1;
283 if (handle->dspH == NULL)
284 return AD_ERR_NOT_OPEN;
286 if (!handle->recording)
289 err = snd_pcm_drop(handle->dspH);
291 fprintf(stderr,
"snd_pcm_drop failed: %s\n", snd_strerror(err));
294 handle->recording = 0;
301 ad_read(
ad_rec_t * handle, int16 * buf, int32 max)
305 if (!handle->recording) {
306 fprintf(stderr,
"Recording is stopped, start recording with ad_start_rec\n");
310 length = snd_pcm_readi(handle->dspH, buf, max);
311 if (length == -EAGAIN) {
314 else if (length == -EPIPE) {
315 fprintf(stderr,
"Input overrun, read calls are too rare (non-fatal)\n");
316 err = snd_pcm_prepare(handle->dspH);
318 fprintf(stderr,
"Can't recover from underrun: %s\n",
324 else if (length == -ESTRPIPE) {
325 fprintf(stderr,
"Resuming sound driver (non-fatal)\n");
326 while ((err = snd_pcm_resume(handle->dspH)) == -EAGAIN)
329 err = snd_pcm_prepare(handle->dspH);
331 fprintf(stderr,
"Can't recover from underrun: %s\n",
338 else if (length < 0) {
339 fprintf(stderr,
"Audio read error: %s\n",
340 snd_strerror(length));
Audio recording structure.
Basic type definitions used in Sphinx.
SPHINXBASE_EXPORT ad_rec_t * ad_open(void)
Open the default audio device.
generic live audio interface for recording and playback
SPHINXBASE_EXPORT ad_rec_t * ad_open_dev(const char *dev, int32 samples_per_sec)
Open a specific audio device for recording.
SPHINXBASE_EXPORT ad_rec_t * ad_open_sps(int32 samples_per_sec)
Open the default audio device with a given sampling rate.
Audio recording structure.