Reputation: 134
I am trying to playback 24bit wav file with 3-bytes sample allignment using ALSA (libasound.so.2
). And ALSA fails on setting buffer size with Invalid argument
error (and ALSA do not pass anything to drivers)
Here is wav
file header content:
chunkId: 46464952
chunkSize: 221417340
format: "WAVE"
subchunk1Id: "fmt "
subchunk1Size: 40
audioFormat: fffe
numChannels: 2
sampleRate: 88200
byteRate: 529200
blockAlign: 6
bitsPerSample: 24
cbSize 16
wValidBitsPerSample 18
dwChannelMask 0
SubFormat
subchunk2Id: "data"
subchunk2Size: 221417280
Unfortunately cannot provide proper test program source as it is part of cross-platform program and wount build separately. The shorten example might looks like
#include <stdio.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <semaphore.h>
#include "asoundlib.h"
int main(int argc, char *argv[])
{
int err = -1; /**< ALSA & clib function return code */
snd_pcm_t *p_handle = NULL; /**< pointer to active pcm object */
static const char *const p_device = "default"; /**< const pointer to const device id string */
unsigned int sampleRate = 0;
unsigned int rbuffertime = 0; /**< real buffer time as granted by ALSA */
err = snd_pcm_open(&p_handle, p_device, SND_PCM_STREAM_PLAYBACK, 0);
if (0 > err)
{
printf("Playback open error: %s\n", snd_strerror(err));
return err;
}
/* Get full range of possible hw params */
err = snd_pcm_hw_params_any(p_handle, p_hwparams);
if (0 > err)
{
printf("Error fetching hw param ranges: %s\n", snd_strerror(err));
return err;
}
// Specify a specific config out of configuration space and set it
err = snd_pcm_hw_params_set_rate_resample(p_handle, p_hwparams, 1);
if (0 > err)
{
printf("Unable to snd_pcm_hw_params_set_rate_resample for playback: %s\n", snd_strerror(err));
return err;
}
err = snd_pcm_hw_params_set_access(p_handle, p_hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
if (0 > err)
{
printf("Unable to snd_pcm_hw_params_set_access for playback: %s\n", snd_strerror(err));
return err;
}
err = snd_pcm_hw_params_set_format(p_handle, p_hwparams, SND_PCM_FORMAT_S24_3LE);
if (0 > err)
{
printf("Unable to snd_pcm_hw_params_set_format for playback: %s\n", snd_strerror(err));
return err;
}
err = snd_pcm_hw_params_set_channels(p_handle, p_hwparams, 2);
if (0 > err)
{
printf("Unable to snd_pcm_hw_params_set_channels for playback: %s\n", snd_strerror(err));
return err;
}
sampleRate = 88200;
err = snd_pcm_hw_params_set_rate_near(p_handle, p_hwparams, &sampleRate, 0);
if (0 > err)
{
printf("Unable to snd_pcm_hw_params_set_rate for playback: %s\n", snd_strerror(err));
return err;
}
rbuffertime = 500000;
err = snd_pcm_hw_params_set_buffer_time_near(p_handle, p_hwparams, &rbuffertime, 0);
if (0 > err)
{
printf("Unable to snd_pcm_hw_params_set_buffer_time_near for playback: %s\n", snd_strerror(err));
}
return err;
}
ALSA fails on snd_pcm_hw_params_set_buffer_time_near()
call with error
ALSA ERROR hw_params: set_near (BUFFER_TIME)
value = 500000 : Invalid argument
ACCESS: RW_INTERLEAVED
FORMAT: S24_3LE
SUBFORMAT: STD
SAMPLE_BITS: 24
FRAME_BITS: 48
CHANNELS: 2
RATE: 88200
PERIOD_TIME: (476 247688)
PERIOD_SIZE: (42 21846)
PERIOD_BYTES: [256 131072]
PERIODS: [2 1024]
BUFFER_TIME: (495351 495352)
BUFFER_SIZE: 43690
BUFFER_BYTES: [262144 262140]
TICK_TIME: ALL
(ALSA even not attempts to pass any data to drivers, just fails on set buffer) That program works well for 16 bit audio.
I have tried different values of buffer (0.001 .. 1 second) however none of them works. Suppose I have missed any part of ALSA config required for 24 bit with 3LE, of maybe some check of previous init steps results?
Unfortunately I cannot find any example of ALSA usage for 24 bits, I would appreciate if You advice any link to example/recommendation/documentation.
EDITED
The result of aplay
for this file is:
aplay -v /export/target/24bit_88.2kHz.wav
Playing WAVE '/export/target/24bit_88.2kHz.wav' : Signed 24 bit Little Endian in 3bytes, Rate 88200 Hz, Stereo
aplay: set_params:979: Sample format non available
Upvotes: 0
Views: 1142