With USB or Bluetooth sources, the controller exhibited random deviations of new_rate around the correct value, due to latency jitter. Use the already-known latency error due to jitter, and assume that there is no latency difference if the difference is below that error margin. --- src/modules/module-loopback.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c index b733663..6b48fc6 100644 --- a/src/modules/module-loopback.c +++ b/src/modules/module-loopback.c @@ -183,12 +183,12 @@ static void teardown(struct userdata *u) { /* rate controller * - maximum deviation from base rate is less than 1% * - can create audible artifacts by changing the rate too quickly - * - exhibits hunting with USB or Bluetooth sources + * - deadband to handle error of latency measurement */ static uint32_t rate_controller( uint32_t base_rate, pa_usec_t adjust_time, - int32_t latency_difference_usec) { + int32_t latency_difference_usec, pa_usec_t latency_error_usec) { uint32_t new_rate; double min_cycles; @@ -198,6 +198,10 @@ static uint32_t rate_controller( min_cycles = (double)abs(latency_difference_usec) / adjust_time / 0.0095 + 1; new_rate = base_rate * (1.0 + (double)latency_difference_usec / min_cycles / adjust_time); + /* Adjust as good as physics allows (with some safety margin) */ + if (abs(latency_difference_usec) <= 2.5 * latency_error_usec + adjust_time / 2 / base_rate + 100) + new_rate = base_rate; + return new_rate; } @@ -276,7 +280,7 @@ static void adjust_rates(struct userdata *u) { u->source_sink_changed = false; /* Calculate new rate */ - new_rate = rate_controller(base_rate, u->adjust_time, latency_difference); + new_rate = rate_controller(base_rate, u->adjust_time, latency_difference, u->latency_error * final_latency); /* Predictor */ u->next_latency = (corrected_latency * base_rate + (int32_t)(base_rate - new_rate) * (int64_t)u->adjust_time) / new_rate; -- 2.1.4