[pulseaudio-discuss] [PATCH 07/13] loopback: Refactor latency initialization

Tanu Kaskinen tanuk at iki.fi
Thu Nov 26 19:46:40 PST 2015


On Thu, 2015-11-26 at 20:36 +0100, Georg Chini wrote:
> On 26.11.2015 18:47, Tanu Kaskinen wrote:
> > On Thu, 2015-11-26 at 08:41 +0100, Georg Chini wrote:
> > > On 26.11.2015 01:49, Tanu Kaskinen wrote:
> > > > And what does this have to do with increasing the latency on underruns?
> > > > If you get an underrun, then you know buffer_latency is too low, so you
> > > > bump it up by 5 ms (if I recall your earlier email correctly), causing
> > > > the configured total latency to go up by 5 ms as well. As far as I can
> > > > see, the measured latency is not needed for anything in this operation.
> > > > 
> > > > ----
> > > > 
> > > > Using your example (usb sound card with 4 * 5 ms sink and source
> > > > buffers), my algorithm combined with the alsa source optimization
> > > > yields the following results:
> > > > 
> > > > configured sink latency = 20 ms
> > > > configured source latency = 20 ms
> > > > maximum source buffer fill level = 5 ms
> > > > buffer_latency = 0 ms
> > > > target latency = 25 ms
> > > > 
> > > > So you see that the results aren't necessarily overly conservative.
> > > That's different from what you proposed above, but sounds
> > > like a reasonable approach. The calculation would be slightly
> > > different because I defined buffer_latency = 5 ms on the
> > > command line. So the result would be 30 ms, which is more
> > > sensible. First we already know that the 25 ms won't work.
> > > Second, the goal of the calculation was to find a working
> > > target latency using the configured buffer_latency, so you
> > > can't ignore it.
> > > My calculation leads to around 27.5 ms instead of your 30 ms,
> > > so the two values are near enough to each other and your
> > > proposal has the advantage of being constant.
> > > 
> > > I will replace the average sum by
> > > 0.25 * configured_source_latency + configured_sink_latency.
> > > in the next version if my tests with that value are successful.
> > Do you mean that you're going to use 0.25 as the multiplier regardless
> > of the number of fragments?
> > 
> > Previously I've been saying that in the general case the target latency
> > should be "configured source latency + buffer_latency + configured sink
> > latency". To generalize the alsa source exception, I'll use the
> > following definition instead from now on: "target latency = maximum
> > source buffer fill level + buffer_latency + maximum sink buffer fill
> > level". Usually the maximum fill levels have to be assumed to be the
> > same as the configured latencies, but in the interrupt-driven alsa
> > source case the maximum fill level is known to be "configured source
> > latency / fragments".
> 
> OK, now I finally got you. That has taken quite a bit, sorry.

Yay! Thanks for not getting too frustrated to continue the discussion.

> Let me summarize:
> 
> - The minimum achievable latency is maximum source fill + maximum sink fill
> - The sink maximum fill level is always 100%, regardless of the device type
> - The source maximum fill level depends on device type
>     # For interrupt driven alsa sources it is one default-fragment-size
>     # For timer-based alsa devices it is 50% of the configured latency
>     # For the general case it is unknown and may be 100%
> 
> Do we have an agreement so far?

Where does that 50% come from for timer-based sources? The timer logic
works so that the source sleeps until the buffer is (almost) full.

> As we are talking about fail-safe measures I would think that it is OK
> to assume that 50% is a reasonable value even for the general case.
> As already said there is a mechanism in the controller that will handle
> the cases when that assumption is not true and I would not want
> to throw away the potential reduction of the latency just to be on
> the 100% safe side.

I don't really like that, but if you really want to do it that way,
fine. In case of bluetooth it may work fine. The fixed latency that is
set for sources is read_block_size plus a certain profile-dependent
constant (which may actually be completely bogus). I'm not sure what
the ratio between read_block_size and the constant usually is, but I'd
guess that read_block_size is smaller, so 50% may be more than enough.
I think read_block_size could be used as the max buffer fill level
variable, if it was possible to query from the source somehow (it
currently isn't).

-- 
Tanu


More information about the pulseaudio-discuss mailing list