Search code examples
linuxubuntuaudioalsa

Linux ALSA Driver using channel count 3


Am running my ALSA Driver on Ubuntu 14.04, 64bit, 3.16.0-30-generic Kernel.

Hardware is proprietary hardware, hence cant give much details.

Following is the existing driver implementation:

Driver is provided sample format, sample rate, channel_count as input via module parameter. (Due to requirements need to provide inputs via module parameters)

Initial snd_pcm_hardware structure for playback path.

#define DEFAULT_PERIOD_SIZE (4096)
#define DEFAULT_NO_OF_PERIODS (1024)
static struct snd_pcm_hardware xxx_playback =
{

.info                   = SNDRV_PCM_INFO_MMAP |
                          SNDRV_PCM_INFO_INTERLEAVED |
                          SNDRV_PCM_INFO_MMAP_VALID |
                          SNDRV_PCM_INFO_SYNC_START,
.formats                = SNDRV_PCM_FMTBIT_S16_LE,
.rates                  = (SNDRV_PCM_RATE_8000 | \
                           SNDRV_PCM_RATE_16000 | \
                           SNDRV_PCM_RATE_48000 | \
                           SNDRV_PCM_RATE_96000),
.rate_min               = 8000,
.rate_max               = 96000,
.channels_min           = 1,
.channels_max           = 1,
.buffer_bytes_max       = (DEFAULT_PERIOD_SIZE * DEFAULT_NO_OF_PERIODS),
.period_bytes_min       = DEFAULT_PERIOD_SIZE,
.period_bytes_max       = DEFAULT_PERIOD_SIZE,
.periods_min            = DEFAULT_NO_OF_PERIODS,
.periods_max            = DEFAULT_NO_OF_PERIODS,
};

Similar values for captures side snd_pcm_hardware structure.

Please, note that the following below values are replaced in playback open entry point, based on the current audio test configuration: (user provides audio format, audio rate, ch count via module parameters as inputs to the driver, which are refilled in snd_pcm_hardware structure)

xxx_playback.formats = user_format_input
xxx_playback.rates = xxx_playback.rate_min, xxx_playback.rate_max = user_sample_rate_input
xxx_playback.channels_min = xxx_playback.channels_max = user_channel_input

Similarly values are re-filled for capture snd_pcm_hardware structure in capture open entry point.

Hardware is configured for clocks based on channel_count, format, sample_rate and driver registers successfully with ALSA layer

Found aplay/arecord working fine for channel_count = 1 or 2 or 4

During aplay/arecord, in driver when "runtime->channels" value is checked, it reflects the channel_count configured, which sounds correct to me.

Record data matches with played, since its a loop back test.

But when i use channel_count = 3, Both aplay or arecord reports

"Broken configuration for this PCM: no configurations available"!! for a wave file with channel_count '3'

ex: Playing WAVE './xxx.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Channels 3

ALSA lib pcm_params.c:2162:(snd1_pcm_hw_refine_slave) Slave PCM not usable

aplay: set_params:1204: Broken configuration for this PCM: no configurations available

With Following changes I was able to move ahead a bit:

.........................

Method1:

Driver is provided channel_count '3' as input via module parameter

Modified Driver to fill snd_pcm_hardware structure as payback->channels_min = 2 & playback->channels_min = 3; Similar values for capture path

aplay/arecord reports as 'channel count not available', though the wave file in use has 3 channels

ex: aplay -D hw:CARD=xxx,DEV=0 ./xxx.wav Playing WAVE './xxx.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Channels 3

aplay: set_params:1239: Channels count non available

Tried aplay/arecord with plughw, and aplay/arecord moved ahead

arecord -D plughw:CARD=xxx,DEV=0 -d 3 -f S16_LE -r 48000 -c 3 ./xxx_rec0.wav

aplay -D plughw:CARD=xxx,DEV=0 ./xxx.wav

Recording WAVE './xxx_rec0.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Channels 3

Playing WAVE './xxx.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Channels 3

End of Test

During aplay/arecord, In driver when "runtime->channels" value is checked it returns value 2!!! But played wavefile has ch count 3...

When data in recorded file is checked its all silence

.........................

Method2:

Driver is provided channel_count '3' as input via module parameter

Modified Driver to fill snd_pcm_hardware structure as playback->channels_min = 3 & playback->channels_min = 4; Similar values for capture path

aplay/arecord reports as 'channel count not available', though the wave file in use has 3 channels

Tried aplay/arecord with plughw, and aplay/arecord moved ahead

During aplay/arecord, In driver when "runtime->channels" value is checked it returns value 4!!! But played wavefile has ch count 3...

When data in recorded file is checked its all silence

.........................

So from above observations, the runtime->channels is either 2 or 4, but never 3 channels was used by alsa stack though requested. When used Plughw, alsa is converting data to run under 2 or 4 channel.

Can anyone help why am unable to use channel count 3.

Will provide more information if needed.

Thanks in Advance.


Solution

  • A period (and the entire buffer) must contain an integral number of frames, i.e., you cannot have partial frames.

    With three channels, one frame has six bytes. The fixed period size (4096) is not divisible by six without remainder.