[Pkg-pulseaudio-devel] [SCM] pulseaudio packaging branch, master, updated. debian/0.9.15-3-1-gdf3ca1c

sjoerd at users.alioth.debian.org sjoerd at users.alioth.debian.org
Sun Jun 21 14:25:47 UTC 2009


The branch, master has been updated
       via  df3ca1cf804c51bcb4fb2bfafdae6160a8bff710 (commit)
      from  28196da5bc488f011dccfbe50cda7bfdf5d91b89 (commit)


- Shortlog ------------------------------------------------------------
df3ca1c Synchronize our patches with Mandriva and Fedora (thanks to Colin Guthrie and Lennart Poettering)

Summary of changes:
 debian/changelog                                   |   36 ++
 ...configuration-of-fallback-device-strings-.patch |    2 +-
 ...L-is-passed-to-pa_path_get_filename-just-.patch |   37 ++
 ...hit-an-assert-when-invalid-module-argumen.patch |   38 ++
 ...rding-we-are-speaking-of-card-profiles-no.patch |   22 +
 ...lize-buffer-size-before-number-of-periods.patch |   81 +++
 ...-obsolete-module-idle-time-directive-from.patch |   40 ++
 ...ure-soft-mute-status-stays-in-sync-with-h.patch |   77 +++
 ...LE-BE-order-for-24-bit-accessor-functions.patch |   45 ++
 ...-log-print-file-name-only-when-we-have-it.patch |   22 +
 ...n-document-24bit-sample-types-in-man-page.patch |   31 ++
 ...-document-log-related-daemon.conf-options.patch |   49 ++
 ...t-that-tsched-doesn-t-use-fragment-settin.patch |   23 +
 ...we-fail-to-fill-in-mutex-into-static-mute.patch |   22 +
 ...eadlock-when-we-try-to-resume-an-OSS-devi.patch |   52 ++
 ...ocol-don-t-hit-an-assert-when-we-call-con.patch |   22 +
 ...t-add-enumeration-macro-PA_IDXSET_FOREACH.patch |   22 +
 ...ams-when-one-stream-move-fails-try-to-con.patch |   45 ++
 ...0018-sample-correctly-pass-s24-32-formats.patch |   31 ++
 ...-fix-iteration-loop-when-adjusting-volume.patch |   37 ++
 ...-properly-allocate-silence-block-for-s24-.patch |   31 ++
 ...1-sconv-fix-a-few-minor-conversion-issues.patch |   58 +++
 ...it-more-verbose-when-a-hwparam-call-fails.patch |  118 +++++
 ...-we-don-t-end-up-in-an-endless-loop-when-.patch |  132 +++++
 ...roduce-pa_-sink-source-_set_fixed_latency.patch |  236 +++++++++
 ...requested-latency-only-when-we-are-runnin.patch |   46 ++
 .../0026-sample-fix-build-on-BE-archs.patch        |   22 +
 ...ly-convert-return-values-of-snd_strerror-.patch |  532 ++++++++++++++++++++
 debian/patches/0028-alsa-remove-debug-code.patch   |   22 +
 debian/patches/series                              |   27 +
 30 files changed, 1957 insertions(+), 1 deletions(-)
-----------------------------------------------------------------------
Details of changes:

commit df3ca1cf804c51bcb4fb2bfafdae6160a8bff710
Author: Sjoerd Simons <sjoerd at debian.org>
Date:   Sun Jun 14 17:37:51 2009 +0100

    Synchronize our patches with Mandriva and Fedora (thanks to Colin Guthrie and Lennart Poettering)
    
    * Synchronize our patches with Mandriva and Fedora (thanks to Colin Guthrie
      and Lennart Poettering)
      - 0002-util-if-NULL-is-passed-to-pa_path_get_filename-just-.patch
      - 0003-alsa-don-t-hit-an-assert-when-invalid-module-argumen.patch
      - 0004-alsa-fix-wording-we-are-speaking-of-card-profiles-no.patch
      - 0005-alsa-initialize-buffer-size-before-number-of-periods.patch
      - 0006-conf-remove-obsolete-module-idle-time-directive-from.patch
      - 0007-core-make-sure-soft-mute-status-stays-in-sync-with-h.patch
        + Ensure hw and software mute states stay in sync
          (Closes: #525572, #522177)
      - 0008-endian-fix-LE-BE-order-for-24-bit-accessor-functions.patch
      - 0009-log-print-file-name-only-when-we-have-it.patch
      - 0010-man-document-24bit-sample-types-in-man-page.patch
      - 0011-man-document-log-related-daemon.conf-options.patch
      - 0012-man-document-that-tsched-doesn-t-use-fragment-settin.patch
      - 0013-mutex-when-we-fail-to-fill-in-mutex-into-static-mute.patch
      - 0014-oss-don-t-deadlock-when-we-try-to-resume-an-OSS-devi.patch
      - 0015-simple-protocol-don-t-hit-an-assert-when-we-call-con.patch
      - 0016-idxset-add-enumeration-macro-PA_IDXSET_FOREACH.patch
      - 0017-rescue-streams-when-one-stream-move-fails-try-to-con.patch
      - 0018-sample-correctly-pass-s24-32-formats.patch
      - 0019-sample-util-fix-iteration-loop-when-adjusting-volume.patch
      - 0020-sample-util-properly-allocate-silence-block-for-s24-.patch
      - 0021-sconv-fix-a-few-minor-conversion-issues.patch
      - 0022-alsa-be-a-bit-more-verbose-when-a-hwparam-call-fails.patch
      - 0023-rescue-make-we-don-t-end-up-in-an-endless-loop-when-.patch
      - 0024-core-introduce-pa_-sink-source-_set_fixed_latency.patch
      - 0025-core-cache-requested-latency-only-when-we-are-runnin.patch
      - 0026-sample-fix-build-on-BE-archs.patch
      - 0027-alsa-properly-convert-return-values-of-snd_strerror-.patch
      - 0028-alsa-remove-debug-code.patch

diff --git a/debian/changelog b/debian/changelog
index d38a2d4..37fabe8 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,39 @@
+pulseaudio (0.9.15-4) UNRELEASED; urgency=low
+
+  * Synchronize our patches with Mandriva and Fedora (thanks to Colin Guthrie
+    and Lennart Poettering)
+    - 0002-util-if-NULL-is-passed-to-pa_path_get_filename-just-.patch
+    - 0003-alsa-don-t-hit-an-assert-when-invalid-module-argumen.patch
+    - 0004-alsa-fix-wording-we-are-speaking-of-card-profiles-no.patch
+    - 0005-alsa-initialize-buffer-size-before-number-of-periods.patch
+    - 0006-conf-remove-obsolete-module-idle-time-directive-from.patch
+    - 0007-core-make-sure-soft-mute-status-stays-in-sync-with-h.patch
+      + Ensure hw and software mute states stay in sync
+        (Closes: #525572, #522177)
+    - 0008-endian-fix-LE-BE-order-for-24-bit-accessor-functions.patch
+    - 0009-log-print-file-name-only-when-we-have-it.patch
+    - 0010-man-document-24bit-sample-types-in-man-page.patch
+    - 0011-man-document-log-related-daemon.conf-options.patch
+    - 0012-man-document-that-tsched-doesn-t-use-fragment-settin.patch
+    - 0013-mutex-when-we-fail-to-fill-in-mutex-into-static-mute.patch
+    - 0014-oss-don-t-deadlock-when-we-try-to-resume-an-OSS-devi.patch
+    - 0015-simple-protocol-don-t-hit-an-assert-when-we-call-con.patch
+    - 0016-idxset-add-enumeration-macro-PA_IDXSET_FOREACH.patch
+    - 0017-rescue-streams-when-one-stream-move-fails-try-to-con.patch
+    - 0018-sample-correctly-pass-s24-32-formats.patch
+    - 0019-sample-util-fix-iteration-loop-when-adjusting-volume.patch
+    - 0020-sample-util-properly-allocate-silence-block-for-s24-.patch
+    - 0021-sconv-fix-a-few-minor-conversion-issues.patch
+    - 0022-alsa-be-a-bit-more-verbose-when-a-hwparam-call-fails.patch
+    - 0023-rescue-make-we-don-t-end-up-in-an-endless-loop-when-.patch
+    - 0024-core-introduce-pa_-sink-source-_set_fixed_latency.patch
+    - 0025-core-cache-requested-latency-only-when-we-are-runnin.patch
+    - 0026-sample-fix-build-on-BE-archs.patch
+    - 0027-alsa-properly-convert-return-values-of-snd_strerror-.patch
+    - 0028-alsa-remove-debug-code.patch
+
+ -- Sjoerd Simons <sjoerd at debian.org>  Sun, 14 Jun 2009 17:30:30 +0100
+
 pulseaudio (0.9.15-3) unstable; urgency=low
 
   * Re-enable bluetooth support (Closes: #530514)
diff --git a/debian/patches/0001-alsa-allow-configuration-of-fallback-device-strings-.patch b/debian/patches/0001-alsa-allow-configuration-of-fallback-device-strings-.patch
index 1c1b15a..3bc5932 100644
--- a/debian/patches/0001-alsa-allow-configuration-of-fallback-device-strings-.patch
+++ b/debian/patches/0001-alsa-allow-configuration-of-fallback-device-strings-.patch
@@ -1,7 +1,7 @@
 From 270ab5f0f2c049f842e5b4a7f69c59db84827c5d Mon Sep 17 00:00:00 2001
 From: Lennart Poettering <lennart at poettering.net>
 Date: Wed, 29 Apr 2009 01:58:18 +0200
-Subject: [PATCH] alsa: allow configuration of fallback device strings in profiles
+Subject: [PATCH 01/28] alsa: allow configuration of fallback device strings in profiles
 
 This has the benefit that we can properly support ALSA devices where
 only the raw 'hw' device exists but no 'front' although it's a proper
diff --git a/debian/patches/0002-util-if-NULL-is-passed-to-pa_path_get_filename-just-.patch b/debian/patches/0002-util-if-NULL-is-passed-to-pa_path_get_filename-just-.patch
new file mode 100644
index 0000000..a2ebe16
--- /dev/null
+++ b/debian/patches/0002-util-if-NULL-is-passed-to-pa_path_get_filename-just-.patch
@@ -0,0 +1,37 @@
+From 876624e3147cf3deac847b11bde4b04988971eee Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Sun, 19 Apr 2009 19:02:16 +0200
+Subject: [PATCH 02/28] util: if NULL is passed to pa_path_get_filename() just hand it through
+
+---
+ src/pulse/util.c |    3 ++-
+ src/pulse/util.h |    2 +-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/src/pulse/util.c b/src/pulse/util.c
+index 54a188d..6f1e40a 100644
+--- a/src/pulse/util.c
++++ b/src/pulse/util.c
+@@ -219,7 +219,8 @@ char *pa_get_binary_name(char *s, size_t l) {
+ char *pa_path_get_filename(const char *p) {
+     char *fn;
+ 
+-    pa_assert(p);
++    if (!p)
++        return NULL;
+ 
+     if ((fn = strrchr(p, PA_PATH_SEP_CHAR)))
+         return fn+1;
+diff --git a/src/pulse/util.h b/src/pulse/util.h
+index f6dd40c..ad85653 100644
+--- a/src/pulse/util.h
++++ b/src/pulse/util.h
+@@ -51,7 +51,7 @@ char *pa_get_home_dir(char *s, size_t l);
+ char *pa_get_binary_name(char *s, size_t l);
+ 
+ /** Return a pointer to the filename inside a path (which is the last
+- * component). */
++ * component). If passed NULL will return NULL. */
+ char *pa_path_get_filename(const char *p);
+ 
+ /** Wait t milliseconds */
diff --git a/debian/patches/0003-alsa-don-t-hit-an-assert-when-invalid-module-argumen.patch b/debian/patches/0003-alsa-don-t-hit-an-assert-when-invalid-module-argumen.patch
new file mode 100644
index 0000000..2524e7f
--- /dev/null
+++ b/debian/patches/0003-alsa-don-t-hit-an-assert-when-invalid-module-argumen.patch
@@ -0,0 +1,38 @@
+From 6e1f6ca6e2279fdd8601d95419aeeaa29445dd5b Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Fri, 1 May 2009 04:11:30 +0200
+Subject: [PATCH 03/28] alsa: don't hit an assert when invalid module arguments are passed
+
+---
+ src/modules/alsa/alsa-sink.c   |    3 ++-
+ src/modules/alsa/alsa-source.c |    3 ++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
+index 2fbcd7b..360cb4d 100644
+--- a/src/modules/alsa/alsa-sink.c
++++ b/src/modules/alsa/alsa-sink.c
+@@ -1770,7 +1770,8 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
+ 
+ fail:
+ 
+-    userdata_free(u);
++    if (u)
++        userdata_free(u);
+ 
+     return NULL;
+ }
+diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
+index c59fc75..19c6cfc 100644
+--- a/src/modules/alsa/alsa-source.c
++++ b/src/modules/alsa/alsa-source.c
+@@ -1621,7 +1621,8 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
+ 
+ fail:
+ 
+-    userdata_free(u);
++    if (u)
++        userdata_free(u);
+ 
+     return NULL;
+ }
diff --git a/debian/patches/0004-alsa-fix-wording-we-are-speaking-of-card-profiles-no.patch b/debian/patches/0004-alsa-fix-wording-we-are-speaking-of-card-profiles-no.patch
new file mode 100644
index 0000000..77fc625
--- /dev/null
+++ b/debian/patches/0004-alsa-fix-wording-we-are-speaking-of-card-profiles-no.patch
@@ -0,0 +1,22 @@
+From b14f2f1aa66e2806849c32e1dbd6d57b19a6d3ee Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 26 May 2009 22:29:33 +0200
+Subject: [PATCH 04/28] alsa: fix wording, we are speaking of card profiles, not output profiles
+
+---
+ src/modules/alsa/module-alsa-card.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
+index fdc952d..dd8636e 100644
+--- a/src/modules/alsa/module-alsa-card.c
++++ b/src/modules/alsa/module-alsa-card.c
+@@ -135,7 +135,7 @@ static void enumerate_cb(
+             bonus += 20000;
+     }
+ 
+-    pa_log_info("Found output profile '%s'", t);
++    pa_log_info("Found profile '%s'", t);
+ 
+     p = pa_card_profile_new(n, t, sizeof(struct profile_data));
+ 
diff --git a/debian/patches/0005-alsa-initialize-buffer-size-before-number-of-periods.patch b/debian/patches/0005-alsa-initialize-buffer-size-before-number-of-periods.patch
new file mode 100644
index 0000000..070ab04
--- /dev/null
+++ b/debian/patches/0005-alsa-initialize-buffer-size-before-number-of-periods.patch
@@ -0,0 +1,81 @@
+From 314241e6002e7c78ee87a171ee337be382b3e0d7 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Fri, 1 May 2009 04:16:17 +0200
+Subject: [PATCH 05/28] alsa: initialize buffer size before number of periods to improve compat with some backends
+
+---
+ src/modules/alsa/alsa-util.c |   33 ++++++++++++++++++++-------------
+ 1 files changed, 20 insertions(+), 13 deletions(-)
+
+diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c
+index 2ea0c3d..34cb6d6 100644
+--- a/src/modules/alsa/alsa-util.c
++++ b/src/modules/alsa/alsa-util.c
+@@ -332,7 +332,6 @@ int pa_alsa_set_hw_params(
+     int ret = -1;
+     snd_pcm_uframes_t _period_size = period_size ? *period_size : 0;
+     unsigned int _periods = periods ? *periods : 0;
+-    snd_pcm_uframes_t buffer_size;
+     unsigned int r = ss->rate;
+     unsigned int c = ss->channels;
+     pa_sample_format_t f = ss->format;
+@@ -388,39 +387,47 @@ int pa_alsa_set_hw_params(
+         goto finish;
+ 
+     if (_period_size && tsched_size && _periods) {
++
+         /* Adjust the buffer sizes, if we didn't get the rate we were asking for */
+         _period_size = (snd_pcm_uframes_t) (((uint64_t) _period_size * r) / ss->rate);
+         tsched_size = (snd_pcm_uframes_t) (((uint64_t) tsched_size * r) / ss->rate);
+ 
+         if (_use_tsched) {
+-            _period_size = tsched_size;
+-            _periods = 1;
++            snd_pcm_uframes_t buffer_size;
+ 
+             pa_assert_se(snd_pcm_hw_params_get_buffer_size_max(hwparams, &buffer_size) == 0);
+             pa_log_debug("Maximum hw buffer size is %u ms", (unsigned) buffer_size * 1000 / r);
++
++            _period_size = tsched_size;
++            _periods = 1;
+         }
+ 
+-        buffer_size = _periods * _period_size;
++        if (_period_size > 0 && _periods > 0) {
++            snd_pcm_uframes_t buffer_size;
++
++            buffer_size = _periods * _period_size;
++
++            if ((ret = snd_pcm_hw_params_set_buffer_size_near(pcm_handle, hwparams, &buffer_size)) < 0)
++                pa_log_info("snd_pcm_hw_params_set_buffer_size_near() failed: %s", pa_alsa_strerror(ret));
++        }
+ 
+         if (_periods > 0) {
+ 
+-            /* First we pass 0 as direction to get exactly what we asked
+-             * for. That this is necessary is presumably a bug in ALSA */
++            /* First we pass 0 as direction to get exactly what we
++             * asked for. That this is necessary is presumably a bug
++             * in ALSA. All in all this is mostly a hint to ALSA, so
++             * we don't care if this fails. */
+ 
+             dir = 0;
+-            if ((ret = snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &_periods, &dir)) < 0) {
++            if (snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &_periods, &dir) < 0) {
+                 dir = 1;
+-                if ((ret = snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &_periods, &dir)) < 0) {
++                if (snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &_periods, &dir) < 0) {
+                     dir = -1;
+                     if ((ret = snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &_periods, &dir)) < 0)
+-                        goto finish;
++                        pa_log_info("snd_pcm_hw_params_set_periods_near() failed: %s", pa_alsa_strerror(ret));
+                 }
+             }
+         }
+-
+-        if (_period_size > 0)
+-            if ((ret = snd_pcm_hw_params_set_buffer_size_near(pcm_handle, hwparams, &buffer_size)) < 0)
+-                goto finish;
+     }
+ 
+     if  ((ret = snd_pcm_hw_params(pcm_handle, hwparams)) < 0)
diff --git a/debian/patches/0006-conf-remove-obsolete-module-idle-time-directive-from.patch b/debian/patches/0006-conf-remove-obsolete-module-idle-time-directive-from.patch
new file mode 100644
index 0000000..bce55f9
--- /dev/null
+++ b/debian/patches/0006-conf-remove-obsolete-module-idle-time-directive-from.patch
@@ -0,0 +1,40 @@
+From 313ac6bf0f63515ff4754208ca5d2749fe1096a8 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Sun, 7 Jun 2009 00:44:16 +0200
+Subject: [PATCH 06/28] conf: remove obsolete module-idle-time directive from default config file/man page
+
+---
+ man/pulse-daemon.conf.5.xml.in |    7 -------
+ src/daemon/daemon.conf.in      |    1 -
+ 2 files changed, 0 insertions(+), 8 deletions(-)
+
+diff --git a/man/pulse-daemon.conf.5.xml.in b/man/pulse-daemon.conf.5.xml.in
+index afa7ca0..7d184a6 100644
+--- a/man/pulse-daemon.conf.5.xml.in
++++ b/man/pulse-daemon.conf.5.xml.in
+@@ -228,13 +228,6 @@ USA.
+     </option>
+ 
+     <option>
+-      <p><opt>module-idle-time=</opt> Unload autoloaded modules after
+-      being idle for this time in seconds. Defaults to 20. The
+-      <opt>--module-idle-time</opt> command line option takes
+-      precedence.</p>
+-    </option>
+-
+-    <option>
+       <p><opt>scache-idle-time=</opt> Unload autoloaded sample cache
+       entries after being idle for this time in seconds. Defaults to
+       20. The <opt>--scache-idle-time</opt> command line option takes
+diff --git a/src/daemon/daemon.conf.in b/src/daemon/daemon.conf.in
+index fcd2513..ee71f85 100644
+--- a/src/daemon/daemon.conf.in
++++ b/src/daemon/daemon.conf.in
+@@ -35,7 +35,6 @@
+ ; realtime-priority = 5
+ 
+ ; exit-idle-time = 20
+-; module-idle-time = 20
+ ; scache-idle-time = 20
+ 
+ ; dl-search-path = (depends on architecture)
diff --git a/debian/patches/0007-core-make-sure-soft-mute-status-stays-in-sync-with-h.patch b/debian/patches/0007-core-make-sure-soft-mute-status-stays-in-sync-with-h.patch
new file mode 100644
index 0000000..5d4f660
--- /dev/null
+++ b/debian/patches/0007-core-make-sure-soft-mute-status-stays-in-sync-with-h.patch
@@ -0,0 +1,77 @@
+From f9bfc3780f14df0def0558e9265a89a7526ebb16 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 8 Jun 2009 00:02:15 +0200
+Subject: [PATCH 07/28] core: make sure soft mute status stays in sync with hw mute status
+
+This should close rhbz #494851, mandriva bz #51234.
+
+Probably the same as our own #572, launchpad #352732.
+---
+ src/modules/alsa/alsa-sink.c   |    2 +-
+ src/modules/alsa/alsa-source.c |    2 +-
+ src/pulsecore/sink.c           |    6 +++++-
+ src/pulsecore/source.c         |    6 +++++-
+ 4 files changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
+index 360cb4d..a544b58 100644
+--- a/src/modules/alsa/alsa-sink.c
++++ b/src/modules/alsa/alsa-sink.c
+@@ -1146,7 +1146,7 @@ fail:
+ 
+ static void sink_get_mute_cb(pa_sink *s) {
+     struct userdata *u = s->userdata;
+-    int err, sw;
++    int err, sw = 0;
+ 
+     pa_assert(u);
+     pa_assert(u->mixer_elem);
+diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
+index 19c6cfc..5d8e349 100644
+--- a/src/modules/alsa/alsa-source.c
++++ b/src/modules/alsa/alsa-source.c
+@@ -1105,7 +1105,7 @@ fail:
+ 
+ static void source_get_mute_cb(pa_source *s) {
+     struct userdata *u = s->userdata;
+-    int err, sw;
++    int err, sw = 0;
+ 
+     pa_assert(u);
+     pa_assert(u->mixer_elem);
+diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
+index 30fa557..c99f9a8 100644
+--- a/src/pulsecore/sink.c
++++ b/src/pulsecore/sink.c
+@@ -1272,8 +1272,12 @@ pa_bool_t pa_sink_get_mute(pa_sink *s, pa_bool_t force_refresh) {
+ 
+         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MUTE, NULL, 0, NULL) == 0);
+ 
+-        if (old_muted != s->muted)
++        if (old_muted != s->muted) {
+             pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
++
++            /* Make sure the soft mute status stays in sync */
++            pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0);
++        }
+     }
+ 
+     return s->muted;
+diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
+index 2190250..0baaed1 100644
+--- a/src/pulsecore/source.c
++++ b/src/pulsecore/source.c
+@@ -757,8 +757,12 @@ pa_bool_t pa_source_get_mute(pa_source *s, pa_bool_t force_refresh) {
+ 
+         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_MUTE, NULL, 0, NULL) == 0);
+ 
+-        if (old_muted != s->muted)
++        if (old_muted != s->muted) {
+             pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
++
++            /* Make sure the soft mute status stays in sync */
++            pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0);
++        }
+     }
+ 
+     return s->muted;
diff --git a/debian/patches/0008-endian-fix-LE-BE-order-for-24-bit-accessor-functions.patch b/debian/patches/0008-endian-fix-LE-BE-order-for-24-bit-accessor-functions.patch
new file mode 100644
index 0000000..264c2f4
--- /dev/null
+++ b/debian/patches/0008-endian-fix-LE-BE-order-for-24-bit-accessor-functions.patch
@@ -0,0 +1,45 @@
+From 7f17882bae9d2b694f440d28dc9bb3fcf133fa1a Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Fri, 1 May 2009 04:13:15 +0200
+Subject: [PATCH 08/28] endian: fix LE/BE order for 24 bit accessor functions
+
+---
+ src/pulsecore/endianmacros.h |    8 ++++----
+ 1 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/pulsecore/endianmacros.h b/src/pulsecore/endianmacros.h
+index 2257937..2b18cf8 100644
+--- a/src/pulsecore/endianmacros.h
++++ b/src/pulsecore/endianmacros.h
+@@ -45,27 +45,27 @@
+ #define PA_UINT32_SWAP(x) ( (uint32_t) ( ((uint32_t) (x) >> 24) | ((uint32_t) (x) << 24) | (((uint32_t) (x) & 0xFF00) << 8) | ((((uint32_t) (x)) >> 8) & 0xFF00) ) )
+ #endif
+ 
+-static inline uint32_t PA_READ24LE(const uint8_t *p) {
++static inline uint32_t PA_READ24BE(const uint8_t *p) {
+     return
+         ((uint32_t) p[0] << 16) |
+         ((uint32_t) p[1] << 8) |
+         ((uint32_t) p[2]);
+ }
+ 
+-static inline uint32_t PA_READ24BE(const uint8_t *p) {
++static inline uint32_t PA_READ24LE(const uint8_t *p) {
+     return
+         ((uint32_t) p[2] << 16) |
+         ((uint32_t) p[1] << 8) |
+         ((uint32_t) p[0]);
+ }
+ 
+-static inline void PA_WRITE24LE(uint8_t *p, uint32_t u) {
++static inline void PA_WRITE24BE(uint8_t *p, uint32_t u) {
+     p[0] = (uint8_t) (u >> 16);
+     p[1] = (uint8_t) (u >> 8);
+     p[2] = (uint8_t) u;
+ }
+ 
+-static inline void PA_WRITE24BE(uint8_t *p, uint32_t u) {
++static inline void PA_WRITE24LE(uint8_t *p, uint32_t u) {
+     p[2] = (uint8_t) (u >> 16);
+     p[1] = (uint8_t) (u >> 8);
+     p[0] = (uint8_t) u;
diff --git a/debian/patches/0009-log-print-file-name-only-when-we-have-it.patch b/debian/patches/0009-log-print-file-name-only-when-we-have-it.patch
new file mode 100644
index 0000000..bdc49c2
--- /dev/null
+++ b/debian/patches/0009-log-print-file-name-only-when-we-have-it.patch
@@ -0,0 +1,22 @@
+From 11c17636d1d6c7eb4d6278869d3fa91715433ab2 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Sun, 19 Apr 2009 19:04:50 +0200
+Subject: [PATCH 09/28] log: print file name only when we have it
+
+---
+ src/pulsecore/log.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/src/pulsecore/log.c b/src/pulsecore/log.c
+index 60ea9c5..919ebe1 100644
+--- a/src/pulsecore/log.c
++++ b/src/pulsecore/log.c
+@@ -285,7 +285,7 @@ void pa_log_levelv_meta(
+ 
+     if ((_flags & PA_LOG_PRINT_META) && file && line > 0 && func)
+         pa_snprintf(location, sizeof(location), "[%s:%i %s()] ", file, line, func);
+-    else if (_flags & (PA_LOG_PRINT_META|PA_LOG_PRINT_FILE))
++    else if ((_flags & (PA_LOG_PRINT_META|PA_LOG_PRINT_FILE)) && file)
+         pa_snprintf(location, sizeof(location), "%s: ", pa_path_get_filename(file));
+     else
+         location[0] = 0;
diff --git a/debian/patches/0010-man-document-24bit-sample-types-in-man-page.patch b/debian/patches/0010-man-document-24bit-sample-types-in-man-page.patch
new file mode 100644
index 0000000..f03c814
--- /dev/null
+++ b/debian/patches/0010-man-document-24bit-sample-types-in-man-page.patch
@@ -0,0 +1,31 @@
+From 4a080c4f93c254c58736728d9b85bbbfc4e4ec9c Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Sun, 7 Jun 2009 00:45:05 +0200
+Subject: [PATCH 10/28] man: document 24bit sample types in man page
+
+---
+ man/pulse-daemon.conf.5.xml.in |   10 ++++++----
+ 1 files changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/man/pulse-daemon.conf.5.xml.in b/man/pulse-daemon.conf.5.xml.in
+index 7d184a6..b667291 100644
+--- a/man/pulse-daemon.conf.5.xml.in
++++ b/man/pulse-daemon.conf.5.xml.in
+@@ -364,11 +364,13 @@ USA.
+     <option>
+       <p><opt>default-sample-format=</opt> The default sampling
+       format. Specify one of <opt>u8</opt>, <opt>s16le</opt>,
+-      <opt>s16be</opt>, <opt>s32le</opt>,
+-      <opt>s32be</opt>, <opt>float32le</opt>, <opt>float32be</opt>,
++      <opt>s16be</opt>, <opt>s24le</opt>, <opt>s24be</opt>,
++      <opt>s24-32le</opt>, <opt>s24-32be</opt>, <opt>s32le</opt>,
++      <opt>s32be</opt> <opt>float32le</opt>, <opt>float32be</opt>,
+       <opt>ulaw</opt>, <opt>alaw</opt>. Depending on the endianess of
+-      the CPU the
+-      formats <opt>s16ne</opt>, <opt>s16re</opt>, <opt>s32ne</opt>, <opt>s32re</opt>,
++      the CPU the formats <opt>s16ne</opt>, <opt>s16re</opt>,
++      <opt>s24ne</opt>, <opt>s24re</opt>, <opt>s24-32ne</opt>,
++      <opt>s24-32re</opt>, <opt>s32ne</opt>, <opt>s32re</opt>,
+       <opt>float32ne</opt>, <opt>float32re</opt> (for native,
+       resp. reverse endian) are available as aliases.</p>
+     </option>
diff --git a/debian/patches/0011-man-document-log-related-daemon.conf-options.patch b/debian/patches/0011-man-document-log-related-daemon.conf-options.patch
new file mode 100644
index 0000000..43622ec
--- /dev/null
+++ b/debian/patches/0011-man-document-log-related-daemon.conf-options.patch
@@ -0,0 +1,49 @@
+From ba745277dfbffeb0a4aac3bcad8fc74b11bf27d1 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Sun, 7 Jun 2009 00:44:49 +0200
+Subject: [PATCH 11/28] man: document log related daemon.conf options
+
+---
+ man/pulse-daemon.conf.5.xml.in |   21 +++++++++++++++++++--
+ 1 files changed, 19 insertions(+), 2 deletions(-)
+
+diff --git a/man/pulse-daemon.conf.5.xml.in b/man/pulse-daemon.conf.5.xml.in
+index b667291..94ee8fa 100644
+--- a/man/pulse-daemon.conf.5.xml.in
++++ b/man/pulse-daemon.conf.5.xml.in
+@@ -260,9 +260,9 @@ USA.
+     </option>
+ 
+     <option>
+-      <p><opt>default-script-file=</opt> Load the default
++      <p><opt>load-default-script-file=</opt> Load the default
+       configuration script file as specified
+-      in <opt>default-script-file=</opt>. Defaults to "yes".</p>
++      in <opt>default-script-file=</opt>. Defaults to <opt>yes</opt>.</p>
+     </option>
+ 
+   </section>
+@@ -289,6 +289,23 @@ USA.
+       might alter this setting.</p>
+     </option>
+ 
++    <option>
++      <p><opt>log-meta=</opt> With each logged message log the code
++      location the message was generated from. Defaults to
++      <opt>no</opt>.</p>
++    </option>
++
++    <option>
++      <p><opt>log-time=</opt> With each logged messages log the
++      relative time since startup. Defaults to <opt>no</opt>.</p>
++    </option>
++
++    <option>
++      <p><opt>log-backtrace=</opt> When greater than 0, with each
++      logged message log a code stack trace up the the specified
++      number of stack frames. Defaults to <opt>0</opt>.</p>
++    </option>
++
+   </section>
+ 
+   <section name="Resource Limits">
diff --git a/debian/patches/0012-man-document-that-tsched-doesn-t-use-fragment-settin.patch b/debian/patches/0012-man-document-that-tsched-doesn-t-use-fragment-settin.patch
new file mode 100644
index 0000000..a59cf98
--- /dev/null
+++ b/debian/patches/0012-man-document-that-tsched-doesn-t-use-fragment-settin.patch
@@ -0,0 +1,23 @@
+From b8219d533e631a5e574e7d7a060b44723a951dd9 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Sun, 7 Jun 2009 00:45:21 +0200
+Subject: [PATCH 12/28] man: document that tsched doesn't use fragment settings
+
+---
+ man/pulse-daemon.conf.5.xml.in |    3 ++-
+ 1 files changed, 2 insertions(+), 1 deletions(-)
+
+diff --git a/man/pulse-daemon.conf.5.xml.in b/man/pulse-daemon.conf.5.xml.in
+index 94ee8fa..1622f23 100644
+--- a/man/pulse-daemon.conf.5.xml.in
++++ b/man/pulse-daemon.conf.5.xml.in
+@@ -413,7 +413,8 @@ USA.
+     these buffer metrics for machines with high scheduling
+     latencies. Not all possible values that may be configured here are
+     available in all hardware. The driver will to find the nearest
+-    setting supported.</p>
++    setting supported. Modern drivers that support timer-based
++    scheduling ignore these options.</p>
+ 
+     <option>
+       <p><opt>default-fragments=</opt> The default number of
diff --git a/debian/patches/0013-mutex-when-we-fail-to-fill-in-mutex-into-static-mute.patch b/debian/patches/0013-mutex-when-we-fail-to-fill-in-mutex-into-static-mute.patch
new file mode 100644
index 0000000..ecd08cb
--- /dev/null
+++ b/debian/patches/0013-mutex-when-we-fail-to-fill-in-mutex-into-static-mute.patch
@@ -0,0 +1,22 @@
+From 977f59368ba55fac3fe21d7549bc0552daf07d91 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 21 Apr 2009 21:24:33 +0200
+Subject: [PATCH 13/28] mutex: when we fail to fill in mutex into static mutex ptr free it again
+
+---
+ src/pulsecore/mutex-posix.c |    2 ++
+ 1 files changed, 2 insertions(+), 0 deletions(-)
+
+diff --git a/src/pulsecore/mutex-posix.c b/src/pulsecore/mutex-posix.c
+index b3e5256..0ff4bee 100644
+--- a/src/pulsecore/mutex-posix.c
++++ b/src/pulsecore/mutex-posix.c
+@@ -153,6 +153,8 @@ pa_mutex* pa_static_mutex_get(pa_static_mutex *s, pa_bool_t recursive, pa_bool_t
+     if ((pa_atomic_ptr_cmpxchg(&s->ptr, NULL, m)))
+         return m;
+ 
++    pa_mutex_free(m);
++
+     /* Him, filling in failed, so someone else must have filled in
+      * already */
+     pa_assert_se(m = pa_atomic_ptr_load(&s->ptr));
diff --git a/debian/patches/0014-oss-don-t-deadlock-when-we-try-to-resume-an-OSS-devi.patch b/debian/patches/0014-oss-don-t-deadlock-when-we-try-to-resume-an-OSS-devi.patch
new file mode 100644
index 0000000..36635a4
--- /dev/null
+++ b/debian/patches/0014-oss-don-t-deadlock-when-we-try-to-resume-an-OSS-devi.patch
@@ -0,0 +1,52 @@
+From 776b0817f79b475c9725b53c185484b5e3ff6fbb Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 26 May 2009 22:30:36 +0200
+Subject: [PATCH 14/28] oss: don't deadlock when we try to resume an OSS device that lacks a mixer
+
+---
+ src/modules/oss/module-oss.c |   11 +++++++----
+ 1 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/src/modules/oss/module-oss.c b/src/modules/oss/module-oss.c
+index 9f7863f..aa5f918 100644
+--- a/src/modules/oss/module-oss.c
++++ b/src/modules/oss/module-oss.c
+@@ -477,6 +477,7 @@ static void build_pollfd(struct userdata *u) {
+     pollfd->revents = 0;
+ }
+ 
++/* Called from IO context */
+ static int suspend(struct userdata *u) {
+     pa_assert(u);
+     pa_assert(u->fd >= 0);
+@@ -526,6 +527,7 @@ static int suspend(struct userdata *u) {
+     return 0;
+ }
+ 
++/* Called from IO context */
+ static int unsuspend(struct userdata *u) {
+     int m;
+     pa_sample_spec ss, *ss_original;
+@@ -616,10 +618,10 @@ static int unsuspend(struct userdata *u) {
+ 
+     build_pollfd(u);
+ 
+-    if (u->sink)
+-        pa_sink_get_volume(u->sink, TRUE, FALSE);
+-    if (u->source)
+-        pa_source_get_volume(u->source, TRUE);
++    if (u->sink && u->sink->get_volume)
++        u->sink->get_volume(u->sink);
++    if (u->source && u->source->get_volume)
++        u->source->get_volume(u->source);
+ 
+     pa_log_info("Resumed successfully...");
+ 
+@@ -631,6 +633,7 @@ fail:
+     return -1;
+ }
+ 
++/* Called from IO context */
+ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
+     struct userdata *u = PA_SINK(o)->userdata;
+     int ret;
diff --git a/debian/patches/0015-simple-protocol-don-t-hit-an-assert-when-we-call-con.patch b/debian/patches/0015-simple-protocol-don-t-hit-an-assert-when-we-call-con.patch
new file mode 100644
index 0000000..de9e0bc
--- /dev/null
+++ b/debian/patches/0015-simple-protocol-don-t-hit-an-assert-when-we-call-con.patch
@@ -0,0 +1,22 @@
+From b8e05f113a44f46a91d3343e3e4a1eb15c98e1c9 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 29 Apr 2009 04:13:07 +0200
+Subject: [PATCH 15/28] simple-protocol: don't hit an assert when we call connection_unlink() early
+
+---
+ src/pulsecore/protocol-simple.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c
+index 44fe597..776d74b 100644
+--- a/src/pulsecore/protocol-simple.c
++++ b/src/pulsecore/protocol-simple.c
+@@ -130,7 +130,7 @@ static void connection_unlink(connection *c) {
+         c->io = NULL;
+     }
+ 
+-    pa_assert_se(pa_idxset_remove_by_data(c->protocol->connections, c, NULL) == c);
++    pa_idxset_remove_by_data(c->protocol->connections, c, NULL);
+     c->protocol = NULL;
+     connection_unref(c);
+ }
diff --git a/debian/patches/0016-idxset-add-enumeration-macro-PA_IDXSET_FOREACH.patch b/debian/patches/0016-idxset-add-enumeration-macro-PA_IDXSET_FOREACH.patch
new file mode 100644
index 0000000..9ccffd5
--- /dev/null
+++ b/debian/patches/0016-idxset-add-enumeration-macro-PA_IDXSET_FOREACH.patch
@@ -0,0 +1,22 @@
+From bee02ee03fc82f447a358a564a4d922c0f29cfcf Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 29 Apr 2009 01:46:12 +0200
+Subject: [PATCH 16/28] idxset: add enumeration macro PA_IDXSET_FOREACH
+
+---
+ src/pulsecore/idxset.h |    4 ++++
+ 1 files changed, 4 insertions(+), 0 deletions(-)
+
+diff --git a/src/pulsecore/idxset.h b/src/pulsecore/idxset.h
+index 7531ea3..6b9ff47 100644
+--- a/src/pulsecore/idxset.h
++++ b/src/pulsecore/idxset.h
+@@ -103,4 +103,8 @@ unsigned pa_idxset_size(pa_idxset*s);
+ /* Return TRUE of the idxset is empty */
+ pa_bool_t pa_idxset_isempty(pa_idxset *s);
+ 
++
++#define PA_IDXSET_FOREACH(e, s, idx) \
++    for ((e) = pa_idxset_first((s), &(idx)); (e); (e) = pa_idxset_next((s), &(idx)))
++
+ #endif
diff --git a/debian/patches/0017-rescue-streams-when-one-stream-move-fails-try-to-con.patch b/debian/patches/0017-rescue-streams-when-one-stream-move-fails-try-to-con.patch
new file mode 100644
index 0000000..4755c7a
--- /dev/null
+++ b/debian/patches/0017-rescue-streams-when-one-stream-move-fails-try-to-con.patch
@@ -0,0 +1,45 @@
+From b7eff401100af0de381fba66293d21aca7ff36fa Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Fri, 17 Apr 2009 20:30:09 +0200
+Subject: [PATCH 17/28] rescue-streams: when one stream move fails try to continue with the remaining ones
+
+---
+ src/modules/module-rescue-streams.c |   16 ++++++----------
+ 1 files changed, 6 insertions(+), 10 deletions(-)
+
+diff --git a/src/modules/module-rescue-streams.c b/src/modules/module-rescue-streams.c
+index 4f616e0..7c99a9b 100644
+--- a/src/modules/module-rescue-streams.c
++++ b/src/modules/module-rescue-streams.c
+@@ -77,12 +77,10 @@ static pa_hook_result_t sink_hook_callback(pa_core *c, pa_sink *sink, void* user
+     }
+ 
+     while ((i = pa_idxset_first(sink->inputs, NULL))) {
+-        if (pa_sink_input_move_to(i, target, FALSE) < 0) {
++        if (pa_sink_input_move_to(i, target, FALSE) < 0)
+             pa_log_warn("Failed to move sink input %u \"%s\" to %s.", i->index, pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME), target->name);
+-            return PA_HOOK_OK;
+-        }
+-
+-        pa_log_info("Sucessfully moved sink input %u \"%s\" to %s.", i->index, pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME), target->name);
++        else
++            pa_log_info("Sucessfully moved sink input %u \"%s\" to %s.", i->index, pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME), target->name);
+     }
+ 
+ 
+@@ -121,12 +119,10 @@ static pa_hook_result_t source_hook_callback(pa_core *c, pa_source *source, void
+     pa_assert(target != source);
+ 
+     while ((o = pa_idxset_first(source->outputs, NULL))) {
+-        if (pa_source_output_move_to(o, target, FALSE) < 0) {
++        if (pa_source_output_move_to(o, target, FALSE) < 0)
+             pa_log_warn("Failed to move source output %u \"%s\" to %s.", o->index, pa_proplist_gets(o->proplist, PA_PROP_APPLICATION_NAME), target->name);
+-            return PA_HOOK_OK;
+-        }
+-
+-        pa_log_info("Sucessfully moved source output %u \"%s\" to %s.", o->index, pa_proplist_gets(o->proplist, PA_PROP_APPLICATION_NAME), target->name);
++        else
++            pa_log_info("Sucessfully moved source output %u \"%s\" to %s.", o->index, pa_proplist_gets(o->proplist, PA_PROP_APPLICATION_NAME), target->name);
+     }
+ 
+ 
diff --git a/debian/patches/0018-sample-correctly-pass-s24-32-formats.patch b/debian/patches/0018-sample-correctly-pass-s24-32-formats.patch
new file mode 100644
index 0000000..7603d40
--- /dev/null
+++ b/debian/patches/0018-sample-correctly-pass-s24-32-formats.patch
@@ -0,0 +1,31 @@
+From 79510a3b15652b04bffbb798221d27e8d16f4ce2 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Fri, 1 May 2009 04:12:24 +0200
+Subject: [PATCH 18/28] sample: correctly pass s24-32 formats
+
+---
+ src/pulse/sample.c |    8 ++++----
+ 1 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/pulse/sample.c b/src/pulse/sample.c
+index 1e67b03..ed7b1b0 100644
+--- a/src/pulse/sample.c
++++ b/src/pulse/sample.c
+@@ -231,13 +231,13 @@ pa_sample_format_t pa_parse_sample_format(const char *format) {
+     else if (strcasecmp(format, "s24re") == 0)
+         return PA_SAMPLE_S24RE;
+     else if (strcasecmp(format, "s24-32le") == 0)
+-        return PA_SAMPLE_S24LE;
++        return PA_SAMPLE_S24_32LE;
+     else if (strcasecmp(format, "s24-32be") == 0)
+-        return PA_SAMPLE_S24BE;
++        return PA_SAMPLE_S24_32BE;
+     else if (strcasecmp(format, "s24-32ne") == 0 || strcasecmp(format, "s24-32") == 0)
+-        return PA_SAMPLE_S24NE;
++        return PA_SAMPLE_S24_32NE;
+     else if (strcasecmp(format, "s24-32re") == 0)
+-        return PA_SAMPLE_S24RE;
++        return PA_SAMPLE_S24_32RE;
+ 
+     return -1;
+ }
diff --git a/debian/patches/0019-sample-util-fix-iteration-loop-when-adjusting-volume.patch b/debian/patches/0019-sample-util-fix-iteration-loop-when-adjusting-volume.patch
new file mode 100644
index 0000000..a5a0ef0
--- /dev/null
+++ b/debian/patches/0019-sample-util-fix-iteration-loop-when-adjusting-volume.patch
@@ -0,0 +1,37 @@
+From 397f517aafda4efd00532ba7f19e7045aa853c2a Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Fri, 1 May 2009 04:14:40 +0200
+Subject: [PATCH 19/28] sample-util: fix iteration loop when adjusting volume of s24 samples
+
+---
+ src/pulsecore/sample-util.c |    8 ++++----
+ 1 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c
+index 3a9b384..a3e490b 100644
+--- a/src/pulsecore/sample-util.c
++++ b/src/pulsecore/sample-util.c
+@@ -831,9 +831,9 @@ void pa_volume_memchunk(
+ 
+             calc_linear_integer_volume(linear, volume);
+ 
+-            e = (uint8_t*) ptr + c->length/3;
++            e = (uint8_t*) ptr + c->length;
+ 
+-            for (channel = 0, d = ptr; d < e; d++) {
++            for (channel = 0, d = ptr; d < e; d += 3) {
+                 int64_t t;
+ 
+                 t = (int64_t)((int32_t) (PA_READ24NE(d) << 8));
+@@ -854,9 +854,9 @@ void pa_volume_memchunk(
+ 
+             calc_linear_integer_volume(linear, volume);
+ 
+-            e = (uint8_t*) ptr + c->length/3;
++            e = (uint8_t*) ptr + c->length;
+ 
+-            for (channel = 0, d = ptr; d < e; d++) {
++            for (channel = 0, d = ptr; d < e; d += 3) {
+                 int64_t t;
+ 
+                 t = (int64_t)((int32_t) (PA_READ24RE(d) << 8));
diff --git a/debian/patches/0020-sample-util-properly-allocate-silence-block-for-s24-.patch b/debian/patches/0020-sample-util-properly-allocate-silence-block-for-s24-.patch
new file mode 100644
index 0000000..d21fb46
--- /dev/null
+++ b/debian/patches/0020-sample-util-properly-allocate-silence-block-for-s24-.patch
@@ -0,0 +1,31 @@
+From 55244f7a07335115caf2b9cc57aecc0f8cd08030 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Fri, 1 May 2009 04:14:02 +0200
+Subject: [PATCH 20/28] sample-util: properly allocate silence block for s24-32 formats
+
+---
+ src/pulsecore/sample-util.c |    4 ++++
+ 1 files changed, 4 insertions(+), 0 deletions(-)
+
+diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c
+index a3e490b..dda3883 100644
+--- a/src/pulsecore/sample-util.c
++++ b/src/pulsecore/sample-util.c
+@@ -1181,6 +1181,8 @@ pa_memchunk* pa_silence_memchunk_get(pa_silence_cache *cache, pa_mempool *pool,
+             case PA_SAMPLE_S32BE:
+             case PA_SAMPLE_S24LE:
+             case PA_SAMPLE_S24BE:
++            case PA_SAMPLE_S24_32LE:
++            case PA_SAMPLE_S24_32RE:
+             case PA_SAMPLE_FLOAT32LE:
+             case PA_SAMPLE_FLOAT32BE:
+                 cache->blocks[PA_SAMPLE_S16LE] = b = silence_memblock_new(pool, 0);
+@@ -1189,6 +1191,8 @@ pa_memchunk* pa_silence_memchunk_get(pa_silence_cache *cache, pa_mempool *pool,
+                 cache->blocks[PA_SAMPLE_S32BE] = pa_memblock_ref(b);
+                 cache->blocks[PA_SAMPLE_S24LE] = pa_memblock_ref(b);
+                 cache->blocks[PA_SAMPLE_S24BE] = pa_memblock_ref(b);
++                cache->blocks[PA_SAMPLE_S24_32LE] = pa_memblock_ref(b);
++                cache->blocks[PA_SAMPLE_S24_32BE] = pa_memblock_ref(b);
+                 cache->blocks[PA_SAMPLE_FLOAT32LE] = pa_memblock_ref(b);
+                 cache->blocks[PA_SAMPLE_FLOAT32BE] = pa_memblock_ref(b);
+                 break;
diff --git a/debian/patches/0021-sconv-fix-a-few-minor-conversion-issues.patch b/debian/patches/0021-sconv-fix-a-few-minor-conversion-issues.patch
new file mode 100644
index 0000000..2ed2653
--- /dev/null
+++ b/debian/patches/0021-sconv-fix-a-few-minor-conversion-issues.patch
@@ -0,0 +1,58 @@
+From 100af7efac584be9f229f4daf663dbb939f5d929 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Fri, 1 May 2009 04:22:08 +0200
+Subject: [PATCH 21/28] sconv: fix a few minor conversion issues
+
+---
+ src/pulsecore/sconv-s16le.c |   10 +++++-----
+ src/pulsecore/sconv.c       |    2 +-
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/src/pulsecore/sconv-s16le.c b/src/pulsecore/sconv-s16le.c
+index 307ce7b..43b8cb3 100644
+--- a/src/pulsecore/sconv-s16le.c
++++ b/src/pulsecore/sconv-s16le.c
+@@ -370,7 +370,7 @@ void pa_sconv_s24_32le_to_s16ne(unsigned n, const uint32_t *a, int16_t *b) {
+     pa_assert(b);
+ 
+     for (; n > 0; n--) {
+-        *b = (int16_t) ((int32_t) (UINT32_FROM(*a) << 8) >> 16);
++        *b = (int16_t) (((int32_t) (UINT32_FROM(*a) << 8)) >> 16);
+         a++;
+         b++;
+     }
+@@ -416,8 +416,8 @@ void pa_sconv_s24_32le_to_float32ne(unsigned n, const uint32_t *a, float *b) {
+     pa_assert(b);
+ 
+     for (; n > 0; n--) {
+-        int32_t s = (int16_t) ((int32_t) (UINT32_FROM(*a) << 8));
+-        *b = ((float) s) / 0x7FFFFFFF;
++        int32_t s = (int32_t) (UINT32_FROM(*a) << 8);
++        *b = (float) s / (float) 0x7FFFFFFF;
+         a ++;
+         b ++;
+     }
+@@ -428,8 +428,8 @@ void pa_sconv_s24_32le_to_float32re(unsigned n, const uint32_t *a, float *b) {
+     pa_assert(b);
+ 
+     for (; n > 0; n--) {
+-        int32_t s = (int16_t) ((int32_t) (UINT32_FROM(*a) << 8));
+-        float k = ((float) s) / 0x7FFFFFFF;
++        int32_t s = (int32_t) (UINT32_FROM(*a) << 8);
++        float k = (float) s / (float) 0x7FFFFFFF;
+         *b = PA_FLOAT32_SWAP(k);
+         a ++;
+         b ++;
+diff --git a/src/pulsecore/sconv.c b/src/pulsecore/sconv.c
+index 29a9a45..d89f428 100644
+--- a/src/pulsecore/sconv.c
++++ b/src/pulsecore/sconv.c
+@@ -75,7 +75,7 @@ static void u8_from_s16ne(unsigned n, const int16_t *a, uint8_t *b) {
+     pa_assert(b);
+ 
+     for (; n > 0; n--, a++, b++)
+-        *b = (uint8_t) (*a / 0x100 + 0x80);
++        *b = (uint8_t) ((uint16_t) *a >> 8) + (uint8_t) 0x80U;
+ }
+ 
+ /* float32 */
diff --git a/debian/patches/0022-alsa-be-a-bit-more-verbose-when-a-hwparam-call-fails.patch b/debian/patches/0022-alsa-be-a-bit-more-verbose-when-a-hwparam-call-fails.patch
new file mode 100644
index 0000000..f0e7a52
--- /dev/null
+++ b/debian/patches/0022-alsa-be-a-bit-more-verbose-when-a-hwparam-call-fails.patch
@@ -0,0 +1,118 @@
+From 11a048bd9dbef1a7ea3c79799248bc2d661cee5f Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Thu, 14 May 2009 01:25:07 +0200
+Subject: [PATCH 22/28] alsa: be a bit more verbose when a hwparam call fails
+
+---
+ src/modules/alsa/alsa-util.c |   45 ++++++++++++++++++++++++++++++++++-------
+ 1 files changed, 37 insertions(+), 8 deletions(-)
+
+diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c
+index 34cb6d6..b3de415 100644
+--- a/src/modules/alsa/alsa-util.c
++++ b/src/modules/alsa/alsa-util.c
+@@ -279,6 +279,11 @@ static int set_format(snd_pcm_t *pcm_handle, snd_pcm_hw_params_t *hwparams, pa_s
+     if ((ret = snd_pcm_hw_params_set_format(pcm_handle, hwparams, format_trans[*f])) >= 0)
+         return ret;
+ 
++    pa_log_debug("snd_pcm_hw_params_set_format(%s) failed: %s",
++                 snd_pcm_format_description(format_trans[*f]),
++                 pa_alsa_strerror(ret));
++
++
+     if (*f == PA_SAMPLE_FLOAT32BE)
+         *f = PA_SAMPLE_FLOAT32LE;
+     else if (*f == PA_SAMPLE_FLOAT32LE)
+@@ -305,6 +310,10 @@ static int set_format(snd_pcm_t *pcm_handle, snd_pcm_hw_params_t *hwparams, pa_s
+     if ((ret = snd_pcm_hw_params_set_format(pcm_handle, hwparams, format_trans[*f])) >= 0)
+         return ret;
+ 
++    pa_log_debug("snd_pcm_hw_params_set_format(%s) failed: %s",
++                 snd_pcm_format_description(format_trans[*f]),
++                 pa_alsa_strerror(ret));
++
+ try_auto:
+ 
+     for (i = 0; try_order[i] != PA_SAMPLE_INVALID; i++) {
+@@ -312,6 +321,10 @@ try_auto:
+ 
+         if ((ret = snd_pcm_hw_params_set_format(pcm_handle, hwparams, format_trans[*f])) >= 0)
+             return ret;
++
++        pa_log_debug("snd_pcm_hw_params_set_format(%s) failed: %s",
++                     snd_pcm_format_description(format_trans[*f]),
++                     pa_alsa_strerror(ret));
+     }
+ 
+     return -1;
+@@ -345,11 +358,15 @@ int pa_alsa_set_hw_params(
+ 
+     snd_pcm_hw_params_alloca(&hwparams);
+ 
+-    if ((ret = snd_pcm_hw_params_any(pcm_handle, hwparams)) < 0)
++    if ((ret = snd_pcm_hw_params_any(pcm_handle, hwparams)) < 0) {
++        pa_log_debug("snd_pcm_hw_params_any() failed: %s", pa_alsa_strerror(ret));
+         goto finish;
++    }
+ 
+-    if ((ret = snd_pcm_hw_params_set_rate_resample(pcm_handle, hwparams, 0)) < 0)
++    if ((ret = snd_pcm_hw_params_set_rate_resample(pcm_handle, hwparams, 0)) < 0) {
++        pa_log_debug("snd_pcm_hw_params_set_rate_resample() failed: %s", pa_alsa_strerror(ret));
+         goto finish;
++    }
+ 
+     if (_use_mmap) {
+ 
+@@ -357,14 +374,18 @@ int pa_alsa_set_hw_params(
+ 
+             /* mmap() didn't work, fall back to interleaved */
+ 
+-            if ((ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
++            if ((ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
++                pa_log_debug("snd_pcm_hw_params_set_access() failed: %s", pa_alsa_strerror(ret));
+                 goto finish;
++            }
+ 
+             _use_mmap = FALSE;
+         }
+ 
+-    } else if ((ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
++    } else if ((ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
++        pa_log_debug("snd_pcm_hw_params_set_access() failed: %s", pa_alsa_strerror(ret));
+         goto finish;
++    }
+ 
+     if (!_use_mmap)
+         _use_tsched = FALSE;
+@@ -372,19 +393,27 @@ int pa_alsa_set_hw_params(
+     if ((ret = set_format(pcm_handle, hwparams, &f)) < 0)
+         goto finish;
+ 
+-    if ((ret = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &r, NULL)) < 0)
++    if ((ret = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &r, NULL)) < 0) {
++        pa_log_debug("snd_pcm_hw_params_set_rate_near() failed: %s", pa_alsa_strerror(ret));
+         goto finish;
++    }
+ 
+     if (require_exact_channel_number) {
+-        if ((ret = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, c)) < 0)
++        if ((ret = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, c)) < 0) {
++            pa_log_debug("snd_pcm_hw_params_set_channels() failed: %s", pa_alsa_strerror(ret));
+             goto finish;
++        }
+     } else {
+-        if ((ret = snd_pcm_hw_params_set_channels_near(pcm_handle, hwparams, &c)) < 0)
++        if ((ret = snd_pcm_hw_params_set_channels_near(pcm_handle, hwparams, &c)) < 0) {
++            pa_log_debug("snd_pcm_hw_params_set_channels_near() failed: %s", pa_alsa_strerror(ret));
+             goto finish;
++        }
+     }
+ 
+-    if ((ret = snd_pcm_hw_params_set_periods_integer(pcm_handle, hwparams)) < 0)
++    if ((ret = snd_pcm_hw_params_set_periods_integer(pcm_handle, hwparams)) < 0) {
++        pa_log_debug("snd_pcm_hw_params_set_periods_integer() failed: %s", pa_alsa_strerror(ret));
+         goto finish;
++    }
+ 
+     if (_period_size && tsched_size && _periods) {
+ 
diff --git a/debian/patches/0023-rescue-make-we-don-t-end-up-in-an-endless-loop-when-.patch b/debian/patches/0023-rescue-make-we-don-t-end-up-in-an-endless-loop-when-.patch
new file mode 100644
index 0000000..ee46823
--- /dev/null
+++ b/debian/patches/0023-rescue-make-we-don-t-end-up-in-an-endless-loop-when-.patch
@@ -0,0 +1,132 @@
+From 1ab53c43c17943d49fc80c86ef2b513354eddc63 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Thu, 14 May 2009 03:52:13 +0200
+Subject: [PATCH 23/28] rescue: make we don't end up in an endless loop when we can't move a sink input
+
+---
+ src/modules/module-rescue-streams.c |   38 +++++++++++++++++++---------------
+ 1 files changed, 21 insertions(+), 17 deletions(-)
+
+diff --git a/src/modules/module-rescue-streams.c b/src/modules/module-rescue-streams.c
+index 7c99a9b..c22711a 100644
+--- a/src/modules/module-rescue-streams.c
++++ b/src/modules/module-rescue-streams.c
+@@ -31,6 +31,7 @@
+ #include <pulsecore/modargs.h>
+ #include <pulsecore/log.h>
+ #include <pulsecore/namereg.h>
++#include <pulsecore/core-util.h>
+ 
+ #include "module-rescue-streams-symdef.h"
+ 
+@@ -49,6 +50,7 @@ struct userdata {
+ 
+ static pa_hook_result_t sink_hook_callback(pa_core *c, pa_sink *sink, void* userdata) {
+     pa_sink_input *i;
++    uint32_t idx;
+     pa_sink *target;
+ 
+     pa_assert(c);
+@@ -58,15 +60,14 @@ static pa_hook_result_t sink_hook_callback(pa_core *c, pa_sink *sink, void* user
+     if (c->state == PA_CORE_SHUTDOWN)
+         return PA_HOOK_OK;
+ 
+-    if (!pa_idxset_size(sink->inputs)) {
++    if (pa_idxset_size(sink->inputs) <= 0) {
+         pa_log_debug("No sink inputs to move away.");
+         return PA_HOOK_OK;
+     }
+ 
+     if (!(target = pa_namereg_get(c, NULL, PA_NAMEREG_SINK)) || target == sink) {
+-        uint32_t idx;
+ 
+-        for (target = pa_idxset_first(c->sinks, &idx); target; target = pa_idxset_next(c->sinks, &idx))
++        PA_IDXSET_FOREACH(target, c->sinks, idx)
+             if (target != sink)
+                 break;
+ 
+@@ -76,20 +77,24 @@ static pa_hook_result_t sink_hook_callback(pa_core *c, pa_sink *sink, void* user
+         }
+     }
+ 
+-    while ((i = pa_idxset_first(sink->inputs, NULL))) {
++    pa_assert(target != sink);
++
++    PA_IDXSET_FOREACH(i, sink->inputs, idx) {
+         if (pa_sink_input_move_to(i, target, FALSE) < 0)
+-            pa_log_warn("Failed to move sink input %u \"%s\" to %s.", i->index, pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME), target->name);
++            pa_log_info("Failed to move sink input %u \"%s\" to %s.", i->index,
++                        pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME)), target->name);
+         else
+-            pa_log_info("Sucessfully moved sink input %u \"%s\" to %s.", i->index, pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME), target->name);
++            pa_log_info("Sucessfully moved sink input %u \"%s\" to %s.", i->index,
++                        pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME)), target->name);
+     }
+ 
+-
+     return PA_HOOK_OK;
+ }
+ 
+ static pa_hook_result_t source_hook_callback(pa_core *c, pa_source *source, void* userdata) {
+     pa_source_output *o;
+     pa_source *target;
++    uint32_t idx;
+ 
+     pa_assert(c);
+     pa_assert(source);
+@@ -98,15 +103,14 @@ static pa_hook_result_t source_hook_callback(pa_core *c, pa_source *source, void
+     if (c->state == PA_CORE_SHUTDOWN)
+         return PA_HOOK_OK;
+ 
+-    if (!pa_idxset_size(source->outputs)) {
++    if (pa_idxset_size(source->outputs) <= 0) {
+         pa_log_debug("No source outputs to move away.");
+         return PA_HOOK_OK;
+     }
+ 
+     if (!(target = pa_namereg_get(c, NULL, PA_NAMEREG_SOURCE)) || target == source) {
+-        uint32_t idx;
+ 
+-        for (target = pa_idxset_first(c->sources, &idx); target; target = pa_idxset_next(c->sources, &idx))
++        PA_IDXSET_FOREACH(target, c->sources, idx)
+             if (target != source && !target->monitor_of == !source->monitor_of)
+                 break;
+ 
+@@ -118,19 +122,20 @@ static pa_hook_result_t source_hook_callback(pa_core *c, pa_source *source, void
+ 
+     pa_assert(target != source);
+ 
+-    while ((o = pa_idxset_first(source->outputs, NULL))) {
++    PA_IDXSET_FOREACH(o, source->outputs, idx) {
+         if (pa_source_output_move_to(o, target, FALSE) < 0)
+-            pa_log_warn("Failed to move source output %u \"%s\" to %s.", o->index, pa_proplist_gets(o->proplist, PA_PROP_APPLICATION_NAME), target->name);
++            pa_log_info("Failed to move source output %u \"%s\" to %s.", o->index,
++                        pa_strnull(pa_proplist_gets(o->proplist, PA_PROP_APPLICATION_NAME)), target->name);
+         else
+-            pa_log_info("Sucessfully moved source output %u \"%s\" to %s.", o->index, pa_proplist_gets(o->proplist, PA_PROP_APPLICATION_NAME), target->name);
++            pa_log_info("Sucessfully moved source output %u \"%s\" to %s.", o->index,
++                        pa_strnull(pa_proplist_gets(o->proplist, PA_PROP_APPLICATION_NAME)), target->name);
+     }
+ 
+-
+     return PA_HOOK_OK;
+ }
+ 
+ int pa__init(pa_module*m) {
+-    pa_modargs *ma = NULL;
++    pa_modargs *ma;
+     struct userdata *u;
+ 
+     pa_assert(m);
+@@ -153,10 +158,9 @@ void pa__done(pa_module*m) {
+ 
+     pa_assert(m);
+ 
+-    if (!m->userdata)
++    if (!(u = m->userdata))
+         return;
+ 
+-    u = m->userdata;
+     if (u->sink_slot)
+         pa_hook_slot_free(u->sink_slot);
+     if (u->source_slot)
diff --git a/debian/patches/0024-core-introduce-pa_-sink-source-_set_fixed_latency.patch b/debian/patches/0024-core-introduce-pa_-sink-source-_set_fixed_latency.patch
new file mode 100644
index 0000000..cea193f
--- /dev/null
+++ b/debian/patches/0024-core-introduce-pa_-sink-source-_set_fixed_latency.patch
@@ -0,0 +1,236 @@
+From c41d9c71667de6d6e9aab077ac58b7371594bbef Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Fri, 8 May 2009 01:56:21 +0200
+Subject: [PATCH 24/28] core: introduce pa_{sink,source}_set_fixed_latency()
+
+This allows us to forward the fixed latency directly from the sink to
+the monitor source withut having to wait for pa_sink_put().
+---
+ src/modules/alsa/alsa-sink.c                    |    4 ++--
+ src/modules/alsa/alsa-source.c                  |    4 ++--
+ src/modules/bluetooth/module-bluetooth-device.c |   12 ++++++------
+ src/modules/module-pipe-sink.c                  |    2 +-
+ src/modules/module-pipe-source.c                |    2 +-
+ src/modules/module-sine-source.c                |    3 +--
+ src/modules/oss/module-oss.c                    |    4 ++--
+ src/pulsecore/sink.c                            |   16 ++++++++++++++++
+ src/pulsecore/sink.h                            |    1 +
+ src/pulsecore/source.c                          |   15 +++++++++++++++
+ src/pulsecore/source.h                          |    1 +
+ 11 files changed, 48 insertions(+), 16 deletions(-)
+
+diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
+index a544b58..94e15df 100644
+--- a/src/modules/alsa/alsa-sink.c
++++ b/src/modules/alsa/alsa-sink.c
+@@ -473,7 +473,7 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle
+             u->since_start += frames * u->frame_size;
+ 
+ #ifdef DEBUG_TIMING
+-            pa_log_debug("Wrote %lu bytes", (unsigned long) (frames * u->frame_size));
++            pa_log_debug("Wrote %lu bytes (of possible %lu bytes)", (unsigned long) (frames * u->frame_size), (unsigned long) n_bytes);
+ #endif
+ 
+             if ((size_t) frames * u->frame_size >= n_bytes)
+@@ -1730,7 +1730,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
+         pa_log_info("Time scheduling watermark is %0.2fms",
+                     (double) pa_bytes_to_usec(u->tsched_watermark, &ss) / PA_USEC_PER_MSEC);
+     } else
+-        u->sink->fixed_latency = pa_bytes_to_usec(u->hwbuf_size, &ss);
++        pa_sink_set_fixed_latency(u->sink, pa_bytes_to_usec(u->hwbuf_size, &ss));
+ 
+     reserve_update(u);
+ 
+diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
+index 5d8e349..c2f905a 100644
+--- a/src/modules/alsa/alsa-source.c
++++ b/src/modules/alsa/alsa-source.c
+@@ -455,7 +455,7 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled
+             u->read_count += frames * u->frame_size;
+ 
+ #ifdef DEBUG_TIMING
+-            pa_log_debug("Read %lu bytes", (unsigned long) (frames * u->frame_size));
++            pa_log_debug("Read %lu bytes (of possible %lu bytes)", (unsigned long) (frames * u->frame_size), (unsigned long) n_bytes);
+ #endif
+ 
+             if ((size_t) frames * u->frame_size >= n_bytes)
+@@ -1582,7 +1582,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
+         pa_log_info("Time scheduling watermark is %0.2fms",
+                     (double) pa_bytes_to_usec(u->tsched_watermark, &ss) / PA_USEC_PER_MSEC);
+     } else
+-        u->source->fixed_latency = pa_bytes_to_usec(u->hwbuf_size, &ss);
++        pa_source_set_fixed_latency(u->source, pa_bytes_to_usec(u->hwbuf_size, &ss));
+ 
+     reserve_update(u);
+ 
+diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c
+index 90f6486..3465b80 100644
+--- a/src/modules/bluetooth/module-bluetooth-device.c
++++ b/src/modules/bluetooth/module-bluetooth-device.c
+@@ -1608,9 +1608,9 @@ static int add_sink(struct userdata *u) {
+         u->sink->parent.process_msg = sink_process_msg;
+ 
+         pa_sink_set_max_request(u->sink, u->block_size);
+-        u->sink->fixed_latency =
+-            (u->profile == PROFILE_A2DP ? FIXED_LATENCY_PLAYBACK_A2DP : FIXED_LATENCY_PLAYBACK_HSP) +
+-            pa_bytes_to_usec(u->block_size, &u->sample_spec);
++        pa_sink_set_fixed_latency(u->sink,
++                                  (u->profile == PROFILE_A2DP ? FIXED_LATENCY_PLAYBACK_A2DP : FIXED_LATENCY_PLAYBACK_HSP) +
++                                  pa_bytes_to_usec(u->block_size, &u->sample_spec));
+     }
+ 
+     if (u->profile == PROFILE_HSP) {
+@@ -1659,9 +1659,9 @@ static int add_source(struct userdata *u) {
+         u->source->userdata = u;
+         u->source->parent.process_msg = source_process_msg;
+ 
+-        u->source->fixed_latency =
+-            (/* u->profile == PROFILE_A2DP ? FIXED_LATENCY_RECORD_A2DP : */ FIXED_LATENCY_RECORD_HSP) +
+-            pa_bytes_to_usec(u->block_size, &u->sample_spec);
++        pa_source_set_fixed_latency(u->source,
++                                    (/* u->profile == PROFILE_A2DP ? FIXED_LATENCY_RECORD_A2DP : */ FIXED_LATENCY_RECORD_HSP) +
++                                    pa_bytes_to_usec(u->block_size, &u->sample_spec));
+     }
+ 
+     if (u->profile == PROFILE_HSP) {
+diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c
+index 9d3e55d..304d01c 100644
+--- a/src/modules/module-pipe-sink.c
++++ b/src/modules/module-pipe-sink.c
+@@ -293,7 +293,7 @@ int pa__init(pa_module*m) {
+     pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
+     pa_sink_set_rtpoll(u->sink, u->rtpoll);
+     pa_sink_set_max_request(u->sink, PIPE_BUF);
+-    u->sink->fixed_latency = pa_bytes_to_usec(PIPE_BUF, &u->sink->sample_spec);
++    pa_sink_set_fixed_latency(u->sink, pa_bytes_to_usec(PIPE_BUF, &u->sink->sample_spec));
+ 
+     u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1);
+     pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
+diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c
+index df72d79..6ed4fbf 100644
+--- a/src/modules/module-pipe-source.c
++++ b/src/modules/module-pipe-source.c
+@@ -277,7 +277,7 @@ int pa__init(pa_module*m) {
+ 
+     pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
+     pa_source_set_rtpoll(u->source, u->rtpoll);
+-    u->source->fixed_latency = pa_bytes_to_usec(PIPE_BUF, &u->source->sample_spec);
++    pa_source_set_fixed_latency(u->source, pa_bytes_to_usec(PIPE_BUF, &u->source->sample_spec));
+ 
+     u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1);
+     pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
+diff --git a/src/modules/module-sine-source.c b/src/modules/module-sine-source.c
+index a5f1ce7..a6e15d8 100644
+--- a/src/modules/module-sine-source.c
++++ b/src/modules/module-sine-source.c
+@@ -264,8 +264,7 @@ int pa__init(pa_module*m) {
+ 
+     pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
+     pa_source_set_rtpoll(u->source, u->rtpoll);
+-    u->source->fixed_latency = u->block_usec;
+-
++    pa_source_set_fixed_latency(u->source, u->block_usec);
+ 
+     if (!(u->thread = pa_thread_new(thread_func, u))) {
+         pa_log("Failed to create thread.");
+diff --git a/src/modules/oss/module-oss.c b/src/modules/oss/module-oss.c
+index aa5f918..d6f549c 100644
+--- a/src/modules/oss/module-oss.c
++++ b/src/modules/oss/module-oss.c
+@@ -1328,8 +1328,8 @@ int pa__init(pa_module*m) {
+ 
+         pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
+         pa_source_set_rtpoll(u->source, u->rtpoll);
++        pa_source_set_fixed_latency(u->source, pa_bytes_to_usec(u->in_hwbuf_size, &u->source->sample_spec));
+         u->source->refresh_volume = TRUE;
+-        u->source->fixed_latency = pa_bytes_to_usec(u->in_hwbuf_size, &u->source->sample_spec);
+ 
+         if (use_mmap)
+             u->in_mmap_memblocks = pa_xnew0(pa_memblock*, u->in_nfrags);
+@@ -1390,8 +1390,8 @@ int pa__init(pa_module*m) {
+ 
+         pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
+         pa_sink_set_rtpoll(u->sink, u->rtpoll);
++        pa_sink_set_fixed_latency(u->sink, pa_bytes_to_usec(u->out_hwbuf_size, &u->sink->sample_spec));
+         u->sink->refresh_volume = TRUE;
+-        u->sink->fixed_latency = pa_bytes_to_usec(u->out_hwbuf_size, &u->sink->sample_spec);
+ 
+         pa_sink_set_max_request(u->sink, u->out_hwbuf_size);
+ 
+diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
+index c99f9a8..2225886 100644
+--- a/src/pulsecore/sink.c
++++ b/src/pulsecore/sink.c
+@@ -2054,6 +2054,22 @@ void pa_sink_set_latency_range_within_thread(pa_sink *s, pa_usec_t min_latency,
+     pa_source_set_latency_range_within_thread(s->monitor_source, min_latency, max_latency);
+ }
+ 
++/* Called from main thread, before the sink is put */
++void pa_sink_set_fixed_latency(pa_sink *s, pa_usec_t latency) {
++    pa_sink_assert_ref(s);
++
++    pa_assert(pa_sink_get_state(s) == PA_SINK_INIT);
++
++    if (latency < ABSOLUTE_MIN_LATENCY)
++        latency = ABSOLUTE_MIN_LATENCY;
++
++    if (latency > ABSOLUTE_MAX_LATENCY)
++        latency = ABSOLUTE_MAX_LATENCY;
++
++    s->fixed_latency = latency;
++    pa_source_set_fixed_latency(s->monitor_source, latency);
++}
++
+ /* Called from main context */
+ size_t pa_sink_get_max_rewind(pa_sink *s) {
+     size_t r;
+diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h
+index 352282b..e33b3cf 100644
+--- a/src/pulsecore/sink.h
++++ b/src/pulsecore/sink.h
+@@ -229,6 +229,7 @@ void pa_sink_set_rtpoll(pa_sink *s, pa_rtpoll *p);
+ void pa_sink_set_max_rewind(pa_sink *s, size_t max_rewind);
+ void pa_sink_set_max_request(pa_sink *s, size_t max_request);
+ void pa_sink_set_latency_range(pa_sink *s, pa_usec_t min_latency, pa_usec_t max_latency);
++void pa_sink_set_fixed_latency(pa_sink *s, pa_usec_t latency);
+ 
+ void pa_sink_detach(pa_sink *s);
+ void pa_sink_attach(pa_sink *s);
+diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
+index 0baaed1..e8deaf7 100644
+--- a/src/pulsecore/source.c
++++ b/src/pulsecore/source.c
+@@ -1280,6 +1280,21 @@ void pa_source_set_latency_range_within_thread(pa_source *s, pa_usec_t min_laten
+     pa_source_invalidate_requested_latency(s);
+ }
+ 
++/* Called from main thread, before the source is put */
++void pa_source_set_fixed_latency(pa_source *s, pa_usec_t latency) {
++    pa_source_assert_ref(s);
++
++    pa_assert(pa_source_get_state(s) == PA_SOURCE_INIT);
++
++    if (latency < ABSOLUTE_MIN_LATENCY)
++        latency = ABSOLUTE_MIN_LATENCY;
++
++    if (latency > ABSOLUTE_MAX_LATENCY)
++        latency = ABSOLUTE_MAX_LATENCY;
++
++    s->fixed_latency = latency;
++}
++
+ /* Called from main thread */
+ size_t pa_source_get_max_rewind(pa_source *s) {
+     size_t r;
+diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h
+index b502c22..2978f57 100644
+--- a/src/pulsecore/source.h
++++ b/src/pulsecore/source.h
+@@ -210,6 +210,7 @@ void pa_source_set_rtpoll(pa_source *s, pa_rtpoll *p);
+ 
+ void pa_source_set_max_rewind(pa_source *s, size_t max_rewind);
+ void pa_source_set_latency_range(pa_source *s, pa_usec_t min_latency, pa_usec_t max_latency);
++void pa_source_set_fixed_latency(pa_source *s, pa_usec_t latency);
+ 
+ void pa_source_detach(pa_source *s);
+ void pa_source_attach(pa_source *s);
diff --git a/debian/patches/0025-core-cache-requested-latency-only-when-we-are-runnin.patch b/debian/patches/0025-core-cache-requested-latency-only-when-we-are-runnin.patch
new file mode 100644
index 0000000..fda25a5
--- /dev/null
+++ b/debian/patches/0025-core-cache-requested-latency-only-when-we-are-runnin.patch
@@ -0,0 +1,46 @@
+From c73733777f11080373264ed4e992c6860809898e Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Fri, 8 May 2009 02:02:36 +0200
+Subject: [PATCH 25/28] core: cache requested latency only when we are running, not while we are still constructing
+
+---
+ src/pulsecore/sink.c   |    7 +++++--
+ src/pulsecore/source.c |    7 +++++--
+ 2 files changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
+index 2225886..161b7c9 100644
+--- a/src/pulsecore/sink.c
++++ b/src/pulsecore/sink.c
+@@ -1867,8 +1867,11 @@ pa_usec_t pa_sink_get_requested_latency_within_thread(pa_sink *s) {
+     if (result != (pa_usec_t) -1)
+         result = PA_CLAMP(result, s->thread_info.min_latency, s->thread_info.max_latency);
+ 
+-    s->thread_info.requested_latency = result;
+-    s->thread_info.requested_latency_valid = TRUE;
++    if (PA_SINK_IS_LINKED(s->thread_info.state)) {
++        /* Only cache if properly initialized */
++        s->thread_info.requested_latency = result;
++        s->thread_info.requested_latency_valid = TRUE;
++    }
+ 
+     return result;
+ }
+diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
+index e8deaf7..8a4c8c4 100644
+--- a/src/pulsecore/source.c
++++ b/src/pulsecore/source.c
+@@ -1122,8 +1122,11 @@ pa_usec_t pa_source_get_requested_latency_within_thread(pa_source *s) {
+     if (result != (pa_usec_t) -1)
+         result = PA_CLAMP(result, s->thread_info.min_latency, s->thread_info.max_latency);
+ 
+-    s->thread_info.requested_latency = result;
+-    s->thread_info.requested_latency_valid = TRUE;
++    if (PA_SOURCE_IS_LINKED(s->thread_info.state)) {
++        /* Only cache this if we are fully set up */
++        s->thread_info.requested_latency = result;
++        s->thread_info.requested_latency_valid = TRUE;
++    }
+ 
+     return result;
+ }
diff --git a/debian/patches/0026-sample-fix-build-on-BE-archs.patch b/debian/patches/0026-sample-fix-build-on-BE-archs.patch
new file mode 100644
index 0000000..03b2074
--- /dev/null
+++ b/debian/patches/0026-sample-fix-build-on-BE-archs.patch
@@ -0,0 +1,22 @@
+From 85fb360fe3b9d3b3fb4e537373f4dc9202ca5e13 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 8 Jun 2009 18:22:19 +0200
+Subject: [PATCH 26/28] sample: fix build on BE archs
+
+---
+ src/pulsecore/sample-util.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c
+index dda3883..5b8ccf5 100644
+--- a/src/pulsecore/sample-util.c
++++ b/src/pulsecore/sample-util.c
+@@ -1182,7 +1182,7 @@ pa_memchunk* pa_silence_memchunk_get(pa_silence_cache *cache, pa_mempool *pool,
+             case PA_SAMPLE_S24LE:
+             case PA_SAMPLE_S24BE:
+             case PA_SAMPLE_S24_32LE:
+-            case PA_SAMPLE_S24_32RE:
++            case PA_SAMPLE_S24_32BE:
+             case PA_SAMPLE_FLOAT32LE:
+             case PA_SAMPLE_FLOAT32BE:
+                 cache->blocks[PA_SAMPLE_S16LE] = b = silence_memblock_new(pool, 0);
diff --git a/debian/patches/0027-alsa-properly-convert-return-values-of-snd_strerror-.patch b/debian/patches/0027-alsa-properly-convert-return-values-of-snd_strerror-.patch
new file mode 100644
index 0000000..94ed91b
--- /dev/null
+++ b/debian/patches/0027-alsa-properly-convert-return-values-of-snd_strerror-.patch
@@ -0,0 +1,532 @@
+From 42885f1f9743a0e2cd7f1ded1cab688e5df10bc8 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Sun, 19 Apr 2009 19:22:51 +0200
+Subject: [PATCH 27/28] alsa: properly convert return values of snd_strerror() to utf8
+
+---
+ src/modules/alsa/alsa-sink.c        |   28 ++++++------
+ src/modules/alsa/alsa-source.c      |   24 +++++-----
+ src/modules/alsa/alsa-util.c        |   83 ++++++++++++++++++++++++-----------
+ src/modules/alsa/alsa-util.h        |    2 +
+ src/modules/alsa/module-alsa-card.c |    2 +-
+ 5 files changed, 86 insertions(+), 53 deletions(-)
+
+diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
+index 94e15df..44c6219 100644
+--- a/src/modules/alsa/alsa-sink.c
++++ b/src/modules/alsa/alsa-sink.c
+@@ -281,7 +281,7 @@ static int try_recover(struct userdata *u, const char *call, int err) {
+     pa_assert(call);
+     pa_assert(err < 0);
+ 
+-    pa_log_debug("%s: %s", call, snd_strerror(err));
++    pa_log_debug("%s: %s", call, pa_alsa_strerror(err));
+ 
+     pa_assert(err != -EAGAIN);
+ 
+@@ -289,7 +289,7 @@ static int try_recover(struct userdata *u, const char *call, int err) {
+         pa_log_debug("%s: Buffer underrun!", call);
+ 
+     if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) < 0) {
+-        pa_log("%s: %s", call, snd_strerror(err));
++        pa_log("%s: %s", call, pa_alsa_strerror(err));
+         return -1;
+     }
+ 
+@@ -636,12 +636,12 @@ static void update_smoother(struct userdata *u) {
+     /* Let's update the time smoother */
+ 
+     if (PA_UNLIKELY((err = pa_alsa_safe_delay(u->pcm_handle, &delay, u->hwbuf_size, &u->sink->sample_spec)) < 0)) {
+-        pa_log_warn("Failed to query DSP status data: %s", snd_strerror(err));
++        pa_log_warn("Failed to query DSP status data: %s", pa_alsa_strerror(err));
+         return;
+     }
+ 
+     if (PA_UNLIKELY((err = snd_pcm_status(u->pcm_handle, status)) < 0))
+-        pa_log_warn("Failed to get timestamp: %s", snd_strerror(err));
++        pa_log_warn("Failed to get timestamp: %s", pa_alsa_strerror(err));
+     else {
+         snd_htimestamp_t htstamp = { 0, 0 };
+         snd_pcm_status_get_htstamp(status, &htstamp);
+@@ -764,7 +764,7 @@ static int update_sw_params(struct userdata *u) {
+     pa_log_debug("setting avail_min=%lu", (unsigned long) avail_min);
+ 
+     if ((err = pa_alsa_set_sw_params(u->pcm_handle, avail_min)) < 0) {
+-        pa_log("Failed to set software parameters: %s", snd_strerror(err));
++        pa_log("Failed to set software parameters: %s", pa_alsa_strerror(err));
+         return err;
+     }
+ 
+@@ -792,7 +792,7 @@ static int unsuspend(struct userdata *u) {
+                             SND_PCM_NO_AUTO_RESAMPLE|
+                             SND_PCM_NO_AUTO_CHANNELS|
+                             SND_PCM_NO_AUTO_FORMAT)) < 0) {
+-        pa_log("Error opening PCM device %s: %s", u->device_name, snd_strerror(err));
++        pa_log("Error opening PCM device %s: %s", u->device_name, pa_alsa_strerror(err));
+         goto fail;
+     }
+ 
+@@ -803,7 +803,7 @@ static int unsuspend(struct userdata *u) {
+     d = u->use_tsched;
+ 
+     if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, u->hwbuf_size / u->frame_size, &b, &d, TRUE)) < 0) {
+-        pa_log("Failed to set hardware parameters: %s", snd_strerror(err));
++        pa_log("Failed to set hardware parameters: %s", pa_alsa_strerror(err));
+         goto fail;
+     }
+ 
+@@ -1030,7 +1030,7 @@ static void sink_get_volume_cb(pa_sink *s) {
+     return;
+ 
+ fail:
+-    pa_log_error("Unable to read volume: %s", snd_strerror(err));
++    pa_log_error("Unable to read volume: %s", pa_alsa_strerror(err));
+ }
+ 
+ static void sink_set_volume_cb(pa_sink *s) {
+@@ -1141,7 +1141,7 @@ static void sink_set_volume_cb(pa_sink *s) {
+     return;
+ 
+ fail:
+-    pa_log_error("Unable to set volume: %s", snd_strerror(err));
++    pa_log_error("Unable to set volume: %s", pa_alsa_strerror(err));
+ }
+ 
+ static void sink_get_mute_cb(pa_sink *s) {
+@@ -1152,7 +1152,7 @@ static void sink_get_mute_cb(pa_sink *s) {
+     pa_assert(u->mixer_elem);
+ 
+     if ((err = snd_mixer_selem_get_playback_switch(u->mixer_elem, 0, &sw)) < 0) {
+-        pa_log_error("Unable to get switch: %s", snd_strerror(err));
++        pa_log_error("Unable to get switch: %s", pa_alsa_strerror(err));
+         return;
+     }
+ 
+@@ -1167,7 +1167,7 @@ static void sink_set_mute_cb(pa_sink *s) {
+     pa_assert(u->mixer_elem);
+ 
+     if ((err = snd_mixer_selem_set_playback_switch_all(u->mixer_elem, !s->muted)) < 0) {
+-        pa_log_error("Unable to set switch: %s", snd_strerror(err));
++        pa_log_error("Unable to set switch: %s", pa_alsa_strerror(err));
+         return;
+     }
+ }
+@@ -1206,7 +1206,7 @@ static int process_rewind(struct userdata *u) {
+     pa_log_debug("Requested to rewind %lu bytes.", (unsigned long) rewind_nbytes);
+ 
+     if (PA_UNLIKELY((unused = pa_alsa_safe_avail(u->pcm_handle, u->hwbuf_size, &u->sink->sample_spec)) < 0)) {
+-        pa_log("snd_pcm_avail() failed: %s", snd_strerror((int) unused));
++        pa_log("snd_pcm_avail() failed: %s", pa_alsa_strerror((int) unused));
+         return -1;
+     }
+ 
+@@ -1228,7 +1228,7 @@ static int process_rewind(struct userdata *u) {
+         in_frames = (snd_pcm_sframes_t) (rewind_nbytes / u->frame_size);
+         pa_log_debug("before: %lu", (unsigned long) in_frames);
+         if ((out_frames = snd_pcm_rewind(u->pcm_handle, (snd_pcm_uframes_t) in_frames)) < 0) {
+-            pa_log("snd_pcm_rewind() failed: %s", snd_strerror((int) out_frames));
++            pa_log("snd_pcm_rewind() failed: %s", pa_alsa_strerror((int) out_frames));
+             return -1;
+         }
+         pa_log_debug("after: %lu", (unsigned long) out_frames);
+@@ -1359,7 +1359,7 @@ static void thread_func(void *userdata) {
+             pollfd = pa_rtpoll_item_get_pollfd(u->alsa_rtpoll_item, &n);
+ 
+             if ((err = snd_pcm_poll_descriptors_revents(u->pcm_handle, pollfd, n, &revents)) < 0) {
+-                pa_log("snd_pcm_poll_descriptors_revents() failed: %s", snd_strerror(err));
++                pa_log("snd_pcm_poll_descriptors_revents() failed: %s", pa_alsa_strerror(err));
+                 goto fail;
+             }
+ 
+diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
+index c2f905a..ba29738 100644
+--- a/src/modules/alsa/alsa-source.c
++++ b/src/modules/alsa/alsa-source.c
+@@ -278,7 +278,7 @@ static int try_recover(struct userdata *u, const char *call, int err) {
+     pa_assert(call);
+     pa_assert(err < 0);
+ 
+-    pa_log_debug("%s: %s", call, snd_strerror(err));
++    pa_log_debug("%s: %s", call, pa_alsa_strerror(err));
+ 
+     pa_assert(err != -EAGAIN);
+ 
+@@ -286,7 +286,7 @@ static int try_recover(struct userdata *u, const char *call, int err) {
+         pa_log_debug("%s: Buffer overrun!", call);
+ 
+     if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) < 0) {
+-        pa_log("%s: %s", call, snd_strerror(err));
++        pa_log("%s: %s", call, pa_alsa_strerror(err));
+         return -1;
+     }
+ 
+@@ -606,12 +606,12 @@ static void update_smoother(struct userdata *u) {
+     /* Let's update the time smoother */
+ 
+     if (PA_UNLIKELY((err = pa_alsa_safe_delay(u->pcm_handle, &delay, u->hwbuf_size, &u->source->sample_spec)) < 0)) {
+-        pa_log_warn("Failed to get delay: %s", snd_strerror(err));
++        pa_log_warn("Failed to get delay: %s", pa_alsa_strerror(err));
+         return;
+     }
+ 
+     if (PA_UNLIKELY((err = snd_pcm_status(u->pcm_handle, status)) < 0))
+-        pa_log_warn("Failed to get timestamp: %s", snd_strerror(err));
++        pa_log_warn("Failed to get timestamp: %s", pa_alsa_strerror(err));
+     else {
+         snd_htimestamp_t htstamp = { 0, 0 };
+         snd_pcm_status_get_htstamp(status, &htstamp);
+@@ -721,7 +721,7 @@ static int update_sw_params(struct userdata *u) {
+     pa_log_debug("setting avail_min=%lu", (unsigned long) avail_min);
+ 
+     if ((err = pa_alsa_set_sw_params(u->pcm_handle, avail_min)) < 0) {
+-        pa_log("Failed to set software parameters: %s", snd_strerror(err));
++        pa_log("Failed to set software parameters: %s", pa_alsa_strerror(err));
+         return err;
+     }
+ 
+@@ -747,7 +747,7 @@ static int unsuspend(struct userdata *u) {
+                             SND_PCM_NO_AUTO_RESAMPLE|
+                             SND_PCM_NO_AUTO_CHANNELS|
+                             SND_PCM_NO_AUTO_FORMAT)) < 0) {
+-        pa_log("Error opening PCM device %s: %s", u->device_name, snd_strerror(err));
++        pa_log("Error opening PCM device %s: %s", u->device_name, pa_alsa_strerror(err));
+         goto fail;
+     }
+ 
+@@ -758,7 +758,7 @@ static int unsuspend(struct userdata *u) {
+     d = u->use_tsched;
+ 
+     if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, u->hwbuf_size / u->frame_size, &b, &d, TRUE)) < 0) {
+-        pa_log("Failed to set hardware parameters: %s", snd_strerror(err));
++        pa_log("Failed to set hardware parameters: %s", pa_alsa_strerror(err));
+         goto fail;
+     }
+ 
+@@ -988,7 +988,7 @@ static void source_get_volume_cb(pa_source *s) {
+     return;
+ 
+ fail:
+-    pa_log_error("Unable to read volume: %s", snd_strerror(err));
++    pa_log_error("Unable to read volume: %s", pa_alsa_strerror(err));
+ }
+ 
+ static void source_set_volume_cb(pa_source *s) {
+@@ -1100,7 +1100,7 @@ static void source_set_volume_cb(pa_source *s) {
+     return;
+ 
+ fail:
+-    pa_log_error("Unable to set volume: %s", snd_strerror(err));
++    pa_log_error("Unable to set volume: %s", pa_alsa_strerror(err));
+ }
+ 
+ static void source_get_mute_cb(pa_source *s) {
+@@ -1111,7 +1111,7 @@ static void source_get_mute_cb(pa_source *s) {
+     pa_assert(u->mixer_elem);
+ 
+     if ((err = snd_mixer_selem_get_capture_switch(u->mixer_elem, 0, &sw)) < 0) {
+-        pa_log_error("Unable to get switch: %s", snd_strerror(err));
++        pa_log_error("Unable to get switch: %s", pa_alsa_strerror(err));
+         return;
+     }
+ 
+@@ -1126,7 +1126,7 @@ static void source_set_mute_cb(pa_source *s) {
+     pa_assert(u->mixer_elem);
+ 
+     if ((err = snd_mixer_selem_set_capture_switch_all(u->mixer_elem, !s->muted)) < 0) {
+-        pa_log_error("Unable to set switch: %s", snd_strerror(err));
++        pa_log_error("Unable to set switch: %s", pa_alsa_strerror(err));
+         return;
+     }
+ }
+@@ -1218,7 +1218,7 @@ static void thread_func(void *userdata) {
+             pollfd = pa_rtpoll_item_get_pollfd(u->alsa_rtpoll_item, &n);
+ 
+             if ((err = snd_pcm_poll_descriptors_revents(u->pcm_handle, pollfd, n, &revents)) < 0) {
+-                pa_log("snd_pcm_poll_descriptors_revents() failed: %s", snd_strerror(err));
++                pa_log("snd_pcm_poll_descriptors_revents() failed: %s", pa_alsa_strerror(err));
+                 goto fail;
+             }
+ 
+diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c
+index b3de415..98710d4 100644
+--- a/src/modules/alsa/alsa-util.c
++++ b/src/modules/alsa/alsa-util.c
+@@ -33,6 +33,7 @@
+ #include <pulse/timeval.h>
+ #include <pulse/util.h>
+ #include <pulse/i18n.h>
++#include <pulse/utf8.h>
+ 
+ #include <pulsecore/log.h>
+ #include <pulsecore/macro.h>
+@@ -40,6 +41,7 @@
+ #include <pulsecore/atomic.h>
+ #include <pulsecore/core-error.h>
+ #include <pulsecore/once.h>
++#include <pulsecore/thread.h>
+ 
+ #include "alsa-util.h"
+ 
+@@ -106,7 +108,7 @@ static void io_cb(pa_mainloop_api*a, pa_io_event* e, int fd, pa_io_event_flags_t
+     pa_assert(i != fdl->num_fds);
+ 
+     if ((err = snd_mixer_poll_descriptors_revents(fdl->mixer, fdl->work_fds, fdl->num_fds, &revents)) < 0) {
+-        pa_log_error("Unable to get poll revent: %s", snd_strerror(err));
++        pa_log_error("Unable to get poll revent: %s", pa_alsa_strerror(err));
+         return;
+     }
+ 
+@@ -129,7 +131,7 @@ static void defer_cb(pa_mainloop_api*a, pa_defer_event* e, void *userdata) {
+     a->defer_enable(fdl->defer, 0);
+ 
+     if ((n = snd_mixer_poll_descriptors_count(fdl->mixer)) < 0) {
+-        pa_log("snd_mixer_poll_descriptors_count() failed: %s", snd_strerror(n));
++        pa_log("snd_mixer_poll_descriptors_count() failed: %s", pa_alsa_strerror(n));
+         return;
+     }
+     num_fds = (unsigned) n;
+@@ -146,7 +148,7 @@ static void defer_cb(pa_mainloop_api*a, pa_defer_event* e, void *userdata) {
+     memset(fdl->work_fds, 0, sizeof(struct pollfd) * num_fds);
+ 
+     if ((err = snd_mixer_poll_descriptors(fdl->mixer, fdl->work_fds, num_fds)) < 0) {
+-        pa_log_error("Unable to get poll descriptors: %s", snd_strerror(err));
++        pa_log_error("Unable to get poll descriptors: %s", pa_alsa_strerror(err));
+         return;
+     }
+ 
+@@ -518,42 +520,42 @@ int pa_alsa_set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t avail_min) {
+     snd_pcm_sw_params_alloca(&swparams);
+ 
+     if ((err = snd_pcm_sw_params_current(pcm, swparams) < 0)) {
+-        pa_log_warn("Unable to determine current swparams: %s\n", snd_strerror(err));
++        pa_log_warn("Unable to determine current swparams: %s\n", pa_alsa_strerror(err));
+         return err;
+     }
+ 
+     if ((err = snd_pcm_sw_params_set_period_event(pcm, swparams, 0)) < 0) {
+-        pa_log_warn("Unable to disable period event: %s\n", snd_strerror(err));
++        pa_log_warn("Unable to disable period event: %s\n", pa_alsa_strerror(err));
+         return err;
+     }
+ 
+     if ((err = snd_pcm_sw_params_set_tstamp_mode(pcm, swparams, SND_PCM_TSTAMP_ENABLE)) < 0) {
+-        pa_log_warn("Unable to enable time stamping: %s\n", snd_strerror(err));
++        pa_log_warn("Unable to enable time stamping: %s\n", pa_alsa_strerror(err));
+         return err;
+     }
+ 
+     if ((err = snd_pcm_sw_params_get_boundary(swparams, &boundary)) < 0) {
+-        pa_log_warn("Unable to get boundary: %s\n", snd_strerror(err));
++        pa_log_warn("Unable to get boundary: %s\n", pa_alsa_strerror(err));
+         return err;
+     }
+ 
+     if ((err = snd_pcm_sw_params_set_stop_threshold(pcm, swparams, boundary)) < 0) {
+-        pa_log_warn("Unable to set stop threshold: %s\n", snd_strerror(err));
++        pa_log_warn("Unable to set stop threshold: %s\n", pa_alsa_strerror(err));
+         return err;
+     }
+ 
+     if ((err = snd_pcm_sw_params_set_start_threshold(pcm, swparams, (snd_pcm_uframes_t) -1)) < 0) {
+-        pa_log_warn("Unable to set start threshold: %s\n", snd_strerror(err));
++        pa_log_warn("Unable to set start threshold: %s\n", pa_alsa_strerror(err));
+         return err;
+     }
+ 
+     if ((err = snd_pcm_sw_params_set_avail_min(pcm, swparams, avail_min)) < 0) {
+-        pa_log_error("snd_pcm_sw_params_set_avail_min() failed: %s", snd_strerror(err));
++        pa_log_error("snd_pcm_sw_params_set_avail_min() failed: %s", pa_alsa_strerror(err));
+         return err;
+     }
+ 
+     if ((err = snd_pcm_sw_params(pcm, swparams)) < 0) {
+-        pa_log_warn("Unable to set sw params: %s\n", snd_strerror(err));
++        pa_log_warn("Unable to set sw params: %s\n", pa_alsa_strerror(err));
+         return err;
+     }
+ 
+@@ -942,7 +944,7 @@ snd_pcm_t *pa_alsa_open_by_device_string(
+                                 SND_PCM_NO_AUTO_RESAMPLE|
+                                 SND_PCM_NO_AUTO_CHANNELS|
+                                 (reformat ? 0 : SND_PCM_NO_AUTO_FORMAT))) < 0) {
+-            pa_log_info("Error opening PCM device %s: %s", d, snd_strerror(err));
++            pa_log_info("Error opening PCM device %s: %s", d, pa_alsa_strerror(err));
+             goto fail;
+         }
+ 
+@@ -972,7 +974,7 @@ snd_pcm_t *pa_alsa_open_by_device_string(
+                 continue;
+             }
+ 
+-            pa_log_info("Failed to set hardware parameters on %s: %s", d, snd_strerror(err));
++            pa_log_info("Failed to set hardware parameters on %s: %s", d, pa_alsa_strerror(err));
+             snd_pcm_close(pcm_handle);
+ 
+             goto fail;
+@@ -1088,17 +1090,17 @@ int pa_alsa_prepare_mixer(snd_mixer_t *mixer, const char *dev) {
+     pa_assert(dev);
+ 
+     if ((err = snd_mixer_attach(mixer, dev)) < 0) {
+-        pa_log_info("Unable to attach to mixer %s: %s", dev, snd_strerror(err));
++        pa_log_info("Unable to attach to mixer %s: %s", dev, pa_alsa_strerror(err));
+         return -1;
+     }
+ 
+     if ((err = snd_mixer_selem_register(mixer, NULL, NULL)) < 0) {
+-        pa_log_warn("Unable to register mixer: %s", snd_strerror(err));
++        pa_log_warn("Unable to register mixer: %s", pa_alsa_strerror(err));
+         return -1;
+     }
+ 
+     if ((err = snd_mixer_load(mixer)) < 0) {
+-        pa_log_warn("Unable to load mixer: %s", snd_strerror(err));
++        pa_log_warn("Unable to load mixer: %s", pa_alsa_strerror(err));
+         return -1;
+     }
+ 
+@@ -1224,7 +1226,7 @@ int pa_alsa_find_mixer_and_elem(
+     }
+ 
+     if ((err = snd_mixer_open(&m, 0)) < 0) {
+-        pa_log("Error opening mixer: %s", snd_strerror(err));
++        pa_log("Error opening mixer: %s", pa_alsa_strerror(err));
+         return -1;
+     }
+ 
+@@ -1426,7 +1428,7 @@ void pa_alsa_dump(pa_log_level_t level, snd_pcm_t *pcm) {
+     pa_assert_se(snd_output_buffer_open(&out) == 0);
+ 
+     if ((err = snd_pcm_dump(pcm, out)) < 0)
+-        pa_logl(level, "snd_pcm_dump(): %s", snd_strerror(err));
++        pa_logl(level, "snd_pcm_dump(): %s", pa_alsa_strerror(err));
+     else {
+         char *s = NULL;
+         snd_output_buffer_string(out, &s);
+@@ -1450,7 +1452,7 @@ void pa_alsa_dump_status(snd_pcm_t *pcm) {
+     pa_assert_se(snd_pcm_status(pcm, status) == 0);
+ 
+     if ((err = snd_pcm_status_dump(status, out)) < 0)
+-        pa_log_debug("snd_pcm_dump(): %s", snd_strerror(err));
++        pa_log_debug("snd_pcm_dump(): %s", pa_alsa_strerror(err));
+     else {
+         char *s = NULL;
+         snd_output_buffer_string(out, &s);
+@@ -1612,7 +1614,7 @@ void pa_alsa_init_proplist_pcm(pa_core *c, pa_proplist *p, snd_pcm_t *pcm, snd_m
+     snd_pcm_info_alloca(&info);
+ 
+     if ((err = snd_pcm_hw_params_current(pcm, hwparams)) < 0)
+-        pa_log_warn("Error fetching hardware parameter info: %s", snd_strerror(err));
++        pa_log_warn("Error fetching hardware parameter info: %s", pa_alsa_strerror(err));
+     else {
+ 
+         if ((bits = snd_pcm_hw_params_get_sbits(hwparams)) >= 0)
+@@ -1623,7 +1625,7 @@ void pa_alsa_init_proplist_pcm(pa_core *c, pa_proplist *p, snd_pcm_t *pcm, snd_m
+         pa_proplist_sets(p, "alsa.mixer_element", snd_mixer_selem_get_name(elem));
+ 
+     if ((err = snd_pcm_info(pcm, info)) < 0)
+-        pa_log_warn("Error fetching PCM info: %s", snd_strerror(err));
++        pa_log_warn("Error fetching PCM info: %s", pa_alsa_strerror(err));
+     else
+         pa_alsa_init_proplist_pcm_info(c, p, info);
+ }
+@@ -1656,14 +1658,14 @@ int pa_alsa_recover_from_poll(snd_pcm_t *pcm, int revents) {
+ 
+         case SND_PCM_STATE_XRUN:
+             if ((err = snd_pcm_recover(pcm, -EPIPE, 1)) != 0) {
+-                pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP and XRUN: %s", snd_strerror(err));
++                pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP and XRUN: %s", pa_alsa_strerror(err));
+                 return -1;
+             }
+             break;
+ 
+         case SND_PCM_STATE_SUSPENDED:
+             if ((err = snd_pcm_recover(pcm, -ESTRPIPE, 1)) != 0) {
+-                pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP and SUSPENDED: %s", snd_strerror(err));
++                pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP and SUSPENDED: %s", pa_alsa_strerror(err));
+                 return -1;
+             }
+             break;
+@@ -1673,7 +1675,7 @@ int pa_alsa_recover_from_poll(snd_pcm_t *pcm, int revents) {
+             snd_pcm_drop(pcm);
+ 
+             if ((err = snd_pcm_prepare(pcm)) < 0) {
+-                pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP with snd_pcm_prepare(): %s", snd_strerror(err));
++                pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP with snd_pcm_prepare(): %s", pa_alsa_strerror(err));
+                 return -1;
+             }
+             break;
+@@ -1690,7 +1692,7 @@ pa_rtpoll_item* pa_alsa_build_pollfd(snd_pcm_t *pcm, pa_rtpoll *rtpoll) {
+     pa_assert(pcm);
+ 
+     if ((n = snd_pcm_poll_descriptors_count(pcm)) < 0) {
+-        pa_log("snd_pcm_poll_descriptors_count() failed: %s", snd_strerror(n));
++        pa_log("snd_pcm_poll_descriptors_count() failed: %s", pa_alsa_strerror(n));
+         return NULL;
+     }
+ 
+@@ -1698,7 +1700,7 @@ pa_rtpoll_item* pa_alsa_build_pollfd(snd_pcm_t *pcm, pa_rtpoll *rtpoll) {
+     pollfd = pa_rtpoll_item_get_pollfd(item, NULL);
+ 
+     if ((err = snd_pcm_poll_descriptors(pcm, pollfd, (unsigned) n)) < 0) {
+-        pa_log("snd_pcm_poll_descriptors() failed: %s", snd_strerror(err));
++        pa_log("snd_pcm_poll_descriptors() failed: %s", pa_alsa_strerror(err));
+         pa_rtpoll_item_free(item);
+         return NULL;
+     }
+@@ -1907,3 +1909,32 @@ pa_bool_t pa_alsa_pcm_is_modem(snd_pcm_t *pcm) {
+ 
+     return snd_pcm_info_get_class(info) == SND_PCM_CLASS_MODEM;
+ }
++
++PA_STATIC_TLS_DECLARE(cstrerror, pa_xfree);
++
++const char* pa_alsa_strerror(int errnum) {
++    const char *original = NULL;
++    char *translated, *t;
++    char errbuf[128];
++
++    if ((t = PA_STATIC_TLS_GET(cstrerror)))
++        pa_xfree(t);
++
++    errnum = EINVAL;
++    PA_DEBUG_TRAP;
++    original = snd_strerror(errnum);
++
++    if (!original) {
++        pa_snprintf(errbuf, sizeof(errbuf), "Unknown error %i", errnum);
++        original = errbuf;
++    }
++
++    if (!(translated = pa_locale_to_utf8(original))) {
++        pa_log_warn("Unable to convert error string to locale, filtering.");
++        translated = pa_utf8_filter(original);
++    }
++
++    PA_STATIC_TLS_SET(cstrerror, translated);
++
++    return translated;
++}
+diff --git a/src/modules/alsa/alsa-util.h b/src/modules/alsa/alsa-util.h
+index c3a8117..4c5d336 100644
+--- a/src/modules/alsa/alsa-util.h
++++ b/src/modules/alsa/alsa-util.h
+@@ -147,4 +147,6 @@ pa_bool_t pa_alsa_pcm_is_hw(snd_pcm_t *pcm);
+ 
+ pa_bool_t pa_alsa_pcm_is_modem(snd_pcm_t *pcm);
+ 
++const char* pa_alsa_strerror(int errnum);
++
+ #endif
+diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
+index dd8636e..d894b9c 100644
+--- a/src/modules/alsa/module-alsa-card.c
++++ b/src/modules/alsa/module-alsa-card.c
+@@ -304,7 +304,7 @@ int pa__init(pa_module *m) {
+     u->modargs = ma;
+ 
+     if ((alsa_card_index = snd_card_get_index(u->device_id)) < 0) {
+-        pa_log("Card '%s' doesn't exist: %s", u->device_id, snd_strerror(alsa_card_index));
++        pa_log("Card '%s' doesn't exist: %s", u->device_id, pa_alsa_strerror(alsa_card_index));
+         goto fail;
+     }
+ 
diff --git a/debian/patches/0028-alsa-remove-debug-code.patch b/debian/patches/0028-alsa-remove-debug-code.patch
new file mode 100644
index 0000000..88728a3
--- /dev/null
+++ b/debian/patches/0028-alsa-remove-debug-code.patch
@@ -0,0 +1,22 @@
+From a15f3868f0b645fa07e1555a5c2812516af86b1e Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Sun, 19 Apr 2009 19:25:42 +0200
+Subject: [PATCH 28/28] alsa: remove debug code
+
+---
+ src/modules/alsa/alsa-util.c |    2 --
+ 1 files changed, 0 insertions(+), 2 deletions(-)
+
+diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c
+index 98710d4..aae38bc 100644
+--- a/src/modules/alsa/alsa-util.c
++++ b/src/modules/alsa/alsa-util.c
+@@ -1920,8 +1920,6 @@ const char* pa_alsa_strerror(int errnum) {
+     if ((t = PA_STATIC_TLS_GET(cstrerror)))
+         pa_xfree(t);
+ 
+-    errnum = EINVAL;
+-    PA_DEBUG_TRAP;
+     original = snd_strerror(errnum);
+ 
+     if (!original) {
diff --git a/debian/patches/series b/debian/patches/series
index 3cfaf5b..0e0d2b5 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1 +1,28 @@
 0001-alsa-allow-configuration-of-fallback-device-strings-.patch
+0002-util-if-NULL-is-passed-to-pa_path_get_filename-just-.patch
+0003-alsa-don-t-hit-an-assert-when-invalid-module-argumen.patch
+0004-alsa-fix-wording-we-are-speaking-of-card-profiles-no.patch
+0005-alsa-initialize-buffer-size-before-number-of-periods.patch
+0006-conf-remove-obsolete-module-idle-time-directive-from.patch
+0007-core-make-sure-soft-mute-status-stays-in-sync-with-h.patch
+0008-endian-fix-LE-BE-order-for-24-bit-accessor-functions.patch
+0009-log-print-file-name-only-when-we-have-it.patch
+0010-man-document-24bit-sample-types-in-man-page.patch
+0011-man-document-log-related-daemon.conf-options.patch
+0012-man-document-that-tsched-doesn-t-use-fragment-settin.patch
+0013-mutex-when-we-fail-to-fill-in-mutex-into-static-mute.patch
+0014-oss-don-t-deadlock-when-we-try-to-resume-an-OSS-devi.patch
+0015-simple-protocol-don-t-hit-an-assert-when-we-call-con.patch
+0016-idxset-add-enumeration-macro-PA_IDXSET_FOREACH.patch
+0017-rescue-streams-when-one-stream-move-fails-try-to-con.patch
+0018-sample-correctly-pass-s24-32-formats.patch
+0019-sample-util-fix-iteration-loop-when-adjusting-volume.patch
+0020-sample-util-properly-allocate-silence-block-for-s24-.patch
+0021-sconv-fix-a-few-minor-conversion-issues.patch
+0022-alsa-be-a-bit-more-verbose-when-a-hwparam-call-fails.patch
+0023-rescue-make-we-don-t-end-up-in-an-endless-loop-when-.patch
+0024-core-introduce-pa_-sink-source-_set_fixed_latency.patch
+0025-core-cache-requested-latency-only-when-we-are-runnin.patch
+0026-sample-fix-build-on-BE-archs.patch
+0027-alsa-properly-convert-return-values-of-snd_strerror-.patch
+0028-alsa-remove-debug-code.patch

-- 
pulseaudio packaging



More information about the Pkg-pulseaudio-devel mailing list