[PATCH] ALSA: hda: Refactor calculating SDnFMT according to specification

Harlozinski, Pawel pawel.harlozinski at linux.intel.com
Wed Sep 2 15:29:04 CEST 2020


> Hey!
>
> Thanks for Your input!
>
> I've created that patch because our validation is actually checking if 
> values
> in SDnFMT are matching their expectations, and they've found  it 
> indicates 32 bits in 32 container while playing 24 bits in 32 container.
> This could be fixed without touching checks of maxbps:
>
> 	switch (snd_pcm_format_width(format)) {
> 	case 8:
> 		val |= AC_FMT_BITS_8;
> 		break;
> 	case 16:
> 		val |= AC_FMT_BITS_16;
> 		break;
> 	case 20:
> 		val |= AC_FMT_BITS_20;
> 		break;
> 	case 24:
> 		if (maxbps >= 24)
> 			val |= AC_FMT_BITS_24;
> 		else
> 			val |= AC_FMT_BITS_20;
> 		break;
> 	case 32:
> 		if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE)
> 			val |= AC_FMT_BITS_32;
> 		else if (maxbps >= 24)
> 			val |= AC_FMT_BITS_24;
> 		else
> 			val |= AC_FMT_BITS_20;
> 		break;
> 	default:
> 		return 0;
> 	}
>
>
> I've simplified that because maxbps seems redundant here - thansk for 
> catching Kai!
> Although reason of  usage maxbps is still not clear (at least for me).
>
> On 8/25/2020 10:25 AM, Takashi Iwai wrote:
>
>> On Mon, 24 Aug 2020 14:16:26 +0200,
>> Kai Vehmanen wrote:
>>> Hey,
>>>
>>> On Mon, 24 Aug 2020, Pawel Harlozinski wrote:
>>>
>>>> Set SDnFMT depending on which format was given, as maxbps only describes container size.
>>> hmm, I'm not entirely sure that is correct. Usage may be a bit varied, but
>>> most places in existing code, "maxbps" is treated as number of significant
>>> bits, not the container size. E.g. in hdac_hda.c:
>>>
>>> »       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
>>> »       »       maxbps = dai->driver->playback.sig_bits;
>>> »       else
>>> »       »       maxbps = dai->driver->capture.sig_bits;
>>>
>>> It would seem "maxbps" is a bit superfluous given the same information can
>>> be relayed in "format" as well. But currently it's still used. E.g. if you
>>> look at snd_hdac_query_supported_pcm(), if codec reports 24bit support,
>>> format is always set to SNDRV_PCM_FMTBIT_S32_LE even if only 24bit are valid.
> So, for me looks like place where we can align with actual format, 
> right ?
>>>   So snd_pcm_format_width() will not return the expected significant
>>> bits info, but you have to use "maxbps". So original code seems correct
>>> (or at least you'd need to update both places).
>
>> Hm, we need to check the call pattern, then.  The maxbps passed to
>> this function was supposed to be the value obtained from
>> snd_hdac_query_supported_pcm(), i.e. the codec capability.
> Here I'm also not sure if we should just "cut" format  in 
> snd_hdac_calc_stream_format (eg. 32 to 24) if codec does not support 32?
>
>> But, basically this patch wouldn't change any practical behavior.  In
>> the current code, snd_pcm_format_width() can be never 20 or 24,
>> because the 24 and 24bit supports are also with SNDRV_PCM_FMT_S32_LE.
>> That is, the cases 20 and 24 there are superfluous from the
>> beginning (although the checks of maxbps are still needed
>>
>> Instead, what we could improve is:
>> - Set up the proper msbits hw_constraint to reflect the maxbps value
>> - Choose the right AC_FMT_BITS_* depending on the hw_params msbitsWe may change the query function not to return a single maxbps value
>> but rather storing the raw PCM parameter value (AC_SUPPCM_*), and pass
>> it at re-encoding the format value, too, if we want to make
>>
>> thanks,
>>
>> Takashi


More information about the Alsa-devel mailing list