On Tue, Jul 15, 2003 at 08:31:50PM +0200, Jaroslav Kysela wrote:
> I looked to the problem and it seems that the overrun state is handled
> differently in the OSS API than ALSA implemented. It seems that the stream
> is not stopped but rather the oldest period (fragment) is discarded.
>
> The new code (plus some optimization) is in the ALSA CVS tree. The patch
> is attached to this e-mail.
This patch does not solve the problem.
As soon as the buffers runs exactly full - which is now a coincidence,
but happens reasonable quickly, the alsa layer detects an "overrun"
and stops the stream.
The stream is then still not restarted.
Attached is the source code of a slightly adjusted
test case that shows the problem.
Example output of attached test code:
>a.out
Allocated 2 buffers of 1024 bytes.
Allocated 2 buffers of 2048 bytes.
Allocated 2 buffers of 4096 bytes.
Successfully allocated a buffer that is large enough.
Available bytes: 0
Available bytes: 1632
Available bytes: 3264
Available bytes: 4896
Available bytes: 6528
Available bytes: 8160
Available bytes: 5696
Available bytes: 7328
Available bytes: 4864
Available bytes: 6496
Available bytes: 8128
Available bytes: 5664
Available bytes: 7296
Available bytes: 4832
Available bytes: 6464
Available bytes: 8096
Available bytes: 5632
Available bytes: 7264
Available bytes: 4800
Available bytes: 6432
Available bytes: 8064
Available bytes: 5600
Available bytes: 7232
Available bytes: 4768
Available bytes: 6400
Available bytes: 8032
Available bytes: 5568
Available bytes: 7200
Available bytes: 4736
Available bytes: 6368
Available bytes: 8000
Available bytes: 5536
Available bytes: 7168
Available bytes: 4704
Available bytes: 6336
Available bytes: 7968
Available bytes: 5504
Available bytes: 7136
Available bytes: 4672
Available bytes: 6304
Available bytes: 7936
Available bytes: 5472
Available bytes: 7104
Available bytes: 4640
Available bytes: 6272
Available bytes: 7904
Available bytes: 5440
Available bytes: 7072
Available bytes: 4608
Available bytes: 6240
Available bytes: 7872
Available bytes: 5408
Available bytes: 7040
Available bytes: 4576
Available bytes: 6208
Available bytes: 7840
Available bytes: 5376
Available bytes: 7008
Available bytes: 4544
Available bytes: 6176
Available bytes: 7808
Available bytes: 5344
Available bytes: 6976
Available bytes: 4512
Available bytes: 6144
Available bytes: 7776
Available bytes: 5312
Available bytes: 6944
Available bytes: 4480
Available bytes: 6112
Available bytes: 7744
Available bytes: 5280
Available bytes: 6912
Available bytes: 4448
Available bytes: 6080
Available bytes: 7712
Available bytes: 5248
Available bytes: 6880
Available bytes: 4416
Available bytes: 6048
Available bytes: 7680
Available bytes: 5216
Available bytes: 6848
Available bytes: 4384
Available bytes: 6016
Available bytes: 7648
Available bytes: 5184
Available bytes: 6816
Available bytes: 4352
Available bytes: 5984
Available bytes: 7616
Available bytes: 5152
Available bytes: 6784
Available bytes: 4320
Available bytes: 5952
Available bytes: 7584
Available bytes: 5120
Available bytes: 6752
Available bytes: 4288
Available bytes: 5920
Available bytes: 7552
Available bytes: 5088
Available bytes: 6720
Available bytes: 4256
Available bytes: 5888
Available bytes: 7520
Available bytes: 5056
Available bytes: 6688
Available bytes: 4224
Available bytes: 5856
Available bytes: 7488
Available bytes: 5024
Available bytes: 6656
Available bytes: 4192
Available bytes: 5824
Available bytes: 7456
Available bytes: 4992
Available bytes: 6624
Available bytes: 4160
Available bytes: 5792
Available bytes: 7424
Available bytes: 4960
Available bytes: 6592
Available bytes: 4128
Available bytes: 5760
Available bytes: 7392
Available bytes: 4928
Available bytes: 6560
Available bytes: 8192
Successfully caused an xrun.
non-blocking fragments: 2
non-blocking bytes: 8192
Available bytes in buffer: 5728
Additionally read 1024 bytes.
Additionally read 1024 bytes.
Additionally read 1024 bytes.
Additionally read 1024 bytes.
Stream is not restarted after xrun.
--
Carlo Wood <[EMAIL PROTECTED]>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <sys/soundcard.h>
#include <time.h>
int main(void)
{
int fd;
int res = 0x7fff0009;
audio_buf_info info;
int prev_size = 0;
do
{
++res;
close(fd);
fd = open("/dev/dsp", O_RDONLY);
if (fd == -1) { perror("open"); exit(127); }
if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &res) == -1) {
perror("ioctl"); exit(127); }
if (ioctl(fd, SNDCTL_DSP_GETISPACE, &info) == -1) {
perror("read"); exit(127); }
printf(" Allocated %d buffers of %d bytes.\n", info.fragstotal, info.fragsize);
if (prev_size == info.fragsize * info.fragstotal)
{
printf(" It seems impossible to set a recording buffer with a\n"
" total size of at least 8192 bytes. This is not going\n"
" to work with ViaVoice. Sorry.\n");
exit(126);
}
prev_size = info.fragsize * info.fragstotal;
}
while (prev_size < 8192);
printf(" Successfully allocated a buffer that is large enough.\n");
res = AFMT_S16_LE;
if (ioctl(fd, SNDCTL_DSP_SETFMT, &res) == -1) {
perror("ioctl"); exit(127); }
res = 0;
if (ioctl(fd, SNDCTL_DSP_STEREO, &res) == -1) {
perror("ioctl"); exit(127); }
res = 22050;
if (ioctl(fd, SOUND_PCM_READ_RATE, 0xbfffdcfc) == -1) {
perror("ioctl"); exit(127); }
char buf[1024];
if (read(fd, buf, sizeof(buf)) < 0) { perror("read"); exit(127); }
static struct timespec naptime = { 0, 100000000 };
do {
if (ioctl(fd, SNDCTL_DSP_GETISPACE, &info) == -1) {
perror("read"); exit(127); }
printf(" Available bytes: %d\n", info.bytes);
nanosleep(&naptime, 0);
} while(info.bytes < info.fragsize * info.fragstotal);
printf(" Successfully caused an xrun.\n");
printf(" non-blocking fragments: %d\n", info.fragments);
printf(" non-blocking bytes: %d\n", info.bytes);
ssize_t bufsize = info.bytes;
if (ioctl(fd, SNDCTL_DSP_GETISPACE, &info) == -1) {
perror("read"); exit(127); }
printf(" Available bytes in buffer: %d\n", info.bytes);
ssize_t trlen = 0;
int nf = 0;
for (;;)
{
if (info.fragments > 0) {
ssize_t rlen;
if ((rlen = read(fd, buf, sizeof(buf))) < 0)
{ perror("read"); exit(127); }
printf(" Additionally read %d bytes.\n", rlen);
trlen += rlen;
if (trlen > bufsize) {
printf(" Read %d bytes: stream successfully restarted.\n", trlen);
break;
}
nf = 0;
}
else if (++nf > 10) {
printf(" Stream is not restarted after xrun.\n");
exit(1);
}
if (ioctl(fd, SNDCTL_DSP_GETISPACE, &info) == -1) {
perror("read"); exit(127); }
}
close(fd);
return 0;
}