Cleanup ALSA mic initialization

ALSA microphone code still suck but now a little bit less.
Cleanup the initialization:
- use default device
- don't force a buffer size and a period which some drivers
can't support, instead query the driver for them

The next step would be to add use interrupt driven capturing
on a separathe thread but ALSA is a bitch...
This commit is contained in:
riccardom 2010-01-26 20:47:36 +00:00
parent 1d7b5994ee
commit 136f3a8642
1 changed files with 18 additions and 23 deletions

View File

@ -36,72 +36,67 @@ u8 Mic_WriteBuf;
int MicButtonPressed; int MicButtonPressed;
// Handle for the PCM device /* Alsa stuff */
static snd_pcm_t *pcm_handle; static snd_pcm_t *pcm_handle;
BOOL Mic_Init() BOOL Mic_Init()
{ {
snd_pcm_hw_params_t *hwparams; snd_pcm_hw_params_t *hwparams;
snd_pcm_uframes_t mic_bufsize, periods;
int err; int err;
if (Mic_Inited) if (Mic_Inited)
return TRUE; return TRUE;
// Open the default sound card in capture if ((err = snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) {
if ((err = snd_pcm_open(&pcm_handle, "plughw:0,0", SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) {
g_printerr("Failed to open device: %s\n", snd_strerror(err)); g_printerr("Failed to open device: %s\n", snd_strerror(err));
return FALSE; return FALSE;
} }
// Allocate the snd_pcm_hw_params_t structure and fill it. /* Hardware params */
snd_pcm_hw_params_alloca(&hwparams); snd_pcm_hw_params_alloca(&hwparams);
if ((err = snd_pcm_hw_params_any(pcm_handle, hwparams)) < 0) { if ((err = snd_pcm_hw_params_any(pcm_handle, hwparams)) < 0) {
g_printerr("Failed to setup hw parameters: %s\n", snd_strerror(err)); g_printerr("Failed to setup hw parameters: %s\n", snd_strerror(err));
return FALSE; return FALSE;
} }
//Set the access
if ((err = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { if ((err = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
g_printerr("Failed to set access: %s\n", snd_strerror(err)); g_printerr("Failed to set access: %s\n", snd_strerror(err));
return FALSE; return FALSE;
} }
//dir 0 == exacte (Rate = 16K exacte) /* 8bit signed, mono, 16000hz */
if ((err = snd_pcm_hw_params_set_rate(pcm_handle, hwparams, 16000, 0)) < 0) {
g_printerr("Failed to set rate: %s\n", snd_strerror(err));
return FALSE;
}
/* Set sample format */
if ((err = snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S8)) < 0) { if ((err = snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S8)) < 0) {
g_printerr("Failed to set format: %s\n", snd_strerror(err)); g_printerr("Failed to set format: %s\n", snd_strerror(err));
return FALSE; return FALSE;
} }
// Set one channel (mono)
if ((err = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 1)) < 0) { if ((err = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 1)) < 0) {
g_printerr("Failed to set channels: %s\n", snd_strerror(err)); g_printerr("Failed to set channels: %s\n", snd_strerror(err));
return FALSE; return FALSE;
} }
// Set 2 periods if ((err = snd_pcm_hw_params_set_rate(pcm_handle, hwparams, 16000, 0)) < 0) {
if ((err = snd_pcm_hw_params_set_periods(pcm_handle, hwparams, 2, 0)) < 0) { g_printerr("Failed to set rate: %s\n", snd_strerror(err));
g_printerr("Failed to set periods: %s\n", snd_strerror(err));
return FALSE; return FALSE;
} }
// Set the buffer sise
if ((err = snd_pcm_hw_params_set_buffer_size(pcm_handle, hwparams, MIC_BUFSIZE)) < 0) {
g_printerr("Failed to set buffer size: %s\n", snd_strerror(err));
return FALSE;
}
//Set the params
if ((err = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) { if ((err = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) {
g_printerr("Failed to set hw parameters: %s\n", snd_strerror(err)); g_printerr("Failed to set hw parameters: %s\n", snd_strerror(err));
return FALSE; return FALSE;
} }
/* Query the driver for buffer and period sizes */
if ((err = snd_pcm_hw_params_get_buffer_size(hwparams, &mic_bufsize)) < 0) {
g_printerr("Failed to get buffer size: %s\n", snd_strerror(err));
return FALSE;
}
if ((err = snd_pcm_hw_params_get_period_size(hwparams, &periods, 0)) < 0) {
g_printerr("Failed to get period size: %s\n", snd_strerror(err));
return FALSE;
}
Mic_Inited = TRUE; Mic_Inited = TRUE;
Mic_Reset(); Mic_Reset();