aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/backends
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2011-11-28 10:24:24 -0800
committerChris Robinson <[email protected]>2011-11-28 10:24:24 -0800
commit6a97f6a327134e83b7e1722dfe61fcb7f594b655 (patch)
tree7c12212d3ef6328d57811041f3e0032c7dae0fb5 /Alc/backends
parentdfd02817fafb39ce7e6d5cb41a95facd9fd910ff (diff)
Reset the ALSA device if the number of available samples grows too large
Diffstat (limited to 'Alc/backends')
-rw-r--r--Alc/backends/alsa.c17
1 files 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)