[alsa-devel] Buffering issues

Lennart Poettering mznyfn at 0pointer.de
Mon Apr 21 23:30:59 CEST 2008


Heya!

As you might now I am currently working on something called
"glitch-free playback model" for PulseAudio:
http://0pointer.de/blog/projects/pulse-glitch-free.html

One of the central ideas is to schedule audio via timer interrupts, no
longer via period-based interrupts. To acomplish this I need to be
able to estimate in advance how long (in time) it will take until the
playback buffer runs empty at a certain point. Then I can set myself a
system timer to wakeup a certain margin earlier than this and fill the
buffer up again. That way I minimize wakeups and should always have
enough safety margin to never get an xrun.

Now, the way I implemented this right now is: in each iteration of my
playback loop I first fill up the playback buffer completely if it is
not fully filled up yet. After that I obviously can go to sleep for
the time it takes to play buffer_size samples minus some safety
margin, which i set to 20ms. Apparently this is actually not as
obvious as I thought. This works fine on many soundcards but it
apparently doesn't work on USB hardware. There, ALSA detects a buffer
underrun much earlier than when my timer elapses. My loop wakes up due
to activity on the ALSA fd, not because of the timer.

My code then goes and asks _avail_update() for the free space in the
buffer and sees that the full buffer is available, thus assuming a
xrun happened. This will cause PA to double the safety margin and do
some other things to make sure an XRUN doesn't happen the next time
again.

So, how do I properly estimate how long the filled up buffer will take
to play? Or to word it differently: how do I properly estimate how
much time will pass until an XRUN would occur?

[My interpretation of what's going on here with lots of guessing how
things work is this: the buffer exposed by ALSA is merely a send
buffer and just one of the buffers involved before the data actually
reaches the speakers. ALSA just takes the data out of this buffer and
sends it to the device via USB block-by-block. Thus the send buffer
maintained by ALSA is much quicker empty than the audio data is
actually played. And Boom! -- If that should actually be the case then
I'd like to request an API that allows me to query an upper limit for
how much buffering/latency actually happens after the audio data left
the ALSA buffer. I could then use this an subtract it from my time to
sleep.]

Thanks, 

Lennart

-- 
Lennart Poettering                        Red Hat, Inc.
lennart [at] poettering [dot] net         ICQ# 11060553
http://0pointer.net/lennart/           GnuPG 0x1A015CC4


More information about the Alsa-devel mailing list