diff -Nur audacious-plugins-fedora-2.1-orig/src/alsa-ng/alsa-core.c audacious-plugins-fedora-2.1/src/alsa-ng/alsa-core.c --- audacious-plugins-fedora-2.1-orig/src/alsa-ng/alsa-core.c 2009-10-21 13:18:35.825170784 +0200 +++ audacious-plugins-fedora-2.1/src/alsa-ng/alsa-core.c 2009-10-26 12:19:30.561386114 +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; @@ -221,6 +225,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)); @@ -237,7 +244,7 @@ static gpointer alsaplug_loop(gpointer unused) { - guchar buf[2048]; + guchar buf[loopbufsize]; int size; while (pcm_going) @@ -247,6 +254,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; @@ -264,12 +272,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); @@ -336,9 +357,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) @@ -354,6 +376,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); @@ -365,18 +391,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; @@ -511,6 +544,7 @@ { g_mutex_lock (pcm_state_mutex); paused = p; + prefill = !paused; g_cond_broadcast (pcm_state_cond); g_mutex_unlock (pcm_state_mutex); }