[alsa-devel] [PATCH] Bugfix: Fix resampling when client and slave both use format float

Takashi Iwai tiwai at suse.de
Mon Feb 24 10:17:27 CET 2014


At Fri, 21 Feb 2014 21:01:00 +0100,
Maarten Baert wrote:
> 
> I found a bug in libasound. When both the client and the slave (in my
> case, the JACK plugin) try to use the float format, but the sample rate
> or channel count does not match, libasound *should* insert linear
> conversion plugins to convert from float to linear, then resample/remap
> channels, and then convert back to float (because apparently the
> resamplers and channel remapper don't support floating point, only
> 'linear' i.e. integers). Currently this doesn't work,
> snd_pcm_plug_change_format doesn't know what to do and simply returns
> EINVAL. As a result, snd_pcm_hw_params fails even though the HW params
> were perfectly valid (it indicates that both the float format and any
> sample rate are supported).
> 
> In my test, this broke audio for WINE (and any other application that
> tries to use float, such as aplay with the right settings) when I wanted
> to use the JACK plugin (which only supports the float format).
> 
> This patch fixes this bug by doing a conversion to S16 and back when
> resampling or remapping is needed. And while I was at it, I also removed
> a check that had no effect because the exact same check is already being
> done at the start of the function.
> 
> I still think it's a bit silly that libasound requires integers for
> resampling, because both libsamplerate and libspeex use float internally
> for resampling. So now ALSA is literally doing a
> float-to-s16-to-float-to-s16-to-float conversion. But changing that
> would have been a lot harder.

Can S32 work instead of S16?  Then we won't lose the accuracy so much.
Of course, handling float directly would be the best option.

In anyway, could you give your acked-by tag?

Thanks!


Takashi

> 
> Maarten Baert
> diff --git a/src/pcm/pcm_plug.c b/src/pcm/pcm_plug.c
> index fa84eaa..ede9c15 100644
> --- a/src/pcm/pcm_plug.c
> +++ b/src/pcm/pcm_plug.c
> @@ -522,15 +522,13 @@ static int snd_pcm_plug_change_format(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm_p
>  		}
>  #ifdef BUILD_PCM_PLUGIN_LFLOAT
>  	} else if (snd_pcm_format_float(slv->format)) {
> -		/* Conversion is done in another plugin */
> -		if (clt->format == slv->format &&
> -		    clt->rate == slv->rate &&
> -		    clt->channels == slv->channels)
> -			return 0;
> -		cfmt = clt->format;
> -		if (snd_pcm_format_linear(clt->format))
> +		if (snd_pcm_format_linear(clt->format)) {
> +			cfmt = clt->format;
>  			f = snd_pcm_lfloat_open;
> -		else
> +		} else if (clt->rate != slv->rate || clt->channels != slv->channels) {
> +			cfmt = SND_PCM_FORMAT_S16;
> +			f = snd_pcm_lfloat_open;
> +		} else
>  			return -EINVAL;
>  #endif
>  #ifdef BUILD_PCM_NONLINEAR
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel at alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel


More information about the Alsa-devel mailing list