From 480d69f921a23cfe62e05692cd646b8fce50d262 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Mon, 9 Sep 2013 03:53:32 +0000 Subject: [PATCH] alsa: New writer option: --buffer-time. 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 | 15 ++++++--------- m4/gengetopt/alsa_write.m4 | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/alsa_write.c b/alsa_write.c index 358b6346..1c0b9281 100644 --- a/alsa_write.c +++ b/alsa_write.c @@ -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", diff --git a/m4/gengetopt/alsa_write.m4 b/m4/gengetopt/alsa_write.m4 index 73d9805f..bb4b0619 100644 --- a/m4/gengetopt/alsa_write.m4 +++ b/m4/gengetopt/alsa_write.m4 @@ -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. +" + + -- 2.39.5