[pulseaudio-discuss] alsa sink latency - how to account for startup delay

Georg Chini georg at chini.tk
Mon Apr 11 21:07:16 UTC 2016


On 11.04.2016 21:44, Tanu Kaskinen wrote:
> On Sat, 2016-04-09 at 11:31 +0200, Georg Chini wrote:
>> On 08.04.2016 20:23, Georg Chini wrote:
>>> On 08.04.2016 18:01, Tanu Kaskinen wrote:
>>>> On Wed, 2016-04-06 at 21:17 +0200, Georg Chini wrote:
>>>>> On 06.04.2016 15:55, Tanu Kaskinen wrote:
>>>>>> On Tue, 2016-04-05 at 21:54 +0200, Georg Chini wrote:
>>>>>>> On 05.04.2016 17:42, Tanu Kaskinen wrote:
>>>>>>> Anyway, even if you think it is wrong I am still measuring
>>>>>>> the
>>>>>>> correct
>>>>>>> end-to-end latency with my code, so something I am doing
>>>>>>> must be
>>>>>>> right ...
>>>>>  From what I can tell, that's a coincidence.
>>> No, it definitely isn't. If you accept the precondition, that
>>> samples
>>> not simply vanish from the latency reports, it's physics.
>>> I would tend to agree that I have overlooked something, if the
>>> "extra
>>> delay" would be the same every time and if I could not write down
>>> the math for it.
>>> But it isn't completely constant (just in the same range) and I can
>>> write down the math and it matches my measurements. So I am
>>> fairly sure that I am right. Did you have a look at my document?
>> Let me try to explain again:
>>
>> Assume your first block of data has 10ms length. This means that
>> your first sample has 10ms delay.
> What, where does that 10 ms delay come from for the first sample? Do
> you mean that if pulseaudio wrote 100 ms in the ring buffer before
> snd_pcm_start(), there would be 100 ms latency for the first sample?

yes, surely. To write 100ms of audio you must have them first. I think
you would agree, that the last sample you write has a delay of 0ms
because it is the current sample. The first sample however is 100ms
older, so consequently, since samples are isochronous, the first sample
must have 100ms delay, unless you say that the last sample you
wrote has a delay of -100ms.
It's just a matter of origin.

>
> The delay for the first sample is zero plus the delay between the ring
> buffer and the DAC.
No, the first sample has the delay of the block length, see above.
Again, it is a matter of origin, but the correct origin is the time when
the first sample is produced and not when it is written into the buffer.

>
>> If you now call snd_pcm_start()
>> and it takes another 10 ms before that sample is played, it then has
>> 20 ms delay. Because the samples are isochronous, all following
>> samples will also be delayed by 20 ms.
> No, there's only a 10 ms minimum delay imposed by the pipeline between
> the ring buffer and the DAC. The rest of the delay depends on the ring
> buffer fill level at any given moment. PulseAudio will wait until it's
> empty before writing the next chunk, so the first sample of the next
> chunk will have 10 ms delay when written to the ring buffer
> (oversimplified a bit, since pulseaudio doesn't actually wait until the
> ring buffer is empty, there are some safety margins to avoid
> underruns).

This has absolutely nothing to do with buffers but only with the passing
of time. Leave your buffer-centered thinking and think in terms of time
instead. Samples have the same distance in time, where ever they are
buffered, so once you have a delay, you cannot remove it without
dropping samples.

>
>> Nothing can remove this additional delay unless you drop samples and
>> accept a gap in the audio.
> The 10 ms minimum delay between the ring buffer and the DAC is not
> removable in any case. Dropping samples doesn't help.
>
> Whatever latency the ring buffer contributes can be removed by waiting
> until the ring buffer is less full, no gaps in the audio.

See above, buffers are completely irrelevant.

>
>> Now, if the driver does not hide samples (like it does in your
>> invisible buffer example), you can use my method t determine the
>> delay between snd_pcm_start() and the start of playback (within the
>> bounds of the granularity of the delay reporting).
>> Even in your invisible buffer example my method would give a more
>> accurate value than the current code does, although it would assume
>> that the sample has been played as soon as it is no longer reported.
> In my invisible buffer example the invisible part's size has no effect
> on the values that your method generates. Your method adds the size of
> the "send buffer" (the middle part of my buffer diagram) to the
> reported delays, so if we change my example so that the invisible
> part's length is zero, your method produces 3 ms too large delay
> values, while the unadjusted delay reports would be accurate. If the
> invisible part's length was 3 ms, your method would accidentally
> produce accurate results.
>
Think again. If the invisible buffer part was not there, my code
would report exactly the correct value.


More information about the pulseaudio-discuss mailing list