[pulseaudio-discuss] [PATCH v6 17/25] loopback: Track and use average adjust time

Georg Chini georg at chini.tk
Sun Jun 5 19:05:20 UTC 2016


The configured adjust time does not match exactly the real adjust time. Also
the adjust time varies. To improve latency estimation use an average of the
measured adjust times instead of the configured value in all calculations.

---
 src/modules/module-loopback.c | 27 ++++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c
index c773a98..03f23e3 100644
--- a/src/modules/module-loopback.c
+++ b/src/modules/module-loopback.c
@@ -79,11 +79,18 @@ struct userdata {
 
     pa_time_event *time_event;
 
+    /* Variables used to calculate the average time between
+     * subsequent calls of adjust_rates() */
+    pa_usec_t time_stamp;
+    pa_usec_t real_adjust_time;
+    pa_usec_t real_adjust_time_sum;
+
     /* Various counters */
     int64_t recv_counter;
     int64_t send_counter;
     uint32_t iteration_counter;
     uint32_t underrun_counter;
+    uint32_t adjust_counter;
 
     /* Values from command line configuration */
     pa_usec_t latency;
@@ -218,7 +225,7 @@ static void adjust_rates(struct userdata *u) {
     pa_assert_ctl_context();
 
     /* Runtime and counters since last change of source or sink */
-    hours = u->iteration_counter * u->adjust_time / PA_USEC_PER_SEC / 3600;
+    hours = u->iteration_counter * u->real_adjust_time / PA_USEC_PER_SEC / 3600;
     u->iteration_counter +=1;
 
     /* If we are seeing underruns then the latency is too small */
@@ -232,11 +239,21 @@ static void adjust_rates(struct userdata *u) {
     }
 
     /* Allow one underrun per hour */
-    if (u->iteration_counter * u->adjust_time / PA_USEC_PER_SEC / 3600 > hours) {
+    if (u->iteration_counter * u->real_adjust_time / PA_USEC_PER_SEC / 3600 > hours) {
         pa_log_info("Underrun counter: %u", u->underrun_counter);
         u->underrun_counter = PA_CLIP_SUB(u->underrun_counter, 1u);
     }
 
+    /* Calculate real adjust time */
+    if (u->source_sink_changed)
+        u->time_stamp = pa_rtclock_now();
+    else {
+        u->adjust_counter++;
+        u->real_adjust_time_sum += pa_rtclock_now() - u->time_stamp;
+        u->time_stamp = pa_rtclock_now();
+        u->real_adjust_time = u->real_adjust_time_sum / u->adjust_counter;
+    }
+
     /* Rates and latencies*/
     old_rate = u->sink_input->sample_spec.rate;
     base_rate = u->source_output->sample_spec.rate;
@@ -269,7 +286,7 @@ static void adjust_rates(struct userdata *u) {
     pa_log_debug("Loopback latency at base rate is %0.2f ms", (double)latency_at_optimum_rate / PA_USEC_PER_MSEC);
 
     /* Calculate new rate */
-    new_rate = rate_controller(base_rate, u->adjust_time, latency_difference);
+    new_rate = rate_controller(base_rate, u->real_adjust_time, latency_difference);
 
     u->source_sink_changed = false;
 
@@ -1082,6 +1099,10 @@ int pa__init(pa_module *m) {
     else
         u->adjust_time = DEFAULT_ADJUST_TIME_USEC;
 
+    u->real_adjust_time = u->adjust_time;
+    u->real_adjust_time_sum = 0;
+    u->adjust_counter = 0;
+
     pa_sink_input_new_data_init(&sink_input_data);
     sink_input_data.driver = __FILE__;
     sink_input_data.module = m;
-- 
2.8.1



More information about the pulseaudio-discuss mailing list