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