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

Georg Chini georg at chini.tk
Sun Nov 22 08:57:22 PST 2015

On 22.11.2015 16:05, Alexander E. Patrakov wrote:
> 22.11.2015 18:44, Georg Chini wrote:
>> On 22.11.2015 14:26, Alexander E. Patrakov wrote:
>>> 22.11.2015 17:21, Georg Chini wrote:
>>>> The other big problem is that you cannot determine the number
>>>> of cycles you will need to correct the initial latency error because
>>>> this error is unknown before the first adjustment cycle.
>>> You can circumvent this problem by sending zeros instead of the actual
>>> data until you correct the initial latency error well enough. And,
>>> because we are sending zeros, nobody cares if there are big frequency
>>> steps. So one cycle is always enough to correct the initial latency
>>> error once it is known, and then we can unmute the sound.
>> I do not understand what you are proposing. Are you saying we should
>> skip samples
>> until we are near the requested latency? So send no audio for at least
>> one adjust time?
>> That would mean that you have to reduce the adjust time drastically.
>> BTW, I did some experiments with shorter adjust times and could not see
>> a significant
>> improvement over the 1s interval.
> Not "send no audio", but "send silence of the same length as input, 
> and get it resampled".
> Yes, this means that adjust_time has to be at most 1s.

So one second silence after loading the module? Sounds rather long to me.
And what should happen in case of an underrun?

>>>> When you calculate that safety margin you also have to consider
>>>> that the controller might overshoot, so you temporarily could
>>>> get less latency than you requested.
>>> This is definitely impossible with the controller in PATCH 04/13
>>> modified so that min_cycles is always 1. Indeed, by design, such
>>> controller corrects exactly 100% of the latency error in one step,
>>> without paying attention that it might be noticeable. And with
>>> min_cycles > 1, it corrects less than 100% of the error, so cannot
>>> make the situation any worse than it is. I.e. here overshoot would
>>> mean correcting less than 0% or more than 100% of the error, and it
>>> just can't happen.
>> In theory yes, but practice you are wrong here. It does overshoot
>> sometimes, especially
>> with long adjust times because we are taking measurements that have some
>> error.
>> Consider that the measured latency is 2 ms too long (this can easily
>> happen in the first cycles),
>> then you will correct 2 ms too much. With short latencies, even half a
>> millisecond might
>> be significant.
> That's only a problem for your P-controller that corrects 100% of the 
> measured latency error (which is, as you have illustrated, not the 
> same as the real latency error) in one step. It is a good controller 
> for emergencies, but for normal operation we do need something 
> different, and you have already implemented that.
> You first invented some "deadband" code that switches to a very dumb 
> controller that does not correct anything - but even that was better 
> than the emergency controller for the steady state. Then you sent a 
> private patch that estimates the clock drift, thus essentially turning 
> the "deadband" code into something that decides between the old 
> (emergency) and the new (slow and good) controller.

Be aware, that the "slow and good" controller ONLY accounts for the 
clock drift,
that means it does not care about the steady state latency. Still the 
other controller
is required to set the requested value.
Also a "slow and good" controller cannot handle sudden latency changes 
by underruns very well, so you will need some "emergency" controller to put
things right in that case (at least if you don't want to insert silence 
or drop samples).

>>> OTOH, the PI-controller that I am currently working on can indeed
>>> overshoot. I think a good idea would be to detect situations where the
>>> latency error is excessive or would be excessive during the next step,
>>> and correct this situation with your controller with min_cycles = 1,
>>> instead of my controller. That's, without paying attention to 
>>> artifacts.
>>> I will post this controller (and, as requested, perform measurements
>>> with the trivial resampler) in the near future.
>> Thanks, please also test the patch I sent on Friday.
> With trivial resampler: https://imgur.com/a/z6oOY
> With speex-float-5: https://imgur.com/a/dOIRc

Thank you for your tests. speex-float-5 looks even better than the 
trivial resampler.

> In both cases, adjust_time=1. No definite conclusions until I compare 
> this with my PI-controller, but both plots look similar to me, and 
> have phase jitter of approximately the same scale as in 
> https://imgur.com/a/eZT8L, but more smooth.
Yes, but the last one takes 50 seconds to compensate the initial latency 
error while my
controller does it in less than 10 seconds. The small peak between 10 
and 30 seconds
is a consequence of large errors during the first cycles. I did some 
changes to the code
that should eliminate that as well.

More information about the pulseaudio-discuss mailing list