Blob Blame History Raw
diff -Nur audacious-plugins-fedora-1.5.1-alsa-ng-mixer/src/alsa/alsa-core.c audacious-plugins-fedora-1.5.1-alsa-ng-underruns/src/alsa/alsa-core.c
--- audacious-plugins-fedora-1.5.1-alsa-ng-mixer/src/alsa/alsa-core.c	2009-09-19 12:54:29.476615457 +0200
+++ audacious-plugins-fedora-1.5.1-alsa-ng-underruns/src/alsa/alsa-core.c	2009-10-26 12:12:39.000000000 +0100
@@ -27,6 +27,10 @@
 static gboolean pcm_going = FALSE;
 static GThread *audio_thread = NULL;
 static gint bps;
+static gint loopbufsize = 384000;
+static gint looppostsize = 2048;
+static gint looppresize;
+static gboolean prefill = TRUE;
 
 static gsize wr_total = 0;
 static gsize wr_hwframes = 0;
@@ -224,6 +228,9 @@
         }
         else
         {
+            if (wr_frames == -EPIPE) {
+                prefill = TRUE;
+            }
             gint err = snd_pcm_recover(pcm_handle, wr_frames, 1);
 
             _DEBUG ("snd_pcm_writei error: %s", snd_strerror (wr_frames));
@@ -240,7 +247,7 @@
 static gpointer
 alsaplug_loop(gpointer unused)
 {
-    guchar buf[2048];
+    guchar buf[loopbufsize];
     int size;
 
     while (pcm_going)
@@ -250,6 +257,7 @@
         if (flush_request != -1)
         {
             alsaplug_ringbuffer_reset (& pcm_ringbuf);
+            prefill = TRUE;
             snd_pcm_drop(pcm_handle);
             snd_pcm_prepare(pcm_handle);
             wr_total = flush_request * (long long) bps / 1000;
@@ -267,12 +275,25 @@
             continue;
         }
 
-        if (size > sizeof buf)
-            size = sizeof buf;
+        if (prefill) {
+            if (size > loopbufsize)
+                size = loopbufsize;
+
+            if (size >= looppresize) {
+                alsaplug_ringbuffer_read (& pcm_ringbuf, buf, size);
+                prefill = FALSE;
+            }
+        }
+        else {
+            if (size > looppostsize)
+                size = looppostsize;
 
-        alsaplug_ringbuffer_read (& pcm_ringbuf, buf, size);
+            alsaplug_ringbuffer_read (& pcm_ringbuf, buf, size);
+        }
         g_mutex_unlock (pcm_state_mutex);
-        alsaplug_write_buffer (buf, size);
+        if (!prefill) {
+            alsaplug_write_buffer (buf, size);
+        }
     }
 
     snd_pcm_drain(pcm_handle);
@@ -324,9 +345,10 @@
 static gint
 alsaplug_open_audio(AFormat fmt, gint rate, gint nch)
 {
-    gint err, bitwidth, ringbuf_size, buf_size;
+    gint err, bitwidth, ringbuf_size, buf_size, buf_size_norm;
     snd_pcm_format_t afmt;
     snd_pcm_hw_params_t *hwparams = NULL;
+    guint buf_time_min;
 
     afmt = alsaplug_format_convert(fmt);
     if (afmt == SND_PCM_FORMAT_UNKNOWN)
@@ -345,6 +367,10 @@
         return -1;
     }
 
+    buf_size = MAX(aud_cfg->output_buffer_size, 100);
+    buf_size_norm = MAX(buf_size-400, 100);
+    buf_time_min = buf_size_norm * 1000;
+
     snd_pcm_hw_params_alloca(&hwparams);
     snd_pcm_hw_params_any(pcm_handle, hwparams);
     CHECK_FAIL (snd_pcm_hw_params_set_access (pcm_handle, hwparams,
@@ -355,18 +381,25 @@
      "snd_pcm_hw_params_set_channels");
     CHECK_FAIL (snd_pcm_hw_params_set_rate (pcm_handle, hwparams, rate, 0),
      "snd_pcm_hw_params_set_rate");
+    snd_pcm_hw_params_set_buffer_time_min (pcm_handle, hwparams, &buf_time_min, 0);
     CHECK_FAIL (snd_pcm_hw_params (pcm_handle, hwparams), "snd_pcm_hw_params");
 
     bitwidth = snd_pcm_format_physical_width(afmt);
     bps = (rate * bitwidth * nch) >> 3;
 
-    buf_size = MAX(aud_cfg->output_buffer_size, 100);
     ringbuf_size = buf_size * bps / 1000;
 
     if (alsaplug_ringbuffer_init(&pcm_ringbuf, ringbuf_size) == -1) {
         _ERROR("alsaplug_ringbuffer_init failed");
         return -1;
     }
+    if (loopbufsize >= ringbuf_size) {
+        looppresize = ringbuf_size/2;
+    }
+    else {
+        looppresize = loopbufsize;
+    }
+    prefill = TRUE;
     pcm_going = TRUE;
     flush_request = -1;
     paused = FALSE;
@@ -509,6 +542,7 @@
 {
     g_mutex_lock (pcm_state_mutex);
     paused = p;
+    prefill = !paused;
     g_cond_broadcast (pcm_state_cond);
     g_mutex_unlock (pcm_state_mutex);
 }