[pulseaudio-commits] 2 commits - man/pulse-daemon.conf.5.xml.in src/daemon src/pulsecore

Arun Raghavan arun at kemper.freedesktop.org
Mon Jan 30 08:39:17 UTC 2017


 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           |   30 ++++++++++++++++++++++--------
 src/pulsecore/source.c         |   30 ++++++++++++++++++++++--------
 8 files changed, 60 insertions(+), 16 deletions(-)

New commits:
commit 539371b3f722e92287f04f962160413e4efe1fa1
Author: Arun Raghavan <arun at arunraghavan.net>
Date:   Mon Jan 30 14:07:37 2017 +0530

    sink, source: Make rate selection more explicit
    
    This serves to explicitly document the various cases we deal with in
    pa_sink_update_rate()/pa_source_update_rate() rather than have some of
    them hidden behind the initialisation of desired_rate.

diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index 1a968f3..6011f45 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -1407,7 +1407,7 @@ void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) {
 /* Called from main thread */
 int pa_sink_update_rate(pa_sink *s, uint32_t rate, bool passthrough) {
     int ret = -1;
-    uint32_t desired_rate = rate;
+    uint32_t desired_rate;
     uint32_t default_rate = s->default_sample_rate;
     uint32_t alternate_rate = s->alternate_sample_rate;
     uint32_t idx;
@@ -1440,21 +1440,30 @@ int pa_sink_update_rate(pa_sink *s, uint32_t rate, bool passthrough) {
         }
     }
 
-    if (PA_UNLIKELY(!pa_sample_rate_valid(desired_rate)))
+    if (PA_UNLIKELY(!pa_sample_rate_valid(rate)))
         return -1;
 
-    if (avoid_resampling && (rate >= default_rate || rate >= alternate_rate)) {
+    if (passthrough) {
+        /* We have to try to use the sink input rate */
+        desired_rate = rate;
+
+    } else if (avoid_resampling && (rate >= default_rate || rate >= alternate_rate)) {
         /* We just try to set the sink input's sample rate if it's not too low */
         desired_rate = rate;
 
-    } else if (!passthrough && default_rate != desired_rate && alternate_rate != desired_rate) {
-        if (default_rate % 11025 == 0 && desired_rate % 11025 == 0)
+    } else if (default_rate == rate || alternate_rate == rate) {
+        /* We can directly try to use this rate */
+        desired_rate = rate;
+
+    } else {
+        /* See if we can pick a rate that results in less resampling effort */
+        if (default_rate % 11025 == 0 && rate % 11025 == 0)
             default_rate_is_usable = true;
-        if (default_rate % 4000 == 0 && desired_rate % 4000 == 0)
+        if (default_rate % 4000 == 0 && rate % 4000 == 0)
             default_rate_is_usable = true;
-        if (alternate_rate && alternate_rate % 11025 == 0 && desired_rate % 11025 == 0)
+        if (alternate_rate && alternate_rate % 11025 == 0 && rate % 11025 == 0)
             alternate_rate_is_usable = true;
-        if (alternate_rate && alternate_rate % 4000 == 0 && desired_rate % 4000 == 0)
+        if (alternate_rate && alternate_rate % 4000 == 0 && rate % 4000 == 0)
             alternate_rate_is_usable = true;
 
         if (alternate_rate_is_usable && !default_rate_is_usable)
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
index 72aae47..09c953f 100644
--- a/src/pulsecore/source.c
+++ b/src/pulsecore/source.c
@@ -977,7 +977,7 @@ void pa_source_post_direct(pa_source*s, pa_source_output *o, const pa_memchunk *
 /* Called from main thread */
 int pa_source_update_rate(pa_source *s, uint32_t rate, bool passthrough) {
     int ret;
-    uint32_t desired_rate = rate;
+    uint32_t desired_rate;
     uint32_t default_rate = s->default_sample_rate;
     uint32_t alternate_rate = s->alternate_sample_rate;
     bool default_rate_is_usable = false;
@@ -1008,21 +1008,30 @@ int pa_source_update_rate(pa_source *s, uint32_t rate, bool passthrough) {
         }
     }
 
-    if (PA_UNLIKELY(!pa_sample_rate_valid(desired_rate)))
+    if (PA_UNLIKELY(!pa_sample_rate_valid(rate)))
         return -1;
 
-    if (avoid_resampling && (rate >= default_rate || rate >= alternate_rate)) {
+    if (passthrough) {
+        /* We have to try to use the source output rate */
+        desired_rate = rate;
+
+    } else if (avoid_resampling && (rate >= default_rate || rate >= alternate_rate)) {
         /* We just try to set the source output's sample rate if it's not too low */
         desired_rate = rate;
 
-    } else if (!passthrough && default_rate != desired_rate && alternate_rate != desired_rate) {
-        if (default_rate % 11025 == 0 && desired_rate % 11025 == 0)
+    } else if (default_rate == rate || alternate_rate == rate) {
+        /* We can directly try to use this rate */
+        desired_rate = rate;
+
+    } else {
+        /* See if we can pick a rate that results in less resampling effort */
+        if (default_rate % 11025 == 0 && rate % 11025 == 0)
             default_rate_is_usable = true;
-        if (default_rate % 4000 == 0 && desired_rate % 4000 == 0)
+        if (default_rate % 4000 == 0 && rate % 4000 == 0)
             default_rate_is_usable = true;
-        if (alternate_rate && alternate_rate % 11025 == 0 && desired_rate % 11025 == 0)
+        if (alternate_rate && alternate_rate % 11025 == 0 && rate % 11025 == 0)
             alternate_rate_is_usable = true;
-        if (alternate_rate && alternate_rate % 4000 == 0 && desired_rate % 4000 == 0)
+        if (alternate_rate && alternate_rate % 4000 == 0 && rate % 4000 == 0)
             alternate_rate_is_usable = true;
 
         if (alternate_rate_is_usable && !default_rate_is_usable)

commit cc021c73305023a113f78190fb1b995528d003ae
Author: Arun Raghavan <arun at arunraghavan.net>
Date:   Sat Jan 28 13:19:08 2017 +0530

    sink, source: Add a mode to avoid resampling if possible
    
    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.
    
    We still will do conversion if sample formats don't match, though. This
    means that if you want to play 96 kHz/24 bit audio without any
    modification the default format will need to 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.

diff --git a/man/pulse-daemon.conf.5.xml.in b/man/pulse-daemon.conf.5.xml.in
index b81a549..f0550f3 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 on devices which
+      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>
+    </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..1a968f3 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,11 @@ 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 && (rate >= default_rate || rate >= alternate_rate)) {
+        /* We just try to set the sink input's sample rate if it's not too low */
+        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..72aae47 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,11 @@ 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 && (rate >= default_rate || rate >= alternate_rate)) {
+        /* We just try to set the source output's sample rate if it's not too low */
+        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)



More information about the pulseaudio-commits mailing list