int snd_pcm_hw_params_malloc(snd_pcm_hw_params_t **ptr);
void snd_pcm_hw_params_free(snd_pcm_hw_params_t *obj);
void snd_pcm_hw_params_copy(snd_pcm_hw_params_t *dst, const snd_pcm_hw_params_t *src);
-int snd_pcm_hw_params_get_access(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_get_access(const snd_pcm_hw_params_t *params, snd_pcm_access_t *val);
int snd_pcm_hw_params_test_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t val);
int snd_pcm_hw_params_set_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t val);
snd_pcm_access_t snd_pcm_hw_params_set_access_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
snd_pcm_access_t snd_pcm_hw_params_set_access_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
int snd_pcm_hw_params_set_access_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask);
void snd_pcm_hw_params_get_access_mask(snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask);
-int snd_pcm_hw_params_get_format(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_get_format(const snd_pcm_hw_params_t *params, snd_pcm_format_t *val);
int snd_pcm_hw_params_test_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val);
int snd_pcm_hw_params_set_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val);
snd_pcm_format_t snd_pcm_hw_params_set_format_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
int snd_pcm_hw_params_set_format_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask);
void snd_pcm_hw_params_get_format_mask(snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask);
int snd_pcm_hw_params_test_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t val);
-int snd_pcm_hw_params_get_subformat(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_get_subformat(const snd_pcm_hw_params_t *params, snd_pcm_subformat_t *val);
int snd_pcm_hw_params_set_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t val);
snd_pcm_subformat_t snd_pcm_hw_params_set_subformat_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
snd_pcm_subformat_t snd_pcm_hw_params_set_subformat_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
unsigned int snd_pcm_hw_params_set_tick_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir);
unsigned int snd_pcm_hw_params_set_tick_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir);
unsigned int snd_pcm_hw_params_set_tick_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir);
+snd_pcm_sframes_t snd_pcm_hw_params_get_min_align(const snd_pcm_hw_params_t *params);
/** \} */
/**
* \brief Extract access type from a configuration space
* \param params Configuration space
+ * \param val Returned value
* \return access type otherwise a negative error code if not exactly one is present
*/
-int snd_pcm_hw_params_get_access(const snd_pcm_hw_params_t *params)
+int snd_pcm_hw_params_get_access(const snd_pcm_hw_params_t *params, snd_pcm_access_t *val)
{
- return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_ACCESS, NULL);
+ int err;
+
+ assert(val);
+ err = snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_ACCESS, NULL);
+ if (err < 0)
+ return err;
+ *val = err;
+ return 0;
}
/**
/**
* \brief Extract format from a configuration space
* \param params Configuration space
+ * \param val returned format
* \return format otherwise a negative error code if not exactly one is present
*/
-int snd_pcm_hw_params_get_format(const snd_pcm_hw_params_t *params)
+int snd_pcm_hw_params_get_format(const snd_pcm_hw_params_t *params, snd_pcm_format_t *val)
{
- return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_FORMAT, NULL);
+ int err;
+
+ assert(val);
+ err = snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_FORMAT, NULL);
+ if (err < 0)
+ return err;
+ *val = err;
+ return 0;
}
/**
/**
* \brief Extract subformat from a configuration space
* \param params Configuration space
+ * \param val Returned subformat
* \return subformat otherwise a negative error code if not exactly one is present
*/
-int snd_pcm_hw_params_get_subformat(const snd_pcm_hw_params_t *params)
+int snd_pcm_hw_params_get_subformat(const snd_pcm_hw_params_t *params, snd_pcm_subformat_t *val)
{
- return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_SUBFORMAT, NULL);
+ int err;
+
+ assert(val);
+ err = snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_SUBFORMAT, NULL);
+ if (err < 0)
+ return err;
+ *val = (snd_pcm_subformat_t)err;
+ return 0;
}
/**
return res;
}
+/**
+ * \brief Get the minimum transfer align value in samples
+ * \param params Configuration space
+ * \return minimum align value otherwise a negative error code if not exactly one is present
+ */
+snd_pcm_sframes_t snd_pcm_hw_params_get_min_align(const snd_pcm_hw_params_t *params)
+{
+ int format, channels, fb, min_align;
+
+ format = snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_FORMAT, NULL);
+ if (format < 0)
+ return format;
+ channels = snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_CHANNELS, NULL);
+ if (channels < 0)
+ return channels;
+ // compute frame bits
+ fb = snd_pcm_format_physical_width(format) * channels;
+ min_align = 1;
+ while (fb % 8) {
+ fb *= 2;
+ min_align *= 2;
+ }
+ return min_align;
+}
+
/**
* \brief Return current software configuration for a PCM
* \param pcm PCM handle
static int snd_pcm_adpcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
{
snd_pcm_adpcm_t *adpcm = pcm->private_data;
+ snd_pcm_format_t format;
int err = snd_pcm_hw_params_slave(pcm, params,
snd_pcm_adpcm_hw_refine_cchange,
snd_pcm_adpcm_hw_refine_sprepare,
if (err < 0)
return err;
+ err = snd_pcm_hw_params_get_format(params, &format);
+ if (err < 0)
+ return err;
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
if (adpcm->sformat == SND_PCM_FORMAT_IMA_ADPCM) {
- adpcm->getput_idx = snd_pcm_linear_get_index(snd_pcm_hw_params_get_format(params), SND_PCM_FORMAT_S16);
+ adpcm->getput_idx = snd_pcm_linear_get_index(format, SND_PCM_FORMAT_S16);
adpcm->func = snd_pcm_adpcm_encode;
} else {
adpcm->getput_idx = snd_pcm_linear_put_index(SND_PCM_FORMAT_S16, adpcm->sformat);
}
} else {
if (adpcm->sformat == SND_PCM_FORMAT_IMA_ADPCM) {
- adpcm->getput_idx = snd_pcm_linear_put_index(SND_PCM_FORMAT_S16, snd_pcm_hw_params_get_format(params));
+ adpcm->getput_idx = snd_pcm_linear_put_index(SND_PCM_FORMAT_S16, format);
adpcm->func = snd_pcm_adpcm_decode;
} else {
adpcm->getput_idx = snd_pcm_linear_get_index(adpcm->sformat, SND_PCM_FORMAT_S16);
static int snd_pcm_alaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
{
snd_pcm_alaw_t *alaw = pcm->private_data;
+ snd_pcm_format_t format;
int err = snd_pcm_hw_params_slave(pcm, params,
snd_pcm_alaw_hw_refine_cchange,
snd_pcm_alaw_hw_refine_sprepare,
if (err < 0)
return err;
+ err = snd_pcm_hw_params_get_format(params, &format);
+ if (err < 0)
+ return err;
+
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
if (alaw->sformat == SND_PCM_FORMAT_A_LAW) {
- alaw->getput_idx = snd_pcm_linear_get_index(snd_pcm_hw_params_get_format(params), SND_PCM_FORMAT_S16);
+ alaw->getput_idx = snd_pcm_linear_get_index(format, SND_PCM_FORMAT_S16);
alaw->func = snd_pcm_alaw_encode;
} else {
alaw->getput_idx = snd_pcm_linear_put_index(SND_PCM_FORMAT_S16, alaw->sformat);
}
} else {
if (alaw->sformat == SND_PCM_FORMAT_A_LAW) {
- alaw->getput_idx = snd_pcm_linear_put_index(SND_PCM_FORMAT_S16, snd_pcm_hw_params_get_format(params));
+ alaw->getput_idx = snd_pcm_linear_put_index(SND_PCM_FORMAT_S16, format);
alaw->func = snd_pcm_alaw_decode;
} else {
alaw->getput_idx = snd_pcm_linear_get_index(alaw->sformat, SND_PCM_FORMAT_S16);
if (hw->mmap_emulation) {
snd_pcm_hw_params_t old = *params;
if (hw_params_call(hw, params) < 0) {
+ snd_pcm_access_t access;
snd_pcm_access_mask_t oldmask;
const snd_mask_t *pmask;
*params = old;
pmask = snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_ACCESS);
oldmask = *(snd_pcm_access_mask_t *)pmask;
- switch (snd_pcm_hw_params_get_access(params)) {
+ if (snd_pcm_hw_params_get_access(params, &access) < 0)
+ goto _err;
+ switch (access) {
case SND_PCM_ACCESS_MMAP_INTERLEAVED:
snd_pcm_access_mask_reset((snd_pcm_access_mask_t *)pmask, SND_PCM_ACCESS_MMAP_INTERLEAVED);
snd_pcm_access_mask_set((snd_pcm_access_mask_t *)pmask, SND_PCM_ACCESS_RW_INTERLEAVED);
if (err < 0)
return err;
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
- src_format = snd_pcm_hw_params_get_format(params);
+ err = snd_pcm_hw_params_get_format(params, &src_format);
dst_format = slave->format;
} else {
src_format = slave->format;
- dst_format = snd_pcm_hw_params_get_format(params);
+ err = snd_pcm_hw_params_get_format(params, &dst_format);
}
if (snd_pcm_format_linear(src_format)) {
lfloat->int32_idx = snd_pcm_linear_get32_index(src_format, SND_PCM_FORMAT_S32);
static int snd_pcm_linear_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
{
snd_pcm_linear_t *linear = pcm->private_data;
+ snd_pcm_format_t format;
int err = snd_pcm_hw_params_slave(pcm, params,
snd_pcm_linear_hw_refine_cchange,
snd_pcm_linear_hw_refine_sprepare,
snd_pcm_plugin_hw_params_slave);
if (err < 0)
return err;
- linear->use_getput = (snd_pcm_format_physical_width(snd_pcm_hw_params_get_format(params)) == 24 ||
+ err = snd_pcm_hw_params_get_format(params, &format);
+ if (err < 0)
+ return err;
+ linear->use_getput = (snd_pcm_format_physical_width(format) == 24 ||
snd_pcm_format_physical_width(linear->sformat) == 24);
if (linear->use_getput) {
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
- linear->get_idx = snd_pcm_linear_get32_index(snd_pcm_hw_params_get_format(params), SND_PCM_FORMAT_S32);
+ linear->get_idx = snd_pcm_linear_get32_index(format, SND_PCM_FORMAT_S32);
linear->put_idx = snd_pcm_linear_put32_index(SND_PCM_FORMAT_S32, linear->sformat);
} else {
linear->get_idx = snd_pcm_linear_get32_index(linear->sformat, SND_PCM_FORMAT_S32);
- linear->put_idx = snd_pcm_linear_put32_index(SND_PCM_FORMAT_S32, snd_pcm_hw_params_get_format(params));
+ linear->put_idx = snd_pcm_linear_put32_index(SND_PCM_FORMAT_S32, format);
}
} else {
if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
- linear->conv_idx = snd_pcm_linear_convert_index(snd_pcm_hw_params_get_format(params),
+ linear->conv_idx = snd_pcm_linear_convert_index(format,
linear->sformat);
else
linear->conv_idx = snd_pcm_linear_convert_index(linear->sformat,
- snd_pcm_hw_params_get_format(params));
+ format);
}
return 0;
}
static int snd_pcm_mulaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
{
snd_pcm_mulaw_t *mulaw = pcm->private_data;
+ snd_pcm_format_t format;
int err = snd_pcm_hw_params_slave(pcm, params,
snd_pcm_mulaw_hw_refine_cchange,
snd_pcm_mulaw_hw_refine_sprepare,
if (err < 0)
return err;
+ err = snd_pcm_hw_params_get_format(params, &format);
+ if (err < 0)
+ return err;
+
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
if (mulaw->sformat == SND_PCM_FORMAT_MU_LAW) {
- mulaw->getput_idx = snd_pcm_linear_get_index(snd_pcm_hw_params_get_format(params), SND_PCM_FORMAT_S16);
+ mulaw->getput_idx = snd_pcm_linear_get_index(format, SND_PCM_FORMAT_S16);
mulaw->func = snd_pcm_mulaw_encode;
} else {
mulaw->getput_idx = snd_pcm_linear_put_index(SND_PCM_FORMAT_S16, mulaw->sformat);
}
} else {
if (mulaw->sformat == SND_PCM_FORMAT_MU_LAW) {
- mulaw->getput_idx = snd_pcm_linear_put_index(SND_PCM_FORMAT_S16, snd_pcm_hw_params_get_format(params));
+ mulaw->getput_idx = snd_pcm_linear_put_index(SND_PCM_FORMAT_S16, format);
mulaw->func = snd_pcm_mulaw_decode;
} else {
mulaw->getput_idx = snd_pcm_linear_get_index(mulaw->sformat, SND_PCM_FORMAT_S16);
return err;
pcm->setup = 1;
- pcm->access = snd_pcm_hw_params_get_access(params);
- pcm->format = snd_pcm_hw_params_get_format(params);
- pcm->subformat = snd_pcm_hw_params_get_subformat(params);
+ snd_pcm_hw_params_get_access(params, &pcm->access);
+ snd_pcm_hw_params_get_format(params, &pcm->format);
+ snd_pcm_hw_params_get_subformat(params, &pcm->subformat);
pcm->channels = snd_pcm_hw_params_get_channels(params);
pcm->rate = snd_pcm_hw_params_get_rate(params, 0);
pcm->period_time = snd_pcm_hw_params_get_period_time(params, 0);
err = snd_pcm_hw_refine_soft(slave, &sparams);
assert(err >= 0);
- clt_params.access = snd_pcm_hw_params_get_access(params);
- clt_params.format = snd_pcm_hw_params_get_format(params);
+ snd_pcm_hw_params_get_access(params, &clt_params.access);
+ snd_pcm_hw_params_get_format(params, &clt_params.format);
clt_params.channels = snd_pcm_hw_params_get_channels(params);
clt_params.rate = snd_pcm_hw_params_get_rate(params, 0);
- slv_params.format = snd_pcm_hw_params_get_format(&sparams);
+ snd_pcm_hw_params_get_format(&sparams, &slv_params.format);
slv_params.channels = snd_pcm_hw_params_get_channels(&sparams);
slv_params.rate = snd_pcm_hw_params_get_rate(&sparams, 0);
snd_pcm_plug_clear(pcm);
return err;
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
- src_format = snd_pcm_hw_params_get_format(params);
+ err = snd_pcm_hw_params_get_format(params, &src_format);
dst_format = slave->format;
src_rate = snd_pcm_hw_params_get_rate(params, 0);
dst_rate = slave->rate;
} else {
src_format = slave->format;
- dst_format = snd_pcm_hw_params_get_format(params);
+ err = snd_pcm_hw_params_get_format(params, &dst_format);
src_rate = slave->rate;
dst_rate = snd_pcm_hw_params_get_rate(params, 0);
}
+ if (err < 0)
+ return err;
rate->get_idx = snd_pcm_linear_get_index(src_format, SND_PCM_FORMAT_S16);
rate->put_idx = snd_pcm_linear_put_index(SND_PCM_FORMAT_S16, dst_format);
if (src_rate < dst_rate) {
return err;
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
- src_format = snd_pcm_hw_params_get_format(params);
+ err = snd_pcm_hw_params_get_format(params, &src_format);
dst_format = slave->format;
} else {
src_format = slave->format;
- dst_format = snd_pcm_hw_params_get_format(params);
+ err = snd_pcm_hw_params_get_format(params, &dst_format);
}
+ if (err < 0)
+ return err;
route->params.use_getput = snd_pcm_format_physical_width(src_format) == 24 ||
snd_pcm_format_physical_width(dst_format) == 24;
route->params.get_idx = snd_pcm_linear_get_index(src_format, SND_PCM_FORMAT_S16);