[pulseaudio-discuss] What is latency? And other related questions

Lennart Poettering lennart at poettering.net
Tue Feb 16 17:02:25 PST 2010


On Thu, 11.02.10 07:35, Tristin Celestin (tristin_celestin at yahoo.com) wrote:

Heya,

(there is something wrong with your mailer. It doesn't do proper line breaking.)

> I managed to write a plugin that successfully delivers audio using
> the normal pulseaudio API. I check the size of
> pa_stream_writable_size every tick, and if it is below some
> threshold, the application runs and produces sound. This threshold
> right now is some magic number I stumbled upon, but I think it is
> related to whatever tlength the server automatically gives me.

You should not apply any threshold like this, and certainly not check
whether _writable_size() is "below" it ("above" would be a better
choice, but having any threshold but 0 is a bad idea).

So what you should be doing is simply check whether _writable_size()
is > 0, and if so supply at least as much data as this value, and you
are free to pass more, in case your PCM generator is based on blocks
of samples and you hence cannot provide the exact amount
_writable_size() returned.

> I can't write the plugin with the simple API, though, because the
> only measure I have of the buffer state is pa_simple_get_latency,
> and this doesn't seem to reflect the state of the sound buffer in
> the same way that pa_stream_writable_size does. So, I assume I am
> misunderstanding what "latency" means. I've never used an audio API
> before, so I don't have any real understanding of the word, just a
> sense of it from mailing lists and games.

pa_stream_writable_size() will tell you how much data is missing in
PA's buffers and which you need to supply quickly.

pa_stream_get_latency() will tell you the delay that if you would call
pa_stream_write() right after it how long it would take until the data
you passed would begin to be audible.

_writable_size() is measured in bytes. _get_latency() is measured in
time units.

For buffer management use the former. For time scheduling use the
latter.

> What happens here either there is a large period (~30 seconds to 90
> seconds) of silence before audio begins to play fine, or I get
> bursts of audio (5-10 seconds) followed by very long bursts of
> silence. I know this is related to prebuffering, but beyond that I
> am lost.

You are probably providing less data than _writable_size() asked you
for. 

Note that PA is optimized for minimal battery/CPU usage. To achieve
that in the ideal case we sleep for 1.9s and then ask all apps for 2s
of data and then go to sleep until only 100ms are unplayed and ask for
the full buffer fillup again. That means that PA will only ask you for
data very very seldomly, which is probably what you are experiencing
here.

> So, in short:
> 1. What is latency?

The time d something you _write() at a time t takes to be played at
a time t+d. Where "playing" means where the data is being turned into
audible sound waves in your speakers.

> 2. How do the meaning of pa_stream_writable_size and
> pa_simple_get_latency differ in terms of the fill state of the
> buffer?

_writable_size() tells you directly about the fill level of your
playback buffer.

_get_latency() is indirectly related to _writable_size() but includes
a lot of additional information. e.g. think of Bluetooth audio,
where the local audio buffer is followed by another audio buffer in
the headset before the audio is actually played. _get_latency() will
try to cover the latency introduced by the latter buffer too, while
_writable_size() just tells you how much data is currently missing and
should be refilled by you in the former buffer.

> 3. Would there be an objection to adding something along the lines
> of pa_simple_writable_size? Does that even make sense?

The simple API is a synchronous API. _writable_size() is useful only
for asynchronous APIs. As such I don't think it makes much sense to
add it to the simple API.

Lennart

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



More information about the pulseaudio-discuss mailing list