Handle ALSA capture errors a bit better

This commit is contained in:
Chris Robinson
2008-11-19 09:01:03 -08:00
parent c8123756ff
commit 2d461379ef
+35 -9
View File
@@ -724,9 +724,8 @@ static void alsa_close_capture(ALCdevice *pDevice)
static void alsa_start_capture(ALCdevice *pDevice)
{
alsa_data *data = (alsa_data*)pDevice->ExtraData;
if(data->thread)
data->doCapture = 1;
else
data->doCapture = 1;
if(!data->thread)
{
psnd_pcm_prepare(data->pcmHandle);
psnd_pcm_start(data->pcmHandle);
@@ -736,9 +735,8 @@ static void alsa_start_capture(ALCdevice *pDevice)
static void alsa_stop_capture(ALCdevice *pDevice)
{
alsa_data *data = (alsa_data*)pDevice->ExtraData;
if(data->thread)
data->doCapture = 0;
else
data->doCapture = 0;
if(!data->thread)
psnd_pcm_drain(data->pcmHandle);
}
@@ -748,6 +746,7 @@ static void alsa_capture_samples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint l
const snd_pcm_channel_area_t *areas = NULL;
snd_pcm_sframes_t frames, commitres;
snd_pcm_uframes_t size, offset;
snd_pcm_state_t state;
int err;
if(data->thread)
@@ -759,6 +758,17 @@ static void alsa_capture_samples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint l
return;
}
state = psnd_pcm_state(data->pcmHandle);
if(state == SND_PCM_STATE_XRUN)
{
err = xrun_recovery(data->pcmHandle, -EPIPE);
if(err < 0)
{
AL_PRINT("XRUN recovery failed: %s\n", psnd_strerror(err));
return;
}
}
frames = psnd_pcm_avail_update(data->pcmHandle);
if(frames < 0)
{
@@ -815,20 +825,36 @@ static ALCuint alsa_available_samples(ALCdevice *pDevice)
{
alsa_data *data = (alsa_data*)pDevice->ExtraData;
snd_pcm_sframes_t frames;
snd_pcm_state_t state;
int err;
if(data->thread)
return RingBufferSize(data->ring);
state = psnd_pcm_state(data->pcmHandle);
if(state == SND_PCM_STATE_XRUN)
{
err = xrun_recovery(data->pcmHandle, -EPIPE);
if(err >= 0)
{
if(data->doCapture)
err = psnd_pcm_start(data->pcmHandle);
}
if (err < 0)
{
AL_PRINT("XRUN recovery failed: %s\n", psnd_strerror(err));
return 0;
}
}
frames = psnd_pcm_avail_update(data->pcmHandle);
if(frames < 0)
{
int err = xrun_recovery(data->pcmHandle, frames);
err = xrun_recovery(data->pcmHandle, frames);
if (err < 0)
AL_PRINT("available update failed: %s\n", psnd_strerror(err));
else
frames = psnd_pcm_avail_update(data->pcmHandle);
if(frames < 0) /* ew.. */
SetALCError(ALC_INVALID_DEVICE);
}
return max(frames, 0);
}