[alsa-devel] Buffer size/periods (Layla3G)
Mark Hills
mark at pogo.org.uk
Sun Mar 16 13:02:58 CET 2008
Hello,
I am investigating problems I'm having with recording over long periods.
I'm using a Layla3G and tested various ALSA versions including 1.0.14 and
1.0.16 on different machines.
I've noticed that when I open the first pair of subdevices, my request for
1000ms buffer size is handled differently to other devices:
$ ./test_buffers "hw:Layla3G,0,0" 1000
buffer_size=16384 period_size=128
$ ./test_buffers "hw:Layla3G,0,2" 1000
buffer_size=32768 period_size=256
$ ./test_buffers "hw:Layla3G,0,4" 1000
buffer_size=32768 period_size=256
$ ./test_buffers "hw:Layla3G,0,6" 1000
buffer_size=32768 period_size=256
If I try other buffer sizes, I can see is a limit to buffer size of 16384
samples on the ,0 subdevice, which is also affecting the chosen period
size. But only on the first subdevice. Is there a reason, or is this a
bug?
Also, there seem to be failures at certain buffer sizes:
$ ./test_buffers "hw:Layla3G,0,2" 429
buffer_size=18912 period_size=96
$ ./test_buffers "hw:Layla3G,0,2" 430
set_buffer_time_near: Invalid argument
$ ./test_buffers "hw:Layla3G,0,2" 431
buffer_size=19008 period_size=96
Can anyone explain to me what's going on here, or is this also a bug?
The overall problem I'm investigating is snd_pcm_readi() returning
incomplete buffers after running for long periods until another
snd_pcm_prepare(). It seems possible that this is related.
Any help is greatly appreciated.
Thanks,
Mark
-------------- next part --------------
#include <stdio.h>
#include <alsa/asoundlib.h>
#define RATE 44100
#define CHANNELS 2
#define CHK(msg, r) \
{ \
if ((r) < 0) { \
fprintf(stderr, "%s: %s\n", msg, snd_strerror(r)); \
return -1; \
} \
}
int main(int argc, char *argv[])
{
int r, dir;
unsigned int p;
snd_pcm_t *pcm;
snd_pcm_hw_params_t *hw_params;
snd_pcm_uframes_t buffer_size, period_size;
r = snd_pcm_open(&pcm, argv[1], SND_PCM_STREAM_CAPTURE, 0);
CHK("open", r);
r = snd_pcm_hw_params_malloc(&hw_params);
CHK("params_malloc", r);
r = snd_pcm_hw_params_any(pcm, hw_params);
CHK("params_any", r);
r = snd_pcm_hw_params_set_access(pcm, hw_params,
SND_PCM_ACCESS_RW_INTERLEAVED);
CHK("params_set_access", r);
r = snd_pcm_hw_params_set_format(pcm, hw_params, SND_PCM_FORMAT_S32);
CHK("set_format", r);
r = snd_pcm_hw_params_set_rate(pcm, hw_params, RATE, 0);
CHK("set_rate", r);
r = snd_pcm_hw_params_set_channels(pcm, hw_params, CHANNELS);
CHK("set_channels",r);
if (argc > 2) {
p = atoi(argv[2]) * 1000;
r = snd_pcm_hw_params_set_buffer_time_near(pcm, hw_params,
&p, &dir);
CHK("set_buffer_time_near", r);
}
if (argc > 3) {
p = atoi(argv[3]) * 1000;
r = snd_pcm_hw_params_set_period_time_near(pcm, hw_params,
&p, &dir);
CHK("set_period_time_near", r);
}
r = snd_pcm_hw_params(pcm, hw_params);
CHK("hw_params", r);
r = snd_pcm_hw_params_get_buffer_size(hw_params, &buffer_size);
CHK("get_buffer_size", r);
r = snd_pcm_hw_params_get_period_size(hw_params, &period_size, &dir);
CHK("get_period_size", r);
printf("buffer_size=%d period_size=%d\n",
(int)buffer_size, (int)period_size);
r = snd_pcm_close(pcm);
CHK("pcm_close", r);
return 0;
}
More information about the Alsa-devel
mailing list