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

Raymond Yau superquad.vortex2 at gmail.com
Wed Apr 6 03:08:12 UTC 2016


>>>>>>>
>>>>>>> 5) The pulseaudio sink code takes the first 10ms of audio out of the
>>>>>>> loopback buffer,
>>>>>>> writes it to the alsa buffer and calls snd_pcm_start().
>>>>>>
>>>>>> If the sink takes something from the loopback buffer, this means that
>>>>>> the first pop() call has been made. Assuming no time has passed since
>>>>>> the previous step, the USB bus is still full, and so is the ring
>>>>>> buffer. Expected delay: 20 ms.
>>>>>
>>>>> Reported delay is exactly the amount of audio that was written to
>>>>> the buffer.
>>>>
>>>> That's the bug that I think should be fixed in alsa if possible (and if
>>>> it's impossible, I don't see how it could be fixed in pulseaudio
>>>> either).
>>>
>>> It can be fixed (or at least be worked around). If you take a time stamp
>>> at the moment when snd_pcm_start() is called and another when
>>> the first audio has definitely been played (delay < write_count), then
>>> the difference between the time stamps corrected by the amount
>>> of audio that has already been played, gives you exactly that
>>> missing bit of latency.
>>
>> I can't follow that line of reasoning. In the beginning the ring buffer
>> is filled to max, and once you call snd_pcm_start(), data starts to
>> move from the ring buffer to other buffers (I'll call the other buffers
>> the "not-ring-buffer"). Apparently the driver "sees" the not-ring-
>> buffer only partially, since it reports a larger latency than just the
>> ring buffer fill level, but it still doesn't report the full latency.
>> The time between snd_pcm_start() and the point where the reported delay
>> does not any more equal the written amount tells the size of the
>> visible part of the not-ring-buffer - it's the time it took for the
>> first sample to travel from the ring buffer to the invisible part of
>> the not-ring-buffer. I don't understand how the time could say anything
>> about the size of the invisible part of the not-ring-buffer. Your logic
>> "works" only if the visible and invisible parts happen to be of the
>> same size.
>>
>> You should get the same results by calculating
>>
>>    adjusted delay = ring buffer fill level + 2 * (reported delay - ring
buffer fill level)
>>
>> That formula doesn't make sense, but that's how I understand your logic
>> works, with the difference that your fix is based on one measurement
>> only, so it's constant over time, while my formula recalculates the
>> adjustment every time the delay is queried, so the adjustment size
>> varies somewhat depending on the granularity at which audio moves to
>> and from the visible part of the not-ring-buffer.
>>
>> In any case, even if your logic actually makes sense and I'm just
>> misunderstanding something, I don't see why the correction should be
>> done in pulseaudio instead of the alsa driver.
>
>
> Well, now I don't understand what you mean. The logic is very simple:
> If there is a not reported delay between the time snd_pcm_start() is
> called and the time when the first sample is delivered to the DAC, then
> this delay will persist and become part of the continuous latency.
> That's all, what causes the delay is completely irrelevant.
>
> Maybe what I said above was not complete. At the point in time when
> the first audio is played, there are two delays: First the one that is
reported
> by alsa and the other is the difference between the time stamps minus
> the played audio. If these two delays don't match, then there is an
> "extra delay" that has to be taken into account.
> Trying to fix up that delay on every iteration does not make any sense
> at all, it is there from the start and it is constant.
>
> You are actually right - the problem should be fixed in the alsa driver,
> but that should not hinder pulseaudio to work around the issue for
> multiple reasons:
> 1) It is relatively easy to work around
> 2) If the problem is fixed in the alsa driver, the delay would just be
> 0 and so have no impact anymore. This means there is no need
> to change the code after the bug has been fixed in alsa.
> 3) If there is another driver out there with the same or a similar bug,
> (which I think is not unlikely) pulseaudio would do the right thing and
> fix it up.
> 4) When it is fixed in the alsa driver pulseaudio should still be able to
> deliver the right values with a not fixed driver - at least for some time
> until old versions of the alsa driver have died out.

The capture device may already started by other application (e.g. mic peak
of pavucontrol), there is some audio already captured by driver but not
read by server

At low latency, usb pointer incremented by number of frames in urb packet
but hda intel increment by frames in dma brust

Do the result different when you use hda-intel as source and usb audio for
playback?

It is unlikey module loopback can achieve lowest latency when you cannot
control start,  capture and playback of alsa sink and source

It should have latency higher than snd-aloop,  alsaloop or latency.c

How can I query those values? Input delay seems to be 0 for HDA, the source
starts
> capturing samples immediately after snd_pcm_start().

Only some hda codec provide this delay, do this delay still exist if band
EQ or hardware filters is not enabled?

http://git.kernel.org/cgit/linux/kernel/git/tiwai/hda-emu.git/tree/codecs/idt92hd73e1x5-intel-dg45id?id=HEAD

Node 0x17 [Audio Output] wcaps 0xd0c05: Stereo Amp-Out R/L
Amp-Out caps: N/A
Amp-Out vals: [0x78 0x78]
Converter: stream=0, channel=0
Power: setting=D0, actual=D0
Delay: 13 samples

Node 0x1a [Audio Input] wcaps 0x1d0541: Stereo
Converter: stream=0, channel=0 SDI-Select: 0
Power: setting=D0, actual=D0
Delay: 13 samples
Connection: 1
0x20
Processing caps: benign=0, ncoeff=0
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/pulseaudio-discuss/attachments/20160406/8aaf1e65/attachment-0001.html>


More information about the pulseaudio-discuss mailing list