[alsa-devel] [PATCH - alsa-lib 1/1] Patch for two bugs in snd_pcm_area_silence().

Takashi Sakamoto o-takashi at sakamocchi.jp
Mon Jan 22 15:48:41 CET 2018


Hi,

On Jan 21 2018 12:27, alsa2 at bushytails.net wrote:
> From: furrywolf <alsa2 at bushytails.net>
> 
> First, after silencing the buffer 64 bits at a time, any remaining samples
> need to be silenced by the following width-specific code.  However, instead
> of silencing the end of the buffer, the code instead re-silences the start
> of the buffer, leaving the end unsilenced.  To fix this, update the pointer
> used by the width-specific code to point to the end of the area just
> silenced, instead of leaving it pointing to the start of the buffer.
> 
> Second, the code for 24 bit samples can only silence a single sample, as
> there's no loop for multiple samples as with other formats.  To fix this,
> add a loop similar to the ones used for every other width.
> 
> The symptoms of these bugs are random data at the end of every supposedly
> silenced buffer with certain format/buffer size combinations, resulting in
> pops and noise.
> 
> Signed-off-by: furrywolf <alsa2 at bushytails.net>
> 
> diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
> index 69d7d66..1753cda 100644
> --- a/src/pcm/pcm.c
> +++ b/src/pcm/pcm.c
> @@ -2955,6 +2955,7 @@ int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes
>   			*dstp++ = silence;
>   		if (samples == 0)
>   			return 0;
> +		dst = (char *)dstp;
>   	}
>   	dst_step = dst_area->step / 8;
>   	switch (width) {
> @@ -2996,16 +2997,20 @@ int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes
>   		}
>   		break;
>   	}
> -	case 24:
> +	case 24: {
> +		while (samples-- > 0) {
>   #ifdef SNDRV_LITTLE_ENDIAN
> -		*(dst + 0) = silence >> 0;
> -		*(dst + 1) = silence >> 8;
> -		*(dst + 2) = silence >> 16;
> +			*(dst + 0) = silence >> 0;
> +			*(dst + 1) = silence >> 8;
> +			*(dst + 2) = silence >> 16;
>   #else
> -		*(dst + 2) = silence >> 0;
> -		*(dst + 1) = silence >> 8;
> -		*(dst + 0) = silence >> 16;
> +			*(dst + 2) = silence >> 0;
> +			*(dst + 1) = silence >> 8;
> +			*(dst + 0) = silence >> 16;
>   #endif
> +			dst += dst_step;
> +		}
> +	}
>   		break;
>   	case 32: {
>   		uint32_t sil = silence;

I'm under reviewing this patch, but need a bit more time (I'm writing 
test program to check these functions.).

However, as you noted, this patch includes two issues. There's a space 
to consider about splitting this into two patches, each of which handles 
each issue you addressed.


Regards

Takashi Sakamoto


More information about the Alsa-devel mailing list