Commit 7bacf54f authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

PulseAudio: more conservative and stable resampling

This time, it should work (famous last words).
(cherry picked from commit 7dc50c98a523b9a2dc0e0255868f1a17757c1a10)

Conflicts:

	modules/audio_output/pulse.c
parent 429558a9
...@@ -200,34 +200,39 @@ static void stream_latency_cb(pa_stream *s, void *userdata) ...@@ -200,34 +200,39 @@ static void stream_latency_cb(pa_stream *s, void *userdata)
//msg_Dbg(aout, "desync: %+"PRId64" us (variation: %+"PRId64" us)", //msg_Dbg(aout, "desync: %+"PRId64" us (variation: %+"PRId64" us)",
// delta, change); // delta, change);
const unsigned inrate = aout->output.output.i_rate;
unsigned outrate = sys->rate;
bool sync = false;
if (delta < -AOUT_LATE_TOLERANCE) if (delta < -AOUT_LATE_TOLERANCE)
msg_Warn(aout, "too late by %"PRId64" us", -delta); msg_Warn(aout, "too late by %"PRId64" us", -delta);
else if (delta > +AOUT_EARLY_TOLERANCE) else if (delta > +AOUT_EARLY_TOLERANCE)
msg_Warn(aout, "too early by %"PRId64" us", delta); msg_Warn(aout, "too early by %"PRId64" us", delta);
else if (outrate == inrate)
return; /* In sync, do not add unnecessary disturbance! */
else
sync = true;
/* Compute playback sample rate */ /* Compute playback sample rate */
const unsigned inrate = aout->output.output.i_rate;
int limit = inrate / 100; /* max varation per iteration */
#define ADJUST_FACTOR 4
/* This is empirical. Feel free to define something smarter. */ /* This is empirical. Feel free to define something smarter. */
int adj = sys->rate * (delta + change) / (CLOCK_FREQ * ADJUST_FACTOR); int adj = sync ? (outrate - inrate)
: outrate * (delta + change) / (CLOCK_FREQ << 4);
/* This avoids too fast rate variation. They sound ugly as hell and they /* This avoids too quick rate variation. It sounds really bad and
* make the algorithm unstable (e.g. oscillation around inrate). */ * causes unstability (e.g. oscillation around the correct rate). */
int limit = inrate >> 10;
/* However, to improve stability and try to converge, closing to the
* nominal rate is favored over drifting from it. */
if ((adj > 0) == (sys->rate > inrate))
limit *= 2;
if (adj > +limit) if (adj > +limit)
adj = +limit; adj = +limit;
if (adj < -limit) if (adj < -limit)
adj = -limit; adj = -limit;
outrate -= adj;
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 /* This keeps the effective rate within specified range
* (+/-AOUT_MAX_RESAMPLING% - see <vlc_aout.h>) of the nominal rate. */ * (+/-AOUT_MAX_RESAMPLING% - see <vlc_aout.h>) of the nominal rate. */
limit *= AOUT_MAX_RESAMPLING; limit = inrate * AOUT_MAX_RESAMPLING / 100;
if (outrate > inrate + limit) if (outrate > inrate + limit)
outrate = inrate + limit; outrate = inrate + limit;
if (outrate < inrate - limit) if (outrate < inrate - limit)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment