[pulseaudio-discuss] [PATCH] sink, source: Add a mode to avoid resampling if possible
Peter Meerwald-Stadler
pmeerw at pmeerw.net
Sat Jan 28 10:31:57 UTC 2017
> This adds an "avoid-resampling" option to daemon.conf that makes the
> daemon try to use the stream sample rate if possible (the device needs
> to support it, which currently only ALSA does), and there should not be
> any other stream connected).
>
> This should enable some of the "audiophile" use-cases where users wish
> to play high sample rate audio files without resampling.
comments below, picking on wording
> We still will do conversion, though which means that the 96/24 case will
> require that the default format be set to be 24-bit as well, this will
> force all streams to be upconverted, which other than the wasted
> resources should be relatively harmless.
> ---
> man/pulse-daemon.conf.5.xml.in | 9 +++++++++
> src/daemon/daemon-conf.c | 3 +++
> src/daemon/daemon-conf.h | 1 +
> src/daemon/daemon.conf.in | 1 +
> src/daemon/main.c | 1 +
> src/pulsecore/core.h | 1 +
> src/pulsecore/sink.c | 10 ++++++++--
> src/pulsecore/source.c | 10 ++++++++--
> 8 files changed, 32 insertions(+), 4 deletions(-)
>
> NOTE: I didn't want to editorialise the commit message itself, but if you're
> excited about this feature, please do make sure you understand Monty's
> excellent post on the subject of high sample rate audio at:
>
> http://people.xiph.org/~xiphmont/demo/neil-young.html
>
> diff --git a/man/pulse-daemon.conf.5.xml.in b/man/pulse-daemon.conf.5.xml.in
> index b81a549..cb09b97 100644
> --- a/man/pulse-daemon.conf.5.xml.in
> +++ b/man/pulse-daemon.conf.5.xml.in
> @@ -124,6 +124,15 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
> </option>
>
> <option>
> + <p><opt>avoid-resampling=</opt> If set, try to configure the
> + device to avoid resampling. This only works if on devices that
only works on devices
> + support reconfiguring their rate, and when no other streams are
> + already playing or capturing audio. The device will also not be
> + configured to a rate less than the default and alternate sample
> + rates.</p>
rate
> + </option>
> +
> + <option>
> <p><opt>enable-remixing=</opt> If disabled never upmix or
> downmix channels to different channel maps. Instead, do a simple
> name-based matching only. Defaults to <opt>yes.</opt></p>
> diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c
> index 31e4b14..9883126 100644
> --- a/src/daemon/daemon-conf.c
> +++ b/src/daemon/daemon-conf.c
> @@ -81,6 +81,7 @@ static const pa_daemon_conf default_conf = {
> .log_meta = false,
> .log_time = false,
> .resample_method = PA_RESAMPLER_AUTO,
> + .avoid_resampling = false,
> .disable_remixing = false,
> .remixing_use_all_sink_channels = true,
> .disable_lfe_remixing = true,
> @@ -553,6 +554,7 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
> { "deferred-volume-extra-delay-usec",
> pa_config_parse_int, &c->deferred_volume_extra_delay_usec, NULL },
> { "nice-level", parse_nice_level, c, NULL },
> + { "avoid-resampling", pa_config_parse_bool, &c->avoid_resampling, NULL },
> { "disable-remixing", pa_config_parse_bool, &c->disable_remixing, NULL },
> { "enable-remixing", pa_config_parse_not_bool, &c->disable_remixing, NULL },
> { "remixing-use-all-sink-channels",
> @@ -750,6 +752,7 @@ char *pa_daemon_conf_dump(pa_daemon_conf *c) {
> pa_strbuf_printf(s, "log-target = %s\n", pa_strempty(log_target));
> pa_strbuf_printf(s, "log-level = %s\n", log_level_to_string[c->log_level]);
> pa_strbuf_printf(s, "resample-method = %s\n", pa_resample_method_to_string(c->resample_method));
> + pa_strbuf_printf(s, "avoid-resampling = %s\n", pa_yes_no(!c->avoid_resampling));
> pa_strbuf_printf(s, "enable-remixing = %s\n", pa_yes_no(!c->disable_remixing));
> pa_strbuf_printf(s, "remixing-use-all-sink-channels = %s\n", pa_yes_no(c->remixing_use_all_sink_channels));
> pa_strbuf_printf(s, "enable-lfe-remixing = %s\n", pa_yes_no(!c->disable_lfe_remixing));
> diff --git a/src/daemon/daemon-conf.h b/src/daemon/daemon-conf.h
> index e61f67f..953ea33 100644
> --- a/src/daemon/daemon-conf.h
> +++ b/src/daemon/daemon-conf.h
> @@ -67,6 +67,7 @@ typedef struct pa_daemon_conf {
> no_cpu_limit,
> disable_shm,
> disable_memfd,
> + avoid_resampling,
> disable_remixing,
> remixing_use_all_sink_channels,
> disable_lfe_remixing,
> diff --git a/src/daemon/daemon.conf.in b/src/daemon/daemon.conf.in
> index 2d74afa..a955523 100644
> --- a/src/daemon/daemon.conf.in
> +++ b/src/daemon/daemon.conf.in
> @@ -54,6 +54,7 @@ ifelse(@HAVE_DBUS@, 1, [dnl
> ; log-backtrace = 0
>
> ; resample-method = speex-float-1
> +; avoid-resampling = false
> ; enable-remixing = yes
> ; remixing-use-all-sink-channels = yes
> ; enable-lfe-remixing = no
> diff --git a/src/daemon/main.c b/src/daemon/main.c
> index 280252a..f35252d 100644
> --- a/src/daemon/main.c
> +++ b/src/daemon/main.c
> @@ -1036,6 +1036,7 @@ int main(int argc, char *argv[]) {
> c->resample_method = conf->resample_method;
> c->realtime_priority = conf->realtime_priority;
> c->realtime_scheduling = conf->realtime_scheduling;
> + c->avoid_resampling = conf->avoid_resampling;
> c->disable_remixing = conf->disable_remixing;
> c->remixing_use_all_sink_channels = conf->remixing_use_all_sink_channels;
> c->disable_lfe_remixing = conf->disable_lfe_remixing;
> diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h
> index d2fe887..212f6f7 100644
> --- a/src/pulsecore/core.h
> +++ b/src/pulsecore/core.h
> @@ -199,6 +199,7 @@ struct pa_core {
> bool disallow_exit:1;
> bool running_as_daemon:1;
> bool realtime_scheduling:1;
> + bool avoid_resampling:1;
> bool disable_remixing:1;
> bool remixing_use_all_sink_channels:1;
> bool disable_lfe_remixing:1;
> diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
> index aa21822..370ea9b 100644
> --- a/src/pulsecore/sink.c
> +++ b/src/pulsecore/sink.c
> @@ -1414,6 +1414,7 @@ int pa_sink_update_rate(pa_sink *s, uint32_t rate, bool passthrough) {
> pa_sink_input *i;
> bool default_rate_is_usable = false;
> bool alternate_rate_is_usable = false;
> + bool avoid_resampling = s->core->avoid_resampling;
>
> if (rate == s->sample_spec.rate)
> return 0;
> @@ -1421,7 +1422,7 @@ int pa_sink_update_rate(pa_sink *s, uint32_t rate, bool passthrough) {
> if (!s->update_rate)
> return -1;
>
> - if (PA_UNLIKELY(default_rate == alternate_rate && !passthrough)) {
> + if (PA_UNLIKELY(default_rate == alternate_rate && !passthrough && !avoid_resampling)) {
> pa_log_debug("Default and alternate sample rates are the same, so there is no point in switching.");
> return -1;
> }
> @@ -1442,7 +1443,12 @@ int pa_sink_update_rate(pa_sink *s, uint32_t rate, bool passthrough) {
> if (PA_UNLIKELY(!pa_sample_rate_valid(desired_rate)))
> return -1;
>
> - if (!passthrough && default_rate != desired_rate && alternate_rate != desired_rate) {
> + if (avoid_resampling) {
> + /* We just try to set the sink input's sample rate if it's not too low */
> + if (rate > default_rate || rate > alternate_rate)
> + desired_rate = rate;
> +
> + } else if (!passthrough && default_rate != desired_rate && alternate_rate != desired_rate) {
> if (default_rate % 11025 == 0 && desired_rate % 11025 == 0)
> default_rate_is_usable = true;
> if (default_rate % 4000 == 0 && desired_rate % 4000 == 0)
> diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
> index 8ce7818..ba59929 100644
> --- a/src/pulsecore/source.c
> +++ b/src/pulsecore/source.c
> @@ -982,6 +982,7 @@ int pa_source_update_rate(pa_source *s, uint32_t rate, bool passthrough) {
> uint32_t alternate_rate = s->alternate_sample_rate;
> bool default_rate_is_usable = false;
> bool alternate_rate_is_usable = false;
> + bool avoid_resampling = s->core->avoid_resampling;
>
> if (rate == s->sample_spec.rate)
> return 0;
> @@ -989,7 +990,7 @@ int pa_source_update_rate(pa_source *s, uint32_t rate, bool passthrough) {
> if (!s->update_rate && !s->monitor_of)
> return -1;
>
> - if (PA_UNLIKELY(default_rate == alternate_rate && !passthrough)) {
> + if (PA_UNLIKELY(default_rate == alternate_rate && !passthrough && !avoid_resampling)) {
> pa_log_debug("Default and alternate sample rates are the same, so there is no point in switching.");
> return -1;
> }
> @@ -1010,7 +1011,12 @@ int pa_source_update_rate(pa_source *s, uint32_t rate, bool passthrough) {
> if (PA_UNLIKELY(!pa_sample_rate_valid(desired_rate)))
> return -1;
>
> - if (!passthrough && default_rate != desired_rate && alternate_rate != desired_rate) {
> + if (avoid_resampling) {
> + /* We just try to set the source output's sample rate if it's not too low */
> + if (rate > default_rate || rate > alternate_rate)
> + desired_rate = rate;
> +
> + } else if (!passthrough && default_rate != desired_rate && alternate_rate != desired_rate) {
> if (default_rate % 11025 == 0 && desired_rate % 11025 == 0)
> default_rate_is_usable = true;
> if (default_rate % 4000 == 0 && desired_rate % 4000 == 0)
> --
> 2.9.3
>
> _______________________________________________
> pulseaudio-discuss mailing list
> pulseaudio-discuss at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
>
--
Peter Meerwald-Stadler
+43-664-2444418 (mobile)
More information about the pulseaudio-discuss
mailing list