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

Georg Chini georg at chini.tk
Wed Apr 6 03:59:46 UTC 2016


On 06.04.2016 05:08, Raymond Yau wrote:
>
>
> >>>>>>>
> >>>>>>> 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 depends on what delay you mean. The delay I am talking about
above stays the same, but as already said the individual sinks and
sources have additional small delays of their own. So moving the
source from HDA to USB increases the overall latency by about 1ms.

> 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
>

The low limit of module-loopback seems to be around 5ms end-to-end latency
for HDA -> HDA. At this point tons of "memblock.c: Pool full" messages 
appear
in the log and going below 5ms will always lead to underruns.

> 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
>
>
Both nodes do not show a delay on my hardware.


More information about the pulseaudio-discuss mailing list