- /* Compute lip desynchronization */
- delta = vlc_pa_get_latency(aout, sys->context, s);
- if (delta == VLC_TS_INVALID)
- return;
-
- delta = (sys->pts - mdate()) - delta;
- change = delta - sys->desync;
- sys->desync = delta;
- //msg_Dbg(aout, "desync: %+"PRId64" us (variation: %+"PRId64" us)",
- // delta, change);
-
- if (delta < -AOUT_MAX_PTS_DELAY)
- msg_Warn(aout, "too late by %"PRId64" us", -delta);
- else if (delta > +AOUT_MAX_PTS_ADVANCE)
- msg_Warn(aout, "too early by %"PRId64" us", delta);
-
- /* Compute playback sample rate */
- const unsigned inrate = aout->format.i_rate;
- int limit = inrate / 100; /* max varation per iteration */
-
-#define ADJUST_FACTOR 4
- /* This is empirical. Feel free to define something smarter. */
- int adj = sys->rate * (delta + change) / (CLOCK_FREQ * ADJUST_FACTOR);
-
- /* This avoids too fast rate variation. They sound ugly as hell and they
- * make the algorithm unstable (e.g. oscillation around inrate). */
- if (adj > +limit)
- adj = +limit;
- if (adj < -limit)
- adj = -limit;
-
- unsigned outrate = sys->rate - adj;
- /* Favor native rate to avoid resampling (FIXME: really a good idea?) */
- if (abs(outrate - inrate) < limit)
- outrate = inrate;
-
- /* This keeps the effective rate within specified range
- * (+/-AOUT_MAX_RESAMPLING% - see <vlc_aout.h>) of the nominal rate. */
- limit *= AOUT_MAX_RESAMPLING;
- if (outrate > inrate + limit)
- outrate = inrate + limit;
- if (outrate < inrate - limit)
- outrate = inrate - limit;
-
- /* Apply adjusted sample rate */
- if (outrate == sys->rate)
- return;
- pa_operation *op = pa_stream_update_sample_rate(s, outrate, NULL, NULL);
- if (unlikely(op == NULL)) {
- vlc_pa_error(aout, "cannot change sample rate", sys->context);
- return;
- }
- pa_operation_unref(op);
- msg_Dbg(aout, "changed sample rate to %u Hz",outrate);
- sys->rate = outrate;