[PATCH 1/3] pcm: dmix: fix incorrect boundary handling in snd_pcm_dmix_sync_area

Maarten Baert maarten-baert at hotmail.com
Tue May 19 19:20:49 CEST 2020


Please ignore the '1/3', the next two patches are for dmix monitoring 
support and are still a work in progress.

Best regards,
Maarten Baert

On 19/05/2020 18:14, Maarten Baert wrote:
> The available size calculation did not handle wraparound correctly. Also, the
> underrun handling code confused slave_buffer_size with slave_boundary, causing
> another integer overflow that results in too many samples being skipped.
>
> Signed-off-by: Maarten Baert <maarten-baert at hotmail.com>
> ---
>   src/pcm/pcm_dmix.c | 16 +++++++++-------
>   1 file changed, 9 insertions(+), 7 deletions(-)
>
> diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c
> index 843fa316..b5fdb240 100644
> --- a/src/pcm/pcm_dmix.c
> +++ b/src/pcm/pcm_dmix.c
> @@ -315,11 +315,12 @@ static void snd_pcm_dmix_sync_area(snd_pcm_t *pcm)
>   	/* 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 (dmix->appl_ptr >= dmix->last_appl_ptr)
> +		size = dmix->appl_ptr - dmix->last_appl_ptr;
> +	else
> +		size = dmix->appl_ptr + (pcm->boundary - dmix->last_appl_ptr);
>   	if (! size)
>   		return;
> -	if (size >= pcm->boundary / 2)
> -		size = pcm->boundary - size;
>   
>   	/* the slave_app_ptr can be far behind the slave_hw_ptr */
>   	/* reduce mixing and errors here - just skip not catched writes */
> @@ -328,18 +329,19 @@ static void snd_pcm_dmix_sync_area(snd_pcm_t *pcm)
>   	else
>   		slave_size = dmix->slave_appl_ptr + (dmix->slave_boundary - dmix->slave_hw_ptr);
>   	if (slave_size > dmix->slave_buffer_size) {
> -		transfer = dmix->slave_buffer_size - slave_size;
> +		transfer = dmix->slave_boundary - slave_size;
>   		if (transfer > size)
>   			transfer = size;
>   		dmix->last_appl_ptr += transfer;
>   		dmix->last_appl_ptr %= pcm->boundary;
>   		dmix->slave_appl_ptr += transfer;
>   		dmix->slave_appl_ptr %= dmix->slave_boundary;
> -		size = dmix->appl_ptr - dmix->last_appl_ptr;
> +		if (dmix->appl_ptr >= dmix->last_appl_ptr)
> +			size = dmix->appl_ptr - dmix->last_appl_ptr;
> +		else
> +			size = dmix->appl_ptr + (pcm->boundary - 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 */


More information about the Alsa-devel mailing list