[pulseaudio-discuss] [PATCH 10/13] loopback: Added a deadband to reduce rate hunting
Georg Chini
georg at chini.tk
Wed Feb 25 10:43:22 PST 2015
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
More information about the pulseaudio-discuss
mailing list