From 6c7f60f7a982fdba828e4530a9d7aa0aa2b704ae Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 16 Jun 2005 14:03:15 +0000 Subject: [PATCH] Fix boundary overlap Fixed the possible bug with boundary overlap in dmix code. --- src/pcm/pcm_dmix.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c index 462a5a21..af4a67a9 100644 --- a/src/pcm/pcm_dmix.c +++ b/src/pcm/pcm_dmix.c @@ -239,13 +239,20 @@ static void snd_pcm_dmix_sync_area(snd_pcm_t *pcm) { snd_pcm_direct_t *dmix = pcm->private_data; snd_pcm_uframes_t appl_ptr, slave_appl_ptr, slave_bsize; - snd_pcm_uframes_t size, slave_hw_ptr; + snd_pcm_uframes_t size, slave_size, slave_hw_ptr; const snd_pcm_channel_area_t *src_areas, *dst_areas; /* calculate the size to transfer */ + /* check the available size in the local buffer + * last_appl_ptr keeps the last updated position + */ size = dmix->appl_ptr - dmix->last_appl_ptr; if (! size) return; + if (size >= pcm->boundary / 2) + size = pcm->boundary - size; + + /* check the available size in the slave PCM buffer */ slave_bsize = dmix->shmptr->s.buffer_size; slave_hw_ptr = dmix->slave_hw_ptr; /* don't write on the last active period - this area may be cleared @@ -253,12 +260,17 @@ static void snd_pcm_dmix_sync_area(snd_pcm_t *pcm) */ slave_hw_ptr -= slave_hw_ptr % dmix->shmptr->s.period_size; slave_hw_ptr += slave_bsize; - if (dmix->slave_hw_ptr > dmix->slave_appl_ptr) + if (slave_hw_ptr >= dmix->shmptr->s.boundary) slave_hw_ptr -= dmix->shmptr->s.boundary; - if (dmix->slave_appl_ptr + size >= slave_hw_ptr) - size = slave_hw_ptr - dmix->slave_appl_ptr; + if (slave_hw_ptr < dmix->slave_appl_ptr) + slave_size = slave_hw_ptr + (dmix->shmptr->s.boundary - dmix->slave_appl_ptr); + else + slave_size = slave_hw_ptr - dmix->slave_appl_ptr; + if (slave_size < size) + size = slave_size; if (! size) return; + /* add sample areas here */ src_areas = snd_pcm_mmap_areas(pcm); dst_areas = snd_pcm_mmap_areas(dmix->spcm); -- 2.47.1