[pulseaudio-discuss] [PATCH v6 20/25] loopback: Add latency prediction and Kalman filter
Tanu Kaskinen
tanuk at iki.fi
Wed Aug 24 19:12:42 UTC 2016
On Sun, 2016-06-05 at 21:05 +0200, Georg Chini wrote:
> @@ -261,6 +267,7 @@ static void adjust_rates(struct userdata *u) {
> int32_t latency_difference;
> pa_usec_t current_buffer_latency, snapshot_delay, current_source_sink_latency, current_latency, latency_at_optimum_rate;
> pa_usec_t final_latency;
> + double filtered_latency, current_latency_error, latency_correction, base_rate_with_drift;
>
> pa_assert(u);
> pa_assert_ctl_context();
> @@ -321,6 +328,23 @@ static void adjust_rates(struct userdata *u) {
> final_latency = PA_MAX(u->latency, u->minimum_latency + u->extra_latency);
> latency_difference = (int32_t)((int64_t)current_latency - final_latency);
>
> + /* Do not filter or calculate error if source or sink changed or if there was an underrun */
> + if (u->source_sink_changed || u->underrun_occured) {
> + /* Initial conditions are very unsure, so use a high variance */
> + u->kalman_variance = 10000000;
Should u->latency_variance be reset too?
> + filtered_latency = latency_at_optimum_rate;
> + u->next_latency_at_optimum_rate_with_drift = latency_at_optimum_rate;
> + u->next_latency_with_drift = current_latency;
> +
> + } else {
> + /* Low pass filtered latency variance */
> + current_latency_error = (double)abs((int32_t)(latency_at_optimum_rate - u->next_latency_at_optimum_rate_with_drift));
The (int32_t) cast should be applied to the individual terms, not to
the result of the substraction.
> @@ -338,6 +362,30 @@ static void adjust_rates(struct userdata *u) {
> u->source_sink_changed = false;
> u->underrun_occured = false;
>
> + /* Predicton of next latency */
> +
> + /* Evaluate optimum rate */
> + base_rate_with_drift = u->drift_compensation_rate + base_rate;
> +
> + /* Latency correction on next iteration */
> + latency_correction = (base_rate_with_drift - new_rate) * (int64_t)u->real_adjust_time / new_rate;
> +
> + if ((int)new_rate != (int)base_rate_with_drift || new_rate != old_rate) {
new_rate is already an integer, no need to cast it.
--
Tanu
More information about the pulseaudio-discuss
mailing list