[alsa-devel] Question about hw_param with Ctrl-Z + fg

Kuninori Morimoto kuninori.morimoto.gx at renesas.com
Tue Apr 4 10:02:57 CEST 2017


Hi Sakamoto-san, Mark

> > Hmm...
> > Above .be_hw_params_fixup is used to convert sampling rate or channel
> > number or some other related things between SoC / Codec as DPCM feature.
> > Thus, I can't switch to .be_hw_params_fixup to .prepare I guess.
> > But Mark, am I misunderstanding ?
> 
> In 'struct snd_pcm_ops.prepare' callback, configured parameters of PCM
> substream are available via members of 'struct snd_pcm_runtime'. The
> runtime is a member of 'struct snd_pcm_substream'. It's available in
> any of .prepare callbacks in ALSA SoC part.

Thank you for detail explain.
I investigated this, and I tried to use .prepare with below system.

	[44.1kHz] -> CPU -> .be_hw_params_fixup[44.1kHz -> 48kHz] -> Codec

This means, CPU converts 44.1kHz to 48kHz, and
Codec want to receive 48kHz as parameter.
On CPU/Codec both side, these got 44.1kHz from runtime.

static int cpu/codec_prepare(struct snd_pcm_substream *substream)
{
	/*
	 * In 44.1kHz -> 48kHz convert case,
	 * .be_hw_params_fixup() do convert magic.
	 * but here .prepare, it still receive 44.1kHz
	 */
	printk("rate = %d\n", substream->runtime->rate);
}

On CPU side, I could get converted parameter somehow (see below),
but it has zero chance to get converted parameter on Codec side .prepare ?
Converted rate is located only struct snd_pcm_hw_params in my system (= simple-scu-card).
Current .be_hw_params_fixup() is saving converted rate/channel in struct snd_interval,
but it should save it to struct snd_soc_pcm_runtime ?

void asoc_simple_card_convert_fixup(...
				    struct snd_pcm_hw_params *hw_params)
{
	struct snd_interval *rate = hw_param_interval(hw_params,
						SNDRV_PCM_HW_PARAM_RATE);
	struct snd_interval *channels = hw_param_interval(hw_params,
						SNDRV_PCM_HW_PARAM_CHANNELS);
	printk("------fixup\n");
	if (data->convert_rate)
		rate->min =
		rate->max = data->convert_rate;

	if (data->convert_channels)
		channels->min =
		channels->max = data->convert_channels;
}


---- CPU could get converted rate --------------------------
static int cpu_prepare(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *fe = substream->private_data;

	/* substream->runtime->rate is still 44.1kHz here */

	if (fe->dai_link->dynamic) {
		int stream = substream->stream;
		struct snd_soc_dpcm *dpcm;
		struct snd_pcm_hw_params *be_params;

		list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
			be_params = &dpcm->hw_params;

			/*
			 * I could receive 48kHz here as params_rate(be_params)
			 */
		}
	}

	return 0;
}


Best regards
---
Kuninori Morimoto


More information about the Alsa-devel mailing list