[alsa-devel] ALSA hw sample rate conversion support
Liam Girdwood
lrg at slimlogic.co.uk
Wed Mar 30 21:09:53 CEST 2011
On Wed, 2011-03-30 at 21:02 +0530, Koul, Vinod wrote:
> Aisheng Dong wrote:
> > Hi ALL,
> >
> > Does ALSA core support hw sample rate conversion now?
> > Our soc has a HW sample rate converter module inside,
> > I wonder if current ALSA core provide interface to support hw sample
> > rate conversion?
> >
> Assuming the SRC is inside SoC and you are converting sampling rate of stream
> and sending at different rate, then I have a patch for you.
> Basically the soc side hw_params should call a new API which call
> codec_set_params() and sets the matching rate.
>
> Something like this in soc-core
>
> +int snd_soc_codec_set_params(struct snd_soc_codec *codec, unsigned int param)
> +{
> + if (codec->driver->set_params)
> + return codec->driver->set_params(codec, param);
> + else
> + return -EINVAL;
> +}
> +EXPORT_SYMBOL_GPL(snd_soc_codec_set_params);
>
> Mark,
> Would you okay with such a patch where DSP is doing some conversion and codec
> will get different params from what stream is set up? And we make sure
> conversion is synced
Fwiw, I've already implemented a hw_params() fixup between the DSP and
CODEC drivers. This is in my dsp branch atm here :-
http://git.kernel.org/?p=linux/kernel/git/lrg/asoc-2.6.git;a=shortlog;h=refs/heads/topic/dsp-upstream
This allows us to rewrite channels, rates, formats etc. depending on the
use case and can be part of the machine driver e.g. (from sdp4430.c)
static int mcbsp_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
struct snd_interval *channels = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
unsigned int be_id = rtd->dai_link->be_id;
if (be_id == OMAP_ABE_DAI_MM_FM)
channels->min = 2;
else if (be_id == OMAP_ABE_DAI_BT_VX)
channels->min = 1;
snd_mask_set(¶ms->masks[SNDRV_PCM_HW_PARAM_FORMAT -
SNDRV_PCM_HW_PARAM_FIRST_MASK],
SNDRV_PCM_FORMAT_S16_LE);
return 0;
}
static int dmic_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
struct snd_interval *rate = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_RATE);
/* The ABE will covert the FE rate to 96k */
rate->min = rate->max = 96000;
snd_mask_set(¶ms->masks[SNDRV_PCM_HW_PARAM_FORMAT -
SNDRV_PCM_HW_PARAM_FIRST_MASK],
SNDRV_PCM_FORMAT_S32_LE);
return 0;
}
I intend to start upstreaming all this stuff when I return from holiday
on the 11th April (in time for 2.6.40).
Liam
More information about the Alsa-devel
mailing list