This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How to config McASP/ALSA to convert audio sample size from 32-bit to 16-bit

Other Parts Discussed in Thread: PCM3168A, PCM3168

Hi all,

I have am335x processor connected to a PCM Codec (sound card: TI PCM3168a) through McASPs.

The PCM Codec is config to run at 16kHz, 24bit/data sample (padded to 32bits, so each sample is clocked as 32bits with a depth of 24bits).

Since the data format from the sound card (PCM Codec) is 32bits/sample, this "big" size per sample of  Audio data are captured by McASP and transfer to the kernel, then transfer to user space through ALSA interface.

 I am trying to find a way to config McASP and/or ALSA to convert this sample size to 16 bits before passing them to user space.

Is this something someone at TI can help me with?

here is how i have defined the soc_dai_driver for this sound card kernel driver i have created under the kernel tree /sound/soc/codecs/ pcm3168.c

static struct snd_soc_dai_driver pcm3168_dai = {
.name = DRV_NAME,
.playback = {
.stream_name = "Playback",
.channels_min = 8,
.channels_max = 8,
.rates = 16000,
.formats = SNDRV_PCM_FMTBIT_S32_LE,
},
.capture = {
.stream_name = "Capture",
.channels_min = 8,
.channels_max = 8,
.rates = 16000,
.formats = SNDRV_PCM_FMTBIT_S32_LE,

},

};

  • I will ask the software team to comment if this is possible.
  • Hi,

    Have you tried changing the format to:
    .formats = SNDRV_PCM_FMTBIT_S16_LE => 16 bit little endian

    Or using aplay -F S16_LE => 16 bit little endian ? What is the result?


    Best Regards,
    Yordan
  • Yes, I have tried

    .formats = SNDRV_PCM_FMTBIT_S16_LE

    without success. with this change, I do not get any audio sound out of the audio sound card even though by reading McASP wFIFO many times, I do see its value changing.

    If I dump the audio data from the sound card with arecord for example, it is all zero!! (arecord --device=sysdefault:CARD=PCM3168a --channel=8 --rate=16000 --format=16LE record.wav

    So definitively, there is more change required to be able to config McASP to get 16bits for each channel from a sound card that is sending 32bits/sample.

    Any more thoughts?

  • Hi,

    You may also need to hardcode the slot width in your codec driver, i.e. you should have something like the bellow code in <codec>_hw_params():
    switch (snd_pcm_format_width(params_format(params))) {
    case 16:
    alen = PCM512x_ALEN_16;
    break;
    case 20:
    alen = PCM512x_ALEN_20;
    break;
    case 24:
    alen = PCM512x_ALEN_24;
    break;
    case 32:
    alen = PCM512x_ALEN_32;
    break;
    default:
    dev_err(codec->dev, "Bad frame size: %d\n",
    snd_pcm_format_width(params_format(params)));
    return -EINVAL;
    }

    And then set the slot width in pcm3168 registers:
    ret = regmap_update_bits(pcm512x->regmap, PCM512x_I2S_1,
    PCM512x_ALEN, alen);


    So track the how the format is passed throughout the sound arch and hardcode the slot width.

    Also check in the alsa configuration in the filesystem; modify /etc/asound.conf with something like:
    pcm.device{
    format S16_LE
    rate 96000
    type hw
    card 0
    device 0
    }

    Best Regards,
    Yordan