[vlc-commits] PulseAudio: more conservative and stable resampling

Rémi Denis-Courmont git at videolan.org
Sun Jul 31 21:31:42 CEST 2011


vlc/vlc-1.1 | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Wed Jul 27 23:18:08 2011 +0300| [7bacf54f81997e398bb5411d38c77f4e4355b496] | committer: 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

> http://git.videolan.org/gitweb.cgi/vlc/vlc-1.1.git/?a=commit;h=7bacf54f81997e398bb5411d38c77f4e4355b496
---

 modules/audio_output/pulse.c |   33 +++++++++++++++++++--------------
 1 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/modules/audio_output/pulse.c b/modules/audio_output/pulse.c
index 71bdee0..37f5141 100644
--- a/modules/audio_output/pulse.c
+++ b/modules/audio_output/pulse.c
@@ -200,34 +200,39 @@ static void stream_latency_cb(pa_stream *s, void *userdata)
     //msg_Dbg(aout, "desync: %+"PRId64" us (variation: %+"PRId64" us)",
     //        delta, change);
 
+    const unsigned inrate = aout->output.output.i_rate;
+    unsigned outrate = sys->rate;
+    bool sync = false;
+
     if (delta < -AOUT_LATE_TOLERANCE)
         msg_Warn(aout, "too late by %"PRId64" us", -delta);
     else if (delta > +AOUT_EARLY_TOLERANCE)
         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 */
-    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. */
-    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). */
+    int adj = sync ? (outrate - inrate)
+                   : outrate * (delta + change) / (CLOCK_FREQ << 4);
+    /* This avoids too quick rate variation. It sounds really bad and
+     * 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)
         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;
+    outrate -= adj;
 
     /* This keeps the effective rate within specified range
      * (+/-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)
         outrate = inrate + limit;
     if (outrate < inrate - limit)



More information about the vlc-commits mailing list