]> git.alsa-project.org Git - alsa-plugins.git/commitdiff
pcm_pulse: set prebuf parameter according to software parameters
authorRémi Denis-Courmont <remi@remlab.net>
Sun, 18 Nov 2012 10:01:49 +0000 (12:01 +0200)
committerTakashi Iwai <tiwai@suse.de>
Tue, 20 Nov 2012 07:56:40 +0000 (08:56 +0100)
The current default value for prebuf is very high, almost the full
virtual ALSA buffer. This breaks some application especially where
low latency is involved.

This patch makes pcm_pulse implement the sw_params callback and get
the prebuf value from the ALSA software parameters. Thus the
trigger latency is much more like what an ALSA application should
expect from an ALSA PCM device.

Acked-by: David Henningsson <david.henningsson@canonical.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
pulse/pcm_pulse.c

index 24fd4dab06e32f2d70f71295b8bc8aedf1c1eb56..4226d30ec2a25b3438487b92af2ba5aed2a7a0ed 100644 (file)
@@ -854,8 +854,9 @@ static int pulse_hw_params(snd_pcm_ioplug_t * io,
                4 * 1024 * 1024;
        pcm->buffer_attr.tlength =
                io->buffer_size * pcm->frame_size;
-       pcm->buffer_attr.prebuf =
-           (io->buffer_size - io->period_size) * pcm->frame_size;
+       if (pcm->buffer_attr.prebuf == (uint32_t)-1)
+               pcm->buffer_attr.prebuf =
+                       (io->buffer_size - io->period_size) * pcm->frame_size;
        pcm->buffer_attr.minreq = io->period_size * pcm->frame_size;
        pcm->buffer_attr.fragsize = io->period_size * pcm->frame_size;
 
@@ -865,6 +866,31 @@ static int pulse_hw_params(snd_pcm_ioplug_t * io,
        return err;
 }
 
+static int pulse_sw_params(snd_pcm_ioplug_t *io, snd_pcm_sw_params_t *params)
+{
+       snd_pcm_pulse_t *pcm = io->private_data;
+       snd_pcm_uframes_t start_threshold;
+
+       assert(pcm);
+
+       if (!pcm->p || !pcm->p->mainloop)
+               return -EBADFD;
+
+       pa_threaded_mainloop_lock(pcm->p->mainloop);
+
+       snd_pcm_sw_params_get_start_threshold(params, &start_threshold);
+
+       /* At least one period to keep PulseAudio happy */
+       if (start_threshold < io->period_size)
+               start_threshold = io->period_size;
+
+       pcm->buffer_attr.prebuf = start_threshold * pcm->frame_size;
+
+       pa_threaded_mainloop_unlock(pcm->p->mainloop);
+
+       return 0;
+}
+
 static int pulse_close(snd_pcm_ioplug_t * io)
 {
        snd_pcm_pulse_t *pcm = io->private_data;
@@ -931,6 +957,7 @@ static const snd_pcm_ioplug_callback_t pulse_playback_callback = {
        .poll_revents = pulse_pcm_poll_revents,
        .prepare = pulse_prepare,
        .hw_params = pulse_hw_params,
+       .sw_params = pulse_sw_params,
        .close = pulse_close,
        .pause = pulse_pause
 };
@@ -1088,6 +1115,7 @@ SND_PCM_PLUGIN_DEFINE_FUNC(pulse)
        }
 
        pcm->handle_underrun = handle_underrun;
+       pcm->buffer_attr.prebuf = -1;
 
        err = pulse_connect(pcm->p, server, fallback_name != NULL);
        if (err < 0)