[pulseaudio-commits] 15 commits - configure.ac man/Makefile.am man/pacat.1.xml.in man/paplay.1.xml.in man/pulse-daemon.conf.5.xml.in man/pulseaudio.1.xml.in src/Makefile.am src/pulse src/pulsecore src/utils

David Henningsson diwic at kemper.freedesktop.org
Thu Feb 12 11:39:05 PST 2015


 configure.ac                   |   18 ++++
 man/Makefile.am                |   19 +++-
 man/pacat.1.xml.in             |   10 ++
 man/paplay.1.xml.in            |  125 ------------------------------
 man/pulse-daemon.conf.5.xml.in |   14 ++-
 man/pulseaudio.1.xml.in        |    4 
 src/Makefile.am                |    6 +
 src/pulse/context.c            |    5 +
 src/pulsecore/dynarray.c       |   51 ++++++++++++
 src/pulsecore/dynarray.h       |   25 ++++--
 src/pulsecore/resampler.c      |   33 +++++++-
 src/pulsecore/resampler.h      |    4 
 src/pulsecore/resampler/soxr.c |  167 +++++++++++++++++++++++++++++++++++++++++
 src/pulsecore/socket-server.c  |   23 ++---
 src/pulsecore/socket-server.h  |    1 
 src/pulsecore/tokenizer.c      |    3 
 src/utils/pacat.c              |   16 ++-
 17 files changed, 357 insertions(+), 167 deletions(-)

New commits:
commit 62dc0ad6c33ce2be6b36dcdfc0bfef21f7681960
Author: Andrey Semashev <andrey.semashev at gmail.com>
Date:   Wed Jan 14 22:22:04 2015 +0300

    Added documentation for soxr resampling methods.

diff --git a/man/pulse-daemon.conf.5.xml.in b/man/pulse-daemon.conf.5.xml.in
index d37de25..07be109 100644
--- a/man/pulse-daemon.conf.5.xml.in
+++ b/man/pulse-daemon.conf.5.xml.in
@@ -86,7 +86,8 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
       <opt>src-sinc-medium-quality</opt>, <opt>src-sinc-fastest</opt>,
       <opt>src-zero-order-hold</opt>, <opt>src-linear</opt>,
       <opt>trivial</opt>, <opt>speex-float-N</opt>,
-      <opt>speex-fixed-N</opt>, <opt>ffmpeg</opt>. See the
+      <opt>speex-fixed-N</opt>, <opt>ffmpeg</opt>, <opt>soxr-mq</opt>,
+      <opt>soxr-hq</opt>, <opt>soxr-vhq</opt>. See the
       documentation of libsamplerate and speex for explanations of the
       different src- and speex- methods, respectively. The method
       <opt>trivial</opt> is the most basic algorithm implemented. If
@@ -96,8 +97,15 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
       exist in two flavours: <opt>fixed</opt> and <opt>float</opt>. The former uses fixed point
       numbers, the latter relies on floating point numbers. On most
       desktop CPUs the float point resampler is a lot faster, and it
-      also offers slightly better quality. See the output of
-      <opt>dump-resample-methods</opt> for a complete list of all
+      also offers slightly better quality. The soxr-family methods
+      are based on libsoxr, a resampler library from the SoX sound processing utility.
+      The mq variant has the best performance of the three. The hq is more expensive
+      and, according to SoX developers, is considered the best choice for audio of up to 16 bits per sample.
+      The vhq variant has more precision than hq and is more suitable for larger samples. The Soxr resamplers
+      generally offer better quality at less CPU compared to other resamplers, such as speex.
+      The downside is that they can add a significant delay to the output
+      (usually up to around 20 ms, in rare cases more).
+      See the output of <opt>dump-resample-methods</opt> for a complete list of all
       available resamplers. Defaults to <opt>speex-float-1</opt>. The
       <opt>--resample-method</opt> command line option takes precedence.
       Note that some modules overwrite or allow overwriting of the

commit 6ea00eeb07a59c33cabc2b8011e5e2bea49d4050
Author: Andrey Semashev <andrey.semashev at gmail.com>
Date:   Wed Jan 14 22:22:03 2015 +0300

    Added libsoxr detection and optional build of soxr resampler backend.

diff --git a/configure.ac b/configure.ac
index 6a80167..b2fcd1e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1139,6 +1139,21 @@ AS_IF([test "x$with_speex" = "xyes" && test "x$HAVE_SPEEX" = "x0"],
 AM_CONDITIONAL([HAVE_SPEEX], [test "x$HAVE_SPEEX" = "x1"])
 AS_IF([test "x$HAVE_SPEEX" = "x1"], AC_DEFINE([HAVE_SPEEX], 1, [Have speex]))
 
+#### soxr (optional) ####
+
+AC_ARG_WITH([soxr],
+    AS_HELP_STRING([--without-soxr],[Omit soxr (resampling)]))
+
+AS_IF([test "x$with_soxr" != "xno"],
+    [PKG_CHECK_MODULES(LIBSOXR, [ soxr >= 0.1.1 ], HAVE_SOXR=1, HAVE_SOXR=0)],
+    HAVE_SOXR=0)
+
+AS_IF([test "x$with_soxr" = "xyes" && test "x$HAVE_SOXR" = "x0"],
+    [AC_MSG_ERROR([*** soxr support not found])])
+
+AM_CONDITIONAL([HAVE_SOXR], [test "x$HAVE_SOXR" = "x1"])
+AS_IF([test "x$HAVE_SOXR" = "x1"], AC_DEFINE([HAVE_SOXR], 1, [Have soxr]))
+
 #### Xen support (optional) ####
 
 AC_ARG_ENABLE([xen],
@@ -1526,6 +1541,7 @@ AS_IF([test "x$HAVE_FFTW" = "x1"], ENABLE_FFTW=yes, ENABLE_FFTW=no)
 AS_IF([test "x$HAVE_ORC" = "xyes"], ENABLE_ORC=yes, ENABLE_ORC=no)
 AS_IF([test "x$HAVE_ADRIAN_EC" = "x1"], ENABLE_ADRIAN_EC=yes, ENABLE_ADRIAN_EC=no)
 AS_IF([test "x$HAVE_SPEEX" = "x1"], ENABLE_SPEEX=yes, ENABLE_SPEEX=no)
+AS_IF([test "x$HAVE_SOXR" = "x1"], ENABLE_SOXR=yes, ENABLE_SOXR=no)
 AS_IF([test "x$HAVE_WEBRTC" = "x1"], ENABLE_WEBRTC=yes, ENABLE_WEBRTC=no)
 AS_IF([test "x$HAVE_TDB" = "x1"], ENABLE_TDB=yes, ENABLE_TDB=no)
 AS_IF([test "x$HAVE_GDBM" = "x1"], ENABLE_GDBM=yes, ENABLE_GDBM=no)
@@ -1587,6 +1603,7 @@ echo "
     Enable orc:                    ${ENABLE_ORC}
     Enable Adrian echo canceller:  ${ENABLE_ADRIAN_EC}
     Enable speex (resampler, AEC): ${ENABLE_SPEEX}
+    Enable soxr (resampler):       ${ENABLE_SOXR}
     Enable WebRTC echo canceller:  ${ENABLE_WEBRTC}
     Enable gcov coverage:          ${ENABLE_GCOV}
     Enable unit tests:             ${ENABLE_TESTS}
diff --git a/src/Makefile.am b/src/Makefile.am
index 5cb5564..67f8627 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1019,6 +1019,12 @@ libpulsecore_ at PA_MAJORMINOR@_la_CFLAGS += $(LIBSPEEX_CFLAGS)
 libpulsecore_ at PA_MAJORMINOR@_la_LIBADD += $(LIBSPEEX_LIBS)
 endif
 
+if HAVE_SOXR
+libpulsecore_ at PA_MAJORMINOR@_la_SOURCES += pulsecore/resampler/soxr.c
+libpulsecore_ at PA_MAJORMINOR@_la_CFLAGS += $(LIBSOXR_CFLAGS)
+libpulsecore_ at PA_MAJORMINOR@_la_LIBADD += $(LIBSOXR_LIBS)
+endif
+
 if HAVE_LIBSAMPLERATE
 libpulsecore_ at PA_MAJORMINOR@_la_SOURCES += pulsecore/resampler/libsamplerate.c
 libpulsecore_ at PA_MAJORMINOR@_la_CFLAGS += $(LIBSAMPLERATE_CFLAGS)

commit e257fd51f60ea66b7e7b02b681c1b89d12a9a9fd
Author: Andrey Semashev <andrey.semashev at gmail.com>
Date:   Wed Jan 14 22:22:02 2015 +0300

    Enabled libsoxr resampler backend.
    
    Added ID and names for the resampler presets and also updated the working sample rate deduction to take the new resampler into account. The initial libsoxr backend version does not variable rate resampling, so it is disabled in this case.

diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c
index b4e84f2..0d7cc20 100644
--- a/src/pulsecore/resampler.c
+++ b/src/pulsecore/resampler.c
@@ -109,6 +109,15 @@ static int (* const init_table[])(pa_resampler *r) = {
     [PA_RESAMPLER_AUTO]                    = NULL,
     [PA_RESAMPLER_COPY]                    = copy_init,
     [PA_RESAMPLER_PEAKS]                   = pa_resampler_peaks_init,
+#ifdef HAVE_SOXR
+    [PA_RESAMPLER_SOXR_MQ]                 = pa_resampler_soxr_init,
+    [PA_RESAMPLER_SOXR_HQ]                 = pa_resampler_soxr_init,
+    [PA_RESAMPLER_SOXR_VHQ]                = pa_resampler_soxr_init,
+#else
+    [PA_RESAMPLER_SOXR_MQ]                 = NULL,
+    [PA_RESAMPLER_SOXR_HQ]                 = NULL,
+    [PA_RESAMPLER_SOXR_VHQ]                = NULL,
+#endif
 };
 
 static pa_resample_method_t choose_auto_resampler(pa_resample_flags_t flags) {
@@ -154,6 +163,9 @@ static pa_resample_method_t fix_method(
             }
                                      /* Else fall through */
         case PA_RESAMPLER_FFMPEG:
+        case PA_RESAMPLER_SOXR_MQ:
+        case PA_RESAMPLER_SOXR_HQ:
+        case PA_RESAMPLER_SOXR_VHQ:
             if (flags & PA_RESAMPLER_VARIABLE_RATE) {
                 pa_log_info("Resampler '%s' cannot do variable rate, reverting to resampler 'auto'.", pa_resample_method_to_string(method));
                 method = PA_RESAMPLER_AUTO;
@@ -276,10 +288,20 @@ static pa_sample_format_t choose_work_format(
             }
                                                 /* Else fall trough */
         case PA_RESAMPLER_PEAKS:
-            if (a == PA_SAMPLE_S16NE || b == PA_SAMPLE_S16NE)
+            /* PEAKS, COPY and TRIVIAL do not benefit from increased
+             * working precision, so for better performance use s16ne
+             * if either input or output fits in it. */
+            if (a == PA_SAMPLE_S16NE || b == PA_SAMPLE_S16NE) {
                 work_format = PA_SAMPLE_S16NE;
-            else if (sample_format_more_precise(a, PA_SAMPLE_S16NE) ||
-                     sample_format_more_precise(b, PA_SAMPLE_S16NE))
+                break;
+            }
+                                                /* Else fall trough */
+        case PA_RESAMPLER_SOXR_MQ:
+        case PA_RESAMPLER_SOXR_HQ:
+        case PA_RESAMPLER_SOXR_VHQ:
+            /* Do processing with max precision of input and output. */
+            if (sample_format_more_precise(a, PA_SAMPLE_S16NE) ||
+                sample_format_more_precise(b, PA_SAMPLE_S16NE))
                 work_format = PA_SAMPLE_FLOAT32NE;
             else
                 work_format = PA_SAMPLE_S16NE;
@@ -599,7 +621,10 @@ static const char * const resample_methods[] = {
     "ffmpeg",
     "auto",
     "copy",
-    "peaks"
+    "peaks",
+    "soxr-mq",
+    "soxr-hq",
+    "soxr-vhq"
 };
 
 const char *pa_resample_method_to_string(pa_resample_method_t m) {
diff --git a/src/pulsecore/resampler.h b/src/pulsecore/resampler.h
index 0580f85..4840a5e 100644
--- a/src/pulsecore/resampler.h
+++ b/src/pulsecore/resampler.h
@@ -57,6 +57,9 @@ typedef enum pa_resample_method {
     PA_RESAMPLER_AUTO, /* automatic select based on sample format */
     PA_RESAMPLER_COPY,
     PA_RESAMPLER_PEAKS,
+    PA_RESAMPLER_SOXR_MQ,
+    PA_RESAMPLER_SOXR_HQ,
+    PA_RESAMPLER_SOXR_VHQ,
     PA_RESAMPLER_MAX
 } pa_resample_method_t;
 
@@ -161,6 +164,7 @@ int pa_resampler_libsamplerate_init(pa_resampler *r);
 int pa_resampler_peaks_init(pa_resampler *r);
 int pa_resampler_speex_init(pa_resampler *r);
 int pa_resampler_trivial_init(pa_resampler*r);
+int pa_resampler_soxr_init(pa_resampler *r);
 
 /* Resampler-specific quirks */
 bool pa_speex_is_fixed_point(void);

commit 1335dcfbb241f8950449093c94dd9877af479d1f
Author: Andrey Semashev <andrey.semashev at gmail.com>
Date:   Wed Jan 14 22:22:01 2015 +0300

    Added libsoxr resampler backend.
    
    The new backend supports 3 quality levels: mq, hq and vhq; 16-bit integer and 32-bit float samples. Discussion and quality assessment are here:
    
    http://comments.gmane.org/gmane.comp.audio.pulseaudio.general/22158

diff --git a/src/pulsecore/resampler/soxr.c b/src/pulsecore/resampler/soxr.c
new file mode 100644
index 0000000..b5f0007
--- /dev/null
+++ b/src/pulsecore/resampler/soxr.c
@@ -0,0 +1,167 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2014, 2015 Andrey Semashev
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.1 of the License,
+  or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stddef.h>
+#include <soxr.h>
+
+#include <pulsecore/resampler.h>
+
+static unsigned resampler_soxr_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames,
+                                        pa_memchunk *output, unsigned *out_n_frames) {
+    soxr_t state;
+    void *in, *out;
+    size_t consumed = 0, produced = 0;
+
+    pa_assert(r);
+    pa_assert(input);
+    pa_assert(output);
+    pa_assert(out_n_frames);
+
+    state = r->impl.data;
+    pa_assert(state);
+
+    in = pa_memblock_acquire_chunk(input);
+    out = pa_memblock_acquire_chunk(output);
+
+    pa_assert_se(soxr_process(state, in, in_n_frames, &consumed, out, *out_n_frames, &produced) == 0);
+
+    pa_memblock_release(input->memblock);
+    pa_memblock_release(output->memblock);
+
+    *out_n_frames = produced;
+
+    return in_n_frames - consumed;
+}
+
+static void resampler_soxr_free(pa_resampler *r) {
+    pa_assert(r);
+
+    if (!r->impl.data)
+        return;
+
+    soxr_delete(r->impl.data);
+    r->impl.data = NULL;
+}
+
+static void resampler_soxr_reset(pa_resampler *r) {
+    soxr_t old_state;
+
+    pa_assert(r);
+
+    /*
+     * soxr_clear() makes soxr_process() crash afterwards,
+     * so don't use this function until libsoxr is fixed.
+     *
+     * soxr_clear(r->impl.data);
+     */
+
+    old_state = r->impl.data;
+    r->impl.data = NULL;
+
+    if (pa_resampler_soxr_init(r) == 0) {
+        if (old_state)
+            soxr_delete(old_state);
+    } else {
+        r->impl.data = old_state;
+        pa_log_error("Failed to reset libsoxr context");
+    }
+}
+
+static void resampler_soxr_update_rates(pa_resampler *r) {
+    soxr_t old_state;
+
+    pa_assert(r);
+
+    /* There is no update method in libsoxr,
+     * so just re-create the resampler context */
+
+    old_state = r->impl.data;
+    r->impl.data = NULL;
+
+    if (pa_resampler_soxr_init(r) == 0) {
+        if (old_state)
+            soxr_delete(old_state);
+    } else {
+        r->impl.data = old_state;
+        pa_log_error("Failed to update libsoxr sample rates");
+    }
+}
+
+int pa_resampler_soxr_init(pa_resampler *r) {
+    soxr_t state;
+    soxr_datatype_t io_format;
+    soxr_io_spec_t io_spec;
+    soxr_runtime_spec_t runtime_spec;
+    unsigned long quality_recipe;
+    soxr_quality_spec_t quality;
+    soxr_error_t err = NULL;
+
+    pa_assert(r);
+
+    switch (r->work_format) {
+        case PA_SAMPLE_S16NE:
+            io_format = SOXR_INT16_I;
+            break;
+        case PA_SAMPLE_FLOAT32NE:
+            io_format = SOXR_FLOAT32_I;
+            break;
+        default:
+            pa_assert_not_reached();
+    }
+
+    io_spec = soxr_io_spec(io_format, io_format);
+
+    /* Resample in one thread. Multithreading makes
+     * performance worse with small chunks of audio. */
+    runtime_spec = soxr_runtime_spec(1);
+
+    switch (r->method) {
+        case PA_RESAMPLER_SOXR_MQ:
+            quality_recipe = SOXR_MQ | SOXR_LINEAR_PHASE;
+            break;
+        case PA_RESAMPLER_SOXR_HQ:
+            quality_recipe = SOXR_HQ | SOXR_LINEAR_PHASE;
+            break;
+        case PA_RESAMPLER_SOXR_VHQ:
+            quality_recipe = SOXR_VHQ | SOXR_LINEAR_PHASE;
+            break;
+        default:
+            pa_assert_not_reached();
+    }
+
+    quality = soxr_quality_spec(quality_recipe, 0);
+
+    state = soxr_create(r->i_ss.rate, r->o_ss.rate, r->work_channels, &err, &io_spec, &quality, &runtime_spec);
+    if (!state) {
+        pa_log_error("Failed to create libsoxr resampler context: %s.", (err ? err : "[unknown error]"));
+        return -1;
+    }
+
+    r->impl.free = resampler_soxr_free;
+    r->impl.reset = resampler_soxr_reset;
+    r->impl.update_rates = resampler_soxr_update_rates;
+    r->impl.resample = resampler_soxr_resample;
+    r->impl.data = state;
+
+    return 0;
+}

commit 8a08e7e38a9400314da0ae74aea4f4375a5ab56f
Author: Peter Meerwald <p.meerwald at bct-electronic.com>
Date:   Mon Nov 17 11:34:59 2014 +0100

    pacat: State purpose of program depending how it was invoked
    
    see https://bugs.freedesktop.org/show_bug.cgi?id=68135
    
    state purpose of paplay/parec/pamon/parecord/pacat when invoked with -h
    
    Signed-off-by: Peter Meerwald <pmeerw at pmeerw.net>

diff --git a/src/utils/pacat.c b/src/utils/pacat.c
index 1db88fb..a6a4ce9 100644
--- a/src/utils/pacat.c
+++ b/src/utils/pacat.c
@@ -50,6 +50,7 @@
 #define CLEAR_LINE "\x1B[K"
 
 static enum { RECORD, PLAYBACK } mode = PLAYBACK;
+static const char *purpose = NULL;
 
 static pa_context *context = NULL;
 static pa_stream *stream = NULL;
@@ -667,7 +668,8 @@ static void time_event_callback(pa_mainloop_api *m, pa_time_event *e, const stru
 
 static void help(const char *argv0) {
 
-    printf(_("%s [options]\n\n"
+    printf(_("%s [options]\n"
+             "%s\n\n"
              "  -h, --help                            Show this help\n"
              "      --version                         Show version\n\n"
              "  -r, --record                          Create a connection for recording\n"
@@ -703,7 +705,7 @@ static void help(const char *argv0) {
              "      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
              "      --list-file-formats               List available file formats.\n"
              "      --monitor-stream=INDEX            Record from the sink input with index INDEX.\n")
-           , argv0);
+           , argv0, purpose);
 }
 
 enum {
@@ -783,15 +785,19 @@ int main(int argc, char *argv[]) {
     if (strstr(bn, "play")) {
         mode = PLAYBACK;
         raw = false;
+        purpose = _("Play back encoded audio files on a PulseAudio sound server.");
     } else if (strstr(bn, "record")) {
         mode = RECORD;
         raw = false;
-    } else if (strstr(bn, "cat")) {
-        mode = PLAYBACK;
-        raw = true;
+        purpose = _("Capture audio data from a PulseAudio sound server and write it to a file.");
     } else if (strstr(bn, "rec") || strstr(bn, "mon")) {
         mode = RECORD;
         raw = true;
+        purpose = _("Capture audio data from a PulseAudio sound server and write it to STDOUT or the specified file.");
+    } else { /* pacat */
+        mode = PLAYBACK;
+        raw = true;
+        purpose = _("Play back audio data from STDIN or the specified file on a PulseAudio sound server.");
     }
 
     proplist = pa_proplist_new();

commit 0f54a91718f46462c44cc58e9eadeefccbc142f2
Author: Peter Meerwald <p.meerwald at bct-electronic.com>
Date:   Mon Nov 17 11:02:25 2014 +0100

    man: Install man page symlinks to pacat for paplay, parec, parecord, pamon
    
    see https://bugs.freedesktop.org/show_bug.cgi?id=68135
    
    Signed-off-by: Peter Meerwald <pmeerw at pmeerw.net>

diff --git a/man/Makefile.am b/man/Makefile.am
index bead05c..d4f4edb 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -59,6 +59,22 @@ CLEANFILES = \
 %: %.xml Makefile
 	$(AM_V_GEN) perl $(srcdir)/xmltoman $< > $@ || rm -f $@
 
+if OS_IS_WIN32
+SYMLINK_PROGRAM=cd $(DESTDIR)$(man1dir) && cp
+else
+SYMLINK_PROGRAM=ln -sf
+endif
+install-data-hook:
+	$(SYMLINK_PROGRAM) pacat.1 $(DESTDIR)$(man1dir)/paplay.1
+	$(SYMLINK_PROGRAM) pacat.1 $(DESTDIR)$(man1dir)/parec.1
+	$(SYMLINK_PROGRAM) pacat.1 $(DESTDIR)$(man1dir)/parecord.1
+	$(SYMLINK_PROGRAM) pacat.1 $(DESTDIR)$(man1dir)/pamon.1
+
+uninstall-hook:
+	rm -f $(DESTDIR)$(man1dir)/paplay.1
+	rm -f $(DESTDIR)$(man1dir)/parec.1
+	rm -f $(DESTDIR)$(man1dir)/parecord.1
+	rm -f $(DESTDIR)$(man1dir)/pamon.1
 endif
 
 EXTRA_DIST = \

commit fd263f048b44ad7fb2c65ea435ab4182f63b4021
Author: Peter Meerwald <p.meerwald at bct-electronic.com>
Date:   Mon Nov 17 10:44:31 2014 +0100

    man: Drop separate paplay man page, move info to pacat man page
    
    see https://bugs.freedesktop.org/show_bug.cgi?id=68135
    
    pacat and paplay man pages both claim to describe the paplay program
    (which is actually a symlink to pacat) -- this is inconsistent and
    redundant, so drop the paplay man page
    
    a follow-up patch will add man page symlink for all programs
    implemented by pacat, not just paplay
    
    Signed-off-by: Peter Meerwald <pmeerw at pmeerw.net>

diff --git a/configure.ac b/configure.ac
index 3c71472..6a80167 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1453,7 +1453,6 @@ po/Makefile.in
 man/pulseaudio.1.xml
 man/esdcompat.1.xml
 man/pax11publish.1.xml
-man/paplay.1.xml
 man/pacat.1.xml
 man/pacmd.1.xml
 man/pactl.1.xml
diff --git a/man/Makefile.am b/man/Makefile.am
index 5ba4e68..bead05c 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -20,7 +20,6 @@ noinst_DATA = \
 	pulseaudio.1.xml \
 	esdcompat.1.xml \
 	pax11publish.1.xml \
-	paplay.1.xml \
 	pacat.1.xml \
 	pacmd.1.xml \
 	pactl.1.xml \
@@ -43,7 +42,6 @@ dist_man_MANS = \
 	pulseaudio.1 \
 	esdcompat.1 \
 	pax11publish.1 \
-	paplay.1 \
 	pacat.1 \
 	pacmd.1 \
 	pactl.1 \
@@ -67,7 +65,6 @@ EXTRA_DIST = \
 	pulseaudio.1.xml.in \
 	esdcompat.1.xml.in \
 	pax11publish.1.xml.in \
-	paplay.1.xml.in \
 	pacat.1.xml.in \
 	pacmd.1.xml.in \
 	pactl.1.xml.in \
diff --git a/man/pacat.1.xml.in b/man/pacat.1.xml.in
index ba213ff..fb63e93 100644
--- a/man/pacat.1.xml.in
+++ b/man/pacat.1.xml.in
@@ -34,7 +34,8 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
   <description>
     <p><file>pacat</file> is a simple tool for playing back or
     capturing raw or encoded audio files on a PulseAudio sound
-    server.</p>
+    server. It understands all audio file formats supported by
+    <file>libsndfile</file>.</p>
   </description>
 
   <options>
@@ -242,6 +243,13 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
 
   </options>
 
+  <section name="Limitations">
+    <p>Due to a limitation in <file>libsndfile</file>
+    <file>paplay</file> currently does not always set the correct channel
+    mapping for playback of multichannel (i.e. surround) audio files, even
+    if the channel mapping information is available in the audio file.</p>
+  </section>
+
   <section name="Authors">
     <p>The PulseAudio Developers <@PACKAGE_BUGREPORT@>; PulseAudio is available from <url href="@PACKAGE_URL@"/></p>
   </section>
diff --git a/man/paplay.1.xml.in b/man/paplay.1.xml.in
deleted file mode 100644
index a459cfd..0000000
--- a/man/paplay.1.xml.in
+++ /dev/null
@@ -1,125 +0,0 @@
-<?xml version="1.0"?><!--*-nxml-*-->
-<!DOCTYPE manpage SYSTEM "xmltoman.dtd">
-<?xml-stylesheet type="text/xsl" href="xmltoman.xsl" ?>
-
-<!--
-This file is part of PulseAudio.
-
-PulseAudio is free software; you can redistribute it and/or modify it
-under the terms of the GNU Lesser General Public License as
-published by the Free Software Foundation; either version 2.1 of the
-License, or (at your option) any later version.
-
-PulseAudio is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
-Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
--->
-
-<manpage name="paplay" section="1" desc="Play back audio files on a PulseAudio sound server">
-
-  <synopsis>
-    <cmd>paplay [<arg>options</arg>] <arg>FILE</arg></cmd>
-    <cmd>paplay <opt>--help</opt></cmd>
-    <cmd>paplay <opt>--version</opt></cmd>
-  </synopsis>
-
-  <description>
-    <p><file>paplay</file> is a simple tool for playing back audio
-    files on a PulseAudio sound server. It understands all audio file
-    formats supported by <file>libsndfile</file>.</p>
-  </description>
-
-  <options>
-
-    <option>
-      <p><opt>-h | --help</opt></p>
-
-      <optdesc><p>Show help.</p></optdesc>
-    </option>
-
-    <option>
-      <p><opt>--version</opt></p>
-
-      <optdesc><p>Show version information.</p></optdesc>
-    </option>
-
-    <option>
-      <p><opt>-v | --verbose</opt></p>
-
-      <optdesc><p>Enable verbose operation. Dumps the current playback time to STDERR during playback.</p></optdesc>
-    </option>
-
-    <option>
-      <p><opt>-s | --server</opt><arg>=SERVER</arg></p>
-
-      <optdesc><p>Choose the server to connect to.</p></optdesc>
-    </option>
-
-    <option>
-      <p><opt>-d | --device</opt><arg>=SINK</arg></p>
-
-      <optdesc><p>Specify the symbolic name of the sink to play this file on.</p></optdesc>
-    </option>
-
-    <option>
-      <p><opt>-n | --client-name</opt><arg>=NAME</arg></p>
-
-      <optdesc><p>Specify the client name <file>paplay</file> shall pass to the server when connecting.</p></optdesc>
-    </option>
-
-    <option>
-      <p><opt>--stream-name</opt><arg>=NAME</arg></p>
-
-      <optdesc><p>Specify the stream name <file>paplay</file> shall pass to the server when creating the stream.</p></optdesc>
-    </option>
-
-    <option>
-      <p><opt>--volume</opt><arg>=VOLUME</arg></p>
-
-      <optdesc><p>Specify the initial playback volume to use. Choose a value between 0 (silent) and 65536 (100% volume).</p></optdesc>
-    </option>
-
-    <option>
-      <p><opt>--channel-map</opt><arg>=CHANNELMAP</arg></p>
-
-      <optdesc><p>Explicitly choose a channel map when playing back
-      this stream. The argument should be a comma separated list of
-      channel names: <arg>front-left</arg>, <arg>front-right</arg>,
-      <arg>mono</arg>, <arg>front-center</arg>, <arg>rear-left</arg>,
-      <arg>rear-right</arg>, <arg>rear-center</arg>, <arg>lfe</arg>,
-      <arg>front-left-of-center</arg>,
-      <arg>front-right-of-center</arg>, <arg>side-left</arg>,
-      <arg>side-right</arg>, <arg>top-center</arg>,
-      <arg>top-front-center</arg>, <arg>top-front-left</arg>,
-      <arg>top-front-right</arg>, <arg>top-rear-left</arg>,
-      <arg>top-rear-right</arg>, <arg>top-rear-center</arg>, or any of
-      the 32 auxiliary channel names <arg>aux0</arg> to
-      <arg>aux31</arg>.</p></optdesc>
-    </option>
-
-  </options>
-
-  <section name="Limitations">
-
-    <p>Due to a limitation in <file>libsndfile</file>
-    <file>paplay</file> currently does not always set the correct channel
-    mapping for playback of multichannel (i.e. surround) audio files, even if the channel mapping information is
-    available in the audio file.</p>
-
-  </section>
-
-  <section name="Authors">
-    <p>The PulseAudio Developers <@PACKAGE_BUGREPORT@>; PulseAudio is available from <url href="@PACKAGE_URL@"/></p>
-  </section>
-
-  <section name="See also">
-    <p>
-      <manref name="pulseaudio" section="1"/>, <manref name="pacat" section="1"/>
-    </p>
-  </section>
-
-</manpage>

commit a95a9d05e5816968da9e930c49d233a25540cab0
Author: Peter Meerwald <pmeerw at pmeerw.net>
Date:   Sat Nov 15 16:06:22 2014 +0100

    man: Describe optional prefix {string} in server address
    
    see https://bugs.freedesktop.org/show_bug.cgi?id=84024
    
    v2: (thanks Tanu Kaskinen)
    * fix wording wrt machine id
    
    Signed-off-by: Peter Meerwald <pmeerw at pmeerw.net>

diff --git a/man/pulseaudio.1.xml.in b/man/pulseaudio.1.xml.in
index aed21f6..0d278b7 100644
--- a/man/pulseaudio.1.xml.in
+++ b/man/pulseaudio.1.xml.in
@@ -457,7 +457,9 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
     server addresses separated by whitespace which are tried in turn. A server
     address consists of an optional address type specifier (unix:, tcp:, tcp4:,
     tcp6:), followed by a path or host address. A host address may include an
-    optional port number.</p>
+    optional port number. A server address may be prefixed by a string enclosed
+    in {}. In this case the following server address is ignored unless the prefix
+    string equals the local hostname or the machine id (/etc/machine-id).</p>
 
     <p><arg>$PULSE_SINK</arg>: the symbolic name of the sink to connect to when a client creates a playback stream and doesn't explicitly ask for a specific sink.</p>
 

commit 75355690b01852650d7ebfbd73281ec66bf4475f
Author: Peter Meerwald <pmeerw at pmeerw.net>
Date:   Sat Nov 15 15:24:22 2014 +0100

    context: pa_context_connect() with PA_CONTEXT_NOFAIL should return 0 when waiting for PA on D-Dus
    
    see
    https://bugs.freedesktop.org/show_bug.cgi?id=85011
    
    in case NOAUTOSPAWN is set and no server has been specified, PA starts listening on DBUS
    for a new server, and the state is PA_CONTEXT_CONNECTING, but pa_context_connect()
    returns -1; it should return 0.
    
    Signed-off-by: Peter Meerwald <pmeerw at pmeerw.net>

diff --git a/src/pulse/context.c b/src/pulse/context.c
index 4bc445f..30d3eab 100644
--- a/src/pulse/context.c
+++ b/src/pulse/context.c
@@ -814,6 +814,11 @@ static int try_next_connection(pa_context *c) {
                     track_pulseaudio_on_dbus(c, DBUS_BUS_SESSION, &c->session_bus);
                 if (!c->system_bus)
                     track_pulseaudio_on_dbus(c, DBUS_BUS_SYSTEM, &c->system_bus);
+
+                if (c->session_bus || c->system_bus) {
+                    pa_log_debug("Waiting for PA on D-Bus...");
+                    break;
+                }
             } else
 #endif
                 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);

commit 360cb6550e6558606091ac8c64028ed9872ba6f9
Author: Tanu Kaskinen <tanu.kaskinen at linux.intel.com>
Date:   Wed Jan 7 16:56:50 2015 +0200

    dynarray: Add PA_DYNARRAY_FOREACH
    
    The PA_DYNARRAY_FOREACH macro requires that pa_dynarray_get() returns
    NULL if the index is out of bounds.

diff --git a/src/pulsecore/dynarray.c b/src/pulsecore/dynarray.c
index e9776fa..6a3eb5f 100644
--- a/src/pulsecore/dynarray.c
+++ b/src/pulsecore/dynarray.c
@@ -72,7 +72,9 @@ void pa_dynarray_append(pa_dynarray *array, void *p) {
 
 void *pa_dynarray_get(pa_dynarray *array, unsigned i) {
     pa_assert(array);
-    pa_assert(i < array->n_entries);
+
+    if (i >= array->n_entries)
+        return NULL;
 
     return array->data[i];
 }
diff --git a/src/pulsecore/dynarray.h b/src/pulsecore/dynarray.h
index 1c0e79f..0b05880 100644
--- a/src/pulsecore/dynarray.h
+++ b/src/pulsecore/dynarray.h
@@ -43,6 +43,8 @@ pa_dynarray* pa_dynarray_new(pa_free_cb_t free_cb);
 void pa_dynarray_free(pa_dynarray *array);
 
 void pa_dynarray_append(pa_dynarray *array, void *p);
+
+/* Returns the element at index i, or NULL if i is out of bounds. */
 void *pa_dynarray_get(pa_dynarray *array, unsigned i);
 
 /* Returns the last element, or NULL if the array is empty. */
@@ -61,4 +63,7 @@ void *pa_dynarray_steal_last(pa_dynarray *array);
 
 unsigned pa_dynarray_size(pa_dynarray *array);
 
+#define PA_DYNARRAY_FOREACH(elem, array, idx) \
+    for ((idx) = 0; ((elem) = pa_dynarray_get(array, idx)); (idx)++)
+
 #endif
diff --git a/src/pulsecore/tokenizer.c b/src/pulsecore/tokenizer.c
index d889fe6..e81dd6b 100644
--- a/src/pulsecore/tokenizer.c
+++ b/src/pulsecore/tokenizer.c
@@ -78,8 +78,5 @@ const char *pa_tokenizer_get(pa_tokenizer *t, unsigned i) {
 
     pa_assert(a);
 
-    if (i >= pa_dynarray_size(a))
-        return NULL;
-
     return pa_dynarray_get(a, i);
 }

commit 7d3879c07fe1cca778fbdc91eb1bdac9fba1137a
Author: Tanu Kaskinen <tanu.kaskinen at linux.intel.com>
Date:   Wed Jan 7 16:56:49 2015 +0200

    dynarray: Add pa_dynarray_remove_by_data()

diff --git a/src/pulsecore/dynarray.c b/src/pulsecore/dynarray.c
index 3f21e90..e9776fa 100644
--- a/src/pulsecore/dynarray.c
+++ b/src/pulsecore/dynarray.c
@@ -104,6 +104,26 @@ int pa_dynarray_remove_by_index(pa_dynarray *array, unsigned i) {
     return 0;
 }
 
+int pa_dynarray_remove_by_data(pa_dynarray *array, void *p) {
+    unsigned i;
+
+    pa_assert(array);
+    pa_assert(p);
+
+    /* Iterate backwards, with the assumption that recently appended entries
+     * are likely to be removed first. */
+    i = array->n_entries;
+    while (i > 0) {
+        i--;
+        if (array->data[i] == p) {
+            pa_dynarray_remove_by_index(array, i);
+            return 0;
+        }
+    }
+
+    return -PA_ERR_NOENTITY;
+}
+
 void *pa_dynarray_steal_last(pa_dynarray *array) {
     pa_assert(array);
 
diff --git a/src/pulsecore/dynarray.h b/src/pulsecore/dynarray.h
index 2b30c7a..1c0e79f 100644
--- a/src/pulsecore/dynarray.h
+++ b/src/pulsecore/dynarray.h
@@ -51,6 +51,11 @@ void *pa_dynarray_last(pa_dynarray *array);
 /* Returns -PA_ERR_NOENTITY if i is out of bounds, and zero otherwise. */
 int pa_dynarray_remove_by_index(pa_dynarray *array, unsigned i);
 
+/* Returns -PA_ERR_NOENTITY if p is not found in the array, and zero
+ * otherwise. If the array contains multiple occurrencies of p, only one of
+ * them is removed (and it's unspecified which one). */
+int pa_dynarray_remove_by_data(pa_dynarray *array, void *p);
+
 /* Returns the removed item, or NULL if the array is empty. */
 void *pa_dynarray_steal_last(pa_dynarray *array);
 

commit 9efe77c8e51181757036aa35ab5c653d42091fa8
Author: Tanu Kaskinen <tanu.kaskinen at linux.intel.com>
Date:   Wed Jan 7 16:56:48 2015 +0200

    dynarray: Add pa_dynarray_remove_by_index()
    
    Also, remove the talk about "fast" variants of functions that remove
    entries from an array. Currently there's no need for order-preserving
    functions, so all functions are "fast".

diff --git a/src/pulsecore/dynarray.c b/src/pulsecore/dynarray.c
index 944f68d..3f21e90 100644
--- a/src/pulsecore/dynarray.c
+++ b/src/pulsecore/dynarray.c
@@ -86,6 +86,24 @@ void *pa_dynarray_last(pa_dynarray *array) {
     return array->data[array->n_entries - 1];
 }
 
+int pa_dynarray_remove_by_index(pa_dynarray *array, unsigned i) {
+    void *entry;
+
+    pa_assert(array);
+
+    if (i >= array->n_entries)
+        return -PA_ERR_NOENTITY;
+
+    entry = array->data[i];
+    array->data[i] = array->data[array->n_entries - 1];
+    array->n_entries--;
+
+    if (array->free_cb)
+        array->free_cb(entry);
+
+    return 0;
+}
+
 void *pa_dynarray_steal_last(pa_dynarray *array) {
     pa_assert(array);
 
diff --git a/src/pulsecore/dynarray.h b/src/pulsecore/dynarray.h
index 082ab1d..2b30c7a 100644
--- a/src/pulsecore/dynarray.h
+++ b/src/pulsecore/dynarray.h
@@ -33,12 +33,9 @@ typedef struct pa_dynarray pa_dynarray;
  * from the array without freeing them, while also having the free callback
  * set, the functions with "steal" in their name can be used.
  *
- * Removing items from the middle of the array causes the subsequent items to
- * be moved to fill the gap, so it's not efficient with large arrays. If the
- * order of the array is not important, however, functions with "fast" in their
- * name can be used, in which case the gap is filled by moving only the last
- * item(s). XXX: Currently there are no functions with "fast" in their name,
- * but such functions will be added if they are ever needed.
+ * Removing items from the middle of the array causes the last item to be
+ * moved to the place of the removed item. That is, array ordering is not
+ * preserved.
  *
  * The array doesn't support storing NULL pointers. */
 
@@ -51,6 +48,9 @@ void *pa_dynarray_get(pa_dynarray *array, unsigned i);
 /* Returns the last element, or NULL if the array is empty. */
 void *pa_dynarray_last(pa_dynarray *array);
 
+/* Returns -PA_ERR_NOENTITY if i is out of bounds, and zero otherwise. */
+int pa_dynarray_remove_by_index(pa_dynarray *array, unsigned i);
+
 /* Returns the removed item, or NULL if the array is empty. */
 void *pa_dynarray_steal_last(pa_dynarray *array);
 

commit e5cf7e4a07368c3b2554d8200949ee6bd15db4b9
Author: Tanu Kaskinen <tanu.kaskinen at linux.intel.com>
Date:   Wed Jan 7 16:56:47 2015 +0200

    dynarray: Add pa_dynarray_last()

diff --git a/src/pulsecore/dynarray.c b/src/pulsecore/dynarray.c
index 7d7c09c..944f68d 100644
--- a/src/pulsecore/dynarray.c
+++ b/src/pulsecore/dynarray.c
@@ -77,6 +77,15 @@ void *pa_dynarray_get(pa_dynarray *array, unsigned i) {
     return array->data[i];
 }
 
+void *pa_dynarray_last(pa_dynarray *array) {
+    pa_assert(array);
+
+    if (array->n_entries == 0)
+        return NULL;
+
+    return array->data[array->n_entries - 1];
+}
+
 void *pa_dynarray_steal_last(pa_dynarray *array) {
     pa_assert(array);
 
diff --git a/src/pulsecore/dynarray.h b/src/pulsecore/dynarray.h
index 0ca6ed3..082ab1d 100644
--- a/src/pulsecore/dynarray.h
+++ b/src/pulsecore/dynarray.h
@@ -48,6 +48,9 @@ void pa_dynarray_free(pa_dynarray *array);
 void pa_dynarray_append(pa_dynarray *array, void *p);
 void *pa_dynarray_get(pa_dynarray *array, unsigned i);
 
+/* Returns the last element, or NULL if the array is empty. */
+void *pa_dynarray_last(pa_dynarray *array);
+
 /* Returns the removed item, or NULL if the array is empty. */
 void *pa_dynarray_steal_last(pa_dynarray *array);
 

commit b094c92a0101029e6f2d7d340166a2afb5e5a8a5
Author: Alexander E. Patrakov <patrakov at gmail.com>
Date:   Wed Dec 31 12:28:03 2014 +0500

    Make pa_socket_server_new static
    
    While at it, also remove SOCKET_SERVER_GENERIC, because it is always
    being overwritten with a specific socket type.
    
    Signed-off-by: Alexander E. Patrakov <patrakov at gmail.com>

diff --git a/src/pulsecore/socket-server.c b/src/pulsecore/socket-server.c
index ce61694..0792586 100644
--- a/src/pulsecore/socket-server.c
+++ b/src/pulsecore/socket-server.c
@@ -85,7 +85,6 @@ struct pa_socket_server {
     pa_io_event *io_event;
     pa_mainloop_api *mainloop;
     enum {
-        SOCKET_SERVER_GENERIC,
         SOCKET_SERVER_IPV4,
         SOCKET_SERVER_UNIX,
         SOCKET_SERVER_IPV6
@@ -147,7 +146,7 @@ finish:
     pa_socket_server_unref(s);
 }
 
-pa_socket_server* pa_socket_server_new(pa_mainloop_api *m, int fd) {
+static pa_socket_server* socket_server_new(pa_mainloop_api *m, int fd) {
     pa_socket_server *s;
 
     pa_assert(m);
@@ -160,8 +159,6 @@ pa_socket_server* pa_socket_server_new(pa_mainloop_api *m, int fd) {
 
     pa_assert_se(s->io_event = m->io_new(m, fd, PA_IO_EVENT_INPUT, callback, s));
 
-    s->type = SOCKET_SERVER_GENERIC;
-
     return s;
 }
 
@@ -229,7 +226,7 @@ pa_socket_server* pa_socket_server_new_unix(pa_mainloop_api *m, const char *file
         }
     }
 
-    pa_assert_se(s = pa_socket_server_new(m, fd));
+    pa_assert_se(s = socket_server_new(m, fd));
 
     s->filename = pa_xstrdup(filename);
     s->type = SOCKET_SERVER_UNIX;
@@ -298,7 +295,7 @@ pa_socket_server* pa_socket_server_new_ipv4(pa_mainloop_api *m, uint32_t address
         goto fail;
     }
 
-    pa_assert_se(ss = pa_socket_server_new(m, fd));
+    pa_assert_se(ss = socket_server_new(m, fd));
 
     ss->type = SOCKET_SERVER_IPV4;
     ss->tcpwrap_service = pa_xstrdup(tcpwrap_service);
@@ -366,7 +363,7 @@ pa_socket_server* pa_socket_server_new_ipv6(pa_mainloop_api *m, const uint8_t ad
         goto fail;
     }
 
-    pa_assert_se(ss = pa_socket_server_new(m, fd));
+    pa_assert_se(ss = socket_server_new(m, fd));
 
     ss->type = SOCKET_SERVER_IPV6;
     ss->tcpwrap_service = pa_xstrdup(tcpwrap_service);
diff --git a/src/pulsecore/socket-server.h b/src/pulsecore/socket-server.h
index 1944e23..0793baf 100644
--- a/src/pulsecore/socket-server.h
+++ b/src/pulsecore/socket-server.h
@@ -29,7 +29,6 @@
 
 typedef struct pa_socket_server pa_socket_server;
 
-pa_socket_server* pa_socket_server_new(pa_mainloop_api *m, int fd);
 pa_socket_server* pa_socket_server_new_unix(pa_mainloop_api *m, const char *filename);
 pa_socket_server* pa_socket_server_new_ipv4(pa_mainloop_api *m, uint32_t address, uint16_t port, bool fallback, const char *tcpwrap_service);
 pa_socket_server* pa_socket_server_new_ipv4_loopback(pa_mainloop_api *m, uint16_t port, bool fallback, const char *tcpwrap_service);

commit 73dee7c9f7fff28ddc5ca6eeded26ef8c41fe761
Author: Tanu Kaskinen <tanu.kaskinen at linux.intel.com>
Date:   Mon Nov 3 11:47:58 2014 +0200

    socket-server: pa_socket_server_new() can't fail, so don't check its return value
    
    An assertion was already used in pa_socket_server_new_unix(), this
    makes the TCP variants consistent with that.
    
    Even if pa_socket_server_new() could fail, the error handling wasn't
    good, because there was no "goto fail", meaning that the fd would have
    been leaked.

diff --git a/src/pulsecore/socket-server.c b/src/pulsecore/socket-server.c
index d1f83f4..ce61694 100644
--- a/src/pulsecore/socket-server.c
+++ b/src/pulsecore/socket-server.c
@@ -298,10 +298,10 @@ pa_socket_server* pa_socket_server_new_ipv4(pa_mainloop_api *m, uint32_t address
         goto fail;
     }
 
-    if ((ss = pa_socket_server_new(m, fd))) {
-        ss->type = SOCKET_SERVER_IPV4;
-        ss->tcpwrap_service = pa_xstrdup(tcpwrap_service);
-    }
+    pa_assert_se(ss = pa_socket_server_new(m, fd));
+
+    ss->type = SOCKET_SERVER_IPV4;
+    ss->tcpwrap_service = pa_xstrdup(tcpwrap_service);
 
     return ss;
 
@@ -366,10 +366,10 @@ pa_socket_server* pa_socket_server_new_ipv6(pa_mainloop_api *m, const uint8_t ad
         goto fail;
     }
 
-    if ((ss = pa_socket_server_new(m, fd))) {
-        ss->type = SOCKET_SERVER_IPV6;
-        ss->tcpwrap_service = pa_xstrdup(tcpwrap_service);
-    }
+    pa_assert_se(ss = pa_socket_server_new(m, fd));
+
+    ss->type = SOCKET_SERVER_IPV6;
+    ss->tcpwrap_service = pa_xstrdup(tcpwrap_service);
 
     return ss;
 



More information about the pulseaudio-commits mailing list