From 6a97f6a327134e83b7e1722dfe61fcb7f594b655 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 28 Nov 2011 10:24:24 -0800 Subject: [PATCH] Reset the ALSA device if the number of available samples grows too large --- Alc/backends/alsa.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Alc/backends/alsa.c b/Alc/backends/alsa.c index 85e1d802..362b25da 100644 --- a/Alc/backends/alsa.c +++ b/Alc/backends/alsa.c @@ -70,6 +70,7 @@ MAKE_FUNC(snd_pcm_sw_params_free); MAKE_FUNC(snd_pcm_prepare); MAKE_FUNC(snd_pcm_start); MAKE_FUNC(snd_pcm_resume); +MAKE_FUNC(snd_pcm_reset); MAKE_FUNC(snd_pcm_wait); MAKE_FUNC(snd_pcm_state); MAKE_FUNC(snd_pcm_avail_update); @@ -133,6 +134,7 @@ MAKE_FUNC(snd_card_next); #define snd_pcm_prepare psnd_pcm_prepare #define snd_pcm_start psnd_pcm_start #define snd_pcm_resume psnd_pcm_resume +#define snd_pcm_reset psnd_pcm_reset #define snd_pcm_wait psnd_pcm_wait #define snd_pcm_state psnd_pcm_state #define snd_pcm_avail_update psnd_pcm_avail_update @@ -214,6 +216,7 @@ static ALCboolean alsa_load(void) LOAD_FUNC(snd_pcm_prepare); LOAD_FUNC(snd_pcm_start); LOAD_FUNC(snd_pcm_resume); + LOAD_FUNC(snd_pcm_reset); LOAD_FUNC(snd_pcm_wait); LOAD_FUNC(snd_pcm_state); LOAD_FUNC(snd_pcm_avail_update); @@ -397,6 +400,7 @@ static ALuint ALSAProc(ALvoid *ptr) ALCdevice *pDevice = (ALCdevice*)ptr; alsa_data *data = (alsa_data*)pDevice->ExtraData; const snd_pcm_channel_area_t *areas = NULL; + snd_pcm_uframes_t update_size, num_updates; snd_pcm_sframes_t avail, commitres; snd_pcm_uframes_t offset, frames; char *WritePtr; @@ -404,6 +408,8 @@ static ALuint ALSAProc(ALvoid *ptr) SetRTPriority(); + update_size = pDevice->UpdateSize; + num_updates = pDevice->NumUpdates; while(!data->killNow) { int state = verify_state(data->pcmHandle); @@ -421,8 +427,15 @@ static ALuint ALSAProc(ALvoid *ptr) continue; } + if((snd_pcm_uframes_t)avail > update_size*(num_updates+1)) + { + WARN("available samples exceeds the buffer size\n"); + snd_pcm_reset(data->pcmHandle); + continue; + } + // make sure there's frames to process - if((snd_pcm_uframes_t)avail < pDevice->UpdateSize) + if((snd_pcm_uframes_t)avail < update_size) { if(state != SND_PCM_STATE_RUNNING) { @@ -437,7 +450,7 @@ static ALuint ALSAProc(ALvoid *ptr) ERR("Wait timeout... buffer size too low?\n"); continue; } - avail -= avail%pDevice->UpdateSize; + avail -= avail%update_size; // it is possible that contiguous areas are smaller, thus we use a loop while(avail > 0) -- 2.11.4.GIT