ccodecalsalibalsa

Alsa Lib Hardware Parameters setting


I'm trying to record sound on my linux (debian) embedded device with alsa library. My embedded hardware is this [1], and according to its datasheet page 33 [2],

Analog audio signals are featured by the on-SOM TLV320AIC3106 audio codec.

and the datasheet of this Texas Instruments audio codec [3],

Supports Rates From 8 kHz to 96 kHz

I use the example application code for alsa lib, for initial work I didn't change the code. In the example code, the sampling rate was set to 44100Hz. I successfully recorded sound and played after. For now, I think, I can record sound with alsa-lib with the sampling rate of 8000Hz based on the datasheets. I set the sampling rate to 8000Hz but while the alsa configuration, it changes to 16000Hz. I set sampling rate to 8000Hz;

snd_pcm_hw_params_set_rate_near(handle, params, &(record_params->rate), &dir);
snd_pcm_hw_params_set_channels(handle, params, record_params->channel);
rc = snd_pcm_hw_params(handle, params);

But after invoking this method;

snd_pcm_hw_params_get_period_time(params, &(record_params->rate), &dir);

it changes to 16000. There is no other method call between above. Are my settings wrong or may be the codec doesn't support for 8kHz?

UPDATE: When I set rate to 16000, it changes to 8000. I'm really confused more.

[1] = http://www.variscite.com/products/system-on-module-som/cortex-a9/dart-mx6-cpu-freescale-imx6

[2] = http://www.variscite.com/images/stories/DataSheets/DART-MX6/DART-MX6_v1_2_datasheet_v2_1.pdf

[3] = http://www.ti.com/lit/ds/symlink/tlv320aic3106.pdf


Solution

  • Period time and rate are two different things.

    The period of a PCM is basically the amount of frames that get transferred between device interrupts. It's done this way because making data transfers to a device frame by frame would be extremely inefficient.

    The ALSA library allows the setting of the period size to be specified by microseconds (using snd_pcm_get_period_time) or by frame count (using snd_pcm_get_period_size).

    If you're trying to calculate what size buffer to allocate for reading or writing to a PCM, it would be more intuitive to use snd_pcm_get_period_size (which returns the number of frames in a period) and then call snd_pcm_frames_to_bytes, which converts a frame count of a PCM to a byte count.