#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
* \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.
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)
{
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;
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) {