alsa: New writer option: --buffer-time.
authorAndre Noll <maan@systemlinux.org>
Mon, 9 Sep 2013 03:53:32 +0000 (03:53 +0000)
committerAndre Noll <maan@systemlinux.org>
Sat, 8 Mar 2014 13:45:20 +0000 (14:45 +0100)
This removes the old way of setting of private_alsa_write_data->buffer_time

Currently we set the buffer time to the minimum of the maximum
buffer time and 500ms. This results in different values for different
hardware. In view of the introduction of the sync filter it seems to
be desirable to have more control over this value.

This patch adds the --buffer-time config option to the alsa
writer which allows to specify a suitable value, the default being
170ms. The unit of private_alsa_write_data->buffer_time is changed
from microseconds to milliseconds as this avoids to divide by 1000
in ->pre_select().

alsa_write.c
m4/gengetopt/alsa_write.m4

index 358b634..1c0b928 100644 (file)
@@ -50,7 +50,7 @@ struct private_alsa_write_data {
        snd_pcm_format_t sample_format;
        /* The number of channels, again determined like \a sample_rate. */
        unsigned channels;
-       /* time until buffer underrun occurs, in microseconds */
+       /* time until buffer underrun occurs, in milliseconds */
        unsigned buffer_time;
        struct timeval drain_barrier;
        /* File descriptor for select(). */
@@ -115,18 +115,15 @@ static int alsa_init(struct private_alsa_write_data *pad,
        if (ret < 0)
                goto fail;
        msg = "unable to get buffer time";
-       ret = snd_pcm_hw_params_get_buffer_time_max(hwparams, &pad->buffer_time,
-               NULL);
-       if (ret < 0 || pad->buffer_time == 0)
-               goto fail;
-       /* buffer at most 500 milliseconds */
-       pad->buffer_time = PARA_MIN(pad->buffer_time, 500U * 1000U);
+       /* alsa wants microseconds */
+       pad->buffer_time = conf->buffer_time_arg * 1000;
        msg = "could not set buffer time";
        ret = snd_pcm_hw_params_set_buffer_time_near(pad->handle, hwparams,
                &pad->buffer_time, NULL);
        if (ret < 0)
                goto fail;
-       period_time = pad->buffer_time / 4;
+       pad->buffer_time /= 1000; /* we prefer milliseconds */
+       period_time = pad->buffer_time * 250; /* buffer time / 4 */
        msg = "could not set period time";
        ret = snd_pcm_hw_params_set_period_time_near(pad->handle, hwparams,
                &period_time, 0);
@@ -223,7 +220,7 @@ static void alsa_write_pre_select(struct sched *s, struct task *t)
                return;
        }
        /* wait at most 50% of the buffer time */
-       sched_request_timeout_ms(pad->buffer_time / 2 / 1000, s);
+       sched_request_timeout_ms(pad->buffer_time / 2, s);
        ret = snd_pcm_poll_descriptors(pad->handle, &pfd, 1);
        if (ret < 0) {
                PARA_ERROR_LOG("could not get alsa poll fd: %s\n",
index 73d9805..bb4b061 100644 (file)
@@ -16,4 +16,21 @@ details = "
        ALSA is present in your kernel. The file /proc/asound/devices
        contains all devices ALSA knows about.
 "
+
+option "buffer-time" B
+#~~~~~~~~~~~~~~~~~~~~~
+"duration of the ALSA buffer"
+int typestr = "milliseconds"
+default = "170"
+optional
+details = "
+       This is only a hint as ALSA might pick a slightly different
+       time, depending on the sound hardware. The chosen value is
+       shown in debug output as BUFFER_TIME.
+
+       If synchronization between multiple clients is desired,
+       the same buffer time should be configured for all clients.
+"
+
 </qu>
+