Skip to content

Commit

Permalink
pcm: clarify and fix default sbits (msbits) value for all formats
Browse files Browse the repository at this point in the history
As described in the kernel patch (link bellow), the significant (resolution)
bits should be related to the usable sample bits not the physical sample bits.

Link: https://lore.kernel.org/linux-sound/20240222173649.1447549-1-perex@perex.cz/
Link: larsimmisch/pyalsaaudio#146
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
  • Loading branch information
perexg committed Feb 23, 2024
1 parent 431f69a commit 13057b7
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 4 deletions.
7 changes: 6 additions & 1 deletion src/pcm/pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,8 @@ range, thus you may get the significant bits for linear samples via
#snd_pcm_hw_params_get_sbits() function. The example: ICE1712
chips support 32-bit sample processing, but low byte is ignored (playback)
or zero (capture). The function snd_pcm_hw_params_get_sbits()
returns 24 in this case.
returns 24 in this case. The significant bits are related to the usable
sample bits (width) not the physical sample space.
\section alsa_transfers ALSA transfers
Expand Down Expand Up @@ -3905,6 +3906,10 @@ int snd_pcm_hw_params_get_rate_numden(const snd_pcm_hw_params_t *params,
* \param params Configuration space
* \return signification bits in sample otherwise a negative error code if the info is not available
*
* Significant bits are related to usable sample bits (width) not the
* physical sample bits (width). For non-linear formats, this value may have
* a special meaning which may be defined in future.
*
* This function should only be called when the configuration space
* contains a single configuration. Call #snd_pcm_hw_params to choose
* a single configuration from the configuration space.
Expand Down
22 changes: 19 additions & 3 deletions src/pcm/pcm_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,12 +379,28 @@ static int snd_pcm_hw_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
return 0;
}

static inline int hw_params_call(snd_pcm_hw_t *pcm_hw, snd_pcm_hw_params_t *params)
#define hw_param_mask(params,var) \
&((params)->masks[(var) - SND_PCM_HW_PARAM_FIRST_MASK])

static int hw_params_call(snd_pcm_hw_t *pcm_hw, snd_pcm_hw_params_t *params)
{
int err;

/* check for new hw_params structure; it's available from 2.0.2 version of PCM API */
if (SNDRV_PROTOCOL_VERSION(2, 0, 2) <= pcm_hw->version)
return ioctl(pcm_hw->fd, SNDRV_PCM_IOCTL_HW_PARAMS, params);
return use_old_hw_params_ioctl(pcm_hw->fd, SND_PCM_IOCTL_HW_PARAMS_OLD, params);
err = ioctl(pcm_hw->fd, SNDRV_PCM_IOCTL_HW_PARAMS, params);
else
err = use_old_hw_params_ioctl(pcm_hw->fd, SND_PCM_IOCTL_HW_PARAMS_OLD, params);
if (err >= 0 && pcm_hw->version < SNDRV_PROTOCOL_VERSION(2, 0, 17) && params->msbits > 0) {
snd_mask_t *m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
if (snd_mask_single(m)) {
snd_pcm_format_t format = snd_mask_min(m);
int width = snd_pcm_format_width(format);
if (width > 0 && params->msbits > (unsigned int)width)
params->msbits = width;
}
}
return err;
}

static int snd_pcm_hw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
Expand Down
6 changes: 6 additions & 0 deletions src/pcm/pcm_params.c
Original file line number Diff line number Diff line change
Expand Up @@ -2075,6 +2075,7 @@ int snd_pcm_hw_refine_soft(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t
{
unsigned int k;
snd_interval_t *i;
snd_mask_t *m;
unsigned int rstamps[RULES];
unsigned int vstamps[SND_PCM_HW_PARAM_LAST_INTERVAL + 1];
unsigned int stamp = 2;
Expand Down Expand Up @@ -2159,6 +2160,11 @@ int snd_pcm_hw_refine_soft(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t
i = hw_param_interval(params, SND_PCM_HW_PARAM_SAMPLE_BITS);
if (snd_interval_single(i))
params->msbits = snd_interval_value(i);
m = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT);
if (snd_mask_single(m)) {
snd_pcm_format_t format = snd_mask_min(m);
params->msbits = snd_pcm_format_width(format);
}
}

if (!params->rate_den) {
Expand Down

0 comments on commit 13057b7

Please sign in to comment.