[pulseaudio-discuss] [PATCH 06/13] loopback: Restart the timer right away

Georg Chini georg at chini.tk
Wed Nov 18 09:27:55 PST 2015


On 18.11.2015 15:10, Tanu Kaskinen wrote:
> On Wed, 2015-02-25 at 19:43 +0100, Georg Chini wrote:
>> Move the timer restart to the beginning of the callback function.
> Please try to remember to always answer the question "why" in commit
> messages.

I will in the future ...

>
>> ---
>>   src/modules/module-loopback.c | 14 ++++++++------
>>   1 file changed, 8 insertions(+), 6 deletions(-)
>>
>> diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c
>> index f9255ee..79bd106 100644
>> --- a/src/modules/module-loopback.c
>> +++ b/src/modules/module-loopback.c
>> @@ -196,9 +196,6 @@ static void adjust_rates(struct userdata *u) {
>>       pa_assert(u);
>>       pa_assert_ctl_context();
>>   
>> -    pa_asyncmsgq_send(u->sink_input->sink->asyncmsgq, PA_MSGOBJECT(u->sink_input), SINK_INPUT_MESSAGE_LATENCY_SNAPSHOT, NULL, 0, NULL);
>> -    pa_asyncmsgq_send(u->source_output->source->asyncmsgq, PA_MSGOBJECT(u->source_output), SOURCE_OUTPUT_MESSAGE_LATENCY_SNAPSHOT, NULL, 0, NULL);
>> -
>>       /* Rates and latencies*/
>>       old_rate = u->sink_input->sample_spec.rate;
>>       base_rate = u->source_output->sample_spec.rate;
>> @@ -236,8 +233,6 @@ static void adjust_rates(struct userdata *u) {
>>       /* Set rate */
>>       pa_sink_input_set_rate(u->sink_input, new_rate);
>>       pa_log_debug("[%s] Updated sampling rate to %lu Hz.", u->sink_input->sink->name, (unsigned long) new_rate);
>> -
>> -    pa_core_rttime_restart(u->core, u->time_event, pa_rtclock_now() + u->adjust_time);
>>   }
>>   
>>   /* Called from main context */
>> @@ -248,6 +243,13 @@ static void time_callback(pa_mainloop_api *a, pa_time_event *e, const struct tim
>>       pa_assert(a);
>>       pa_assert(u->time_event == e);
>>   
>> +    /* Restart timer right away */
>> +    pa_core_rttime_restart(u->core, u->time_event, pa_rtclock_now() + u->adjust_time);
> If the goal of this change is to make the wakeups happen exactly with
> adjust_time intervals instead of adjust_time + time taken in servicing
> the timer interrupt, wouldn't it be better to have a counter of the
> timer events and use start_time + counter * adjust_time as the time
> value here? That way the average interval should become exactly
> adjust_time.

Yes, the goal is to minimize the influence of the interrupt service time.
It is more important that two consecutive interrupts are spaced as
exactly as possible by adjust_time, than that the average time interval
is correct. So I believe the best way is to restart the timer as early as
possible in the interrupt routine.

>> +
>> +    /* Get sink and source latency snapshot */
>> +    pa_asyncmsgq_send(u->sink_input->sink->asyncmsgq, PA_MSGOBJECT(u->sink_input), SINK_INPUT_MESSAGE_LATENCY_SNAPSHOT, NULL, 0, NULL);
>> +    pa_asyncmsgq_send(u->source_output->source->asyncmsgq, PA_MSGOBJECT(u->source_output), SOURCE_OUTPUT_MESSAGE_LATENCY_SNAPSHOT, NULL, 0, NULL);
>> +
>>       adjust_rates(u);
>>   }
>>   
>> @@ -257,7 +259,7 @@ static void enable_adjust_timer(struct userdata *u, bool enable) {
>>           if (u->time_event || u->adjust_time <= 0)
>>               return;
>>   
>> -        u->time_event = pa_core_rttime_new(u->module->core, pa_rtclock_now() + u->adjust_time, time_callback, u);
>> +        u->time_event = pa_core_rttime_new(u->module->core, pa_rtclock_now() + 333 * PA_USEC_PER_MSEC, time_callback, u);
> What is this about?
>
Well, actually the patch does two things: One is to move the timer 
restart so that
the interval between calls is as constant and as near to adjust_time as 
possible, the
other is starting the regulation as soon as possible. In the current 
version of module
loopback  - after start up or a sink / source switch - the interrupt 
routine is called the
first time after adjust_time has passed. With the default adjust time 
this means 10
seconds before the latency regulation kicks in, which can lead to 
underruns especially
after switching source or sink.
Replacing adjust_time by one third of a second gives the source/sink 
enough time to settle
down to report reliable latency values and starts the regulation process 
as early as
possible (thereby also resetting any previous deviations from the base 
rate).


More information about the pulseaudio-discuss mailing list