[Pkg-pulseaudio-devel] [SCM] pulseaudio packaging branch, patches, updated. upstream/0.9.15-28-ga15f386

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


The branch, patches has been updated
       via  a15f3868f0b645fa07e1555a5c2812516af86b1e (commit)
       via  42885f1f9743a0e2cd7f1ded1cab688e5df10bc8 (commit)
       via  85fb360fe3b9d3b3fb4e537373f4dc9202ca5e13 (commit)
       via  c73733777f11080373264ed4e992c6860809898e (commit)
       via  c41d9c71667de6d6e9aab077ac58b7371594bbef (commit)
       via  1ab53c43c17943d49fc80c86ef2b513354eddc63 (commit)
       via  11a048bd9dbef1a7ea3c79799248bc2d661cee5f (commit)
       via  100af7efac584be9f229f4daf663dbb939f5d929 (commit)
       via  55244f7a07335115caf2b9cc57aecc0f8cd08030 (commit)
       via  397f517aafda4efd00532ba7f19e7045aa853c2a (commit)
       via  79510a3b15652b04bffbb798221d27e8d16f4ce2 (commit)
       via  b7eff401100af0de381fba66293d21aca7ff36fa (commit)
       via  bee02ee03fc82f447a358a564a4d922c0f29cfcf (commit)
       via  b8e05f113a44f46a91d3343e3e4a1eb15c98e1c9 (commit)
       via  776b0817f79b475c9725b53c185484b5e3ff6fbb (commit)
       via  977f59368ba55fac3fe21d7549bc0552daf07d91 (commit)
       via  b8219d533e631a5e574e7d7a060b44723a951dd9 (commit)
       via  ba745277dfbffeb0a4aac3bcad8fc74b11bf27d1 (commit)
       via  4a080c4f93c254c58736728d9b85bbbfc4e4ec9c (commit)
       via  11c17636d1d6c7eb4d6278869d3fa91715433ab2 (commit)
       via  7f17882bae9d2b694f440d28dc9bb3fcf133fa1a (commit)
       via  f9bfc3780f14df0def0558e9265a89a7526ebb16 (commit)
       via  313ac6bf0f63515ff4754208ca5d2749fe1096a8 (commit)
       via  314241e6002e7c78ee87a171ee337be382b3e0d7 (commit)
       via  b14f2f1aa66e2806849c32e1dbd6d57b19a6d3ee (commit)
       via  6e1f6ca6e2279fdd8601d95419aeeaa29445dd5b (commit)
       via  876624e3147cf3deac847b11bde4b04988971eee (commit)
      from  270ab5f0f2c049f842e5b4a7f69c59db84827c5d (commit)


- Shortlog ------------------------------------------------------------
a15f386 alsa: remove debug code
42885f1 alsa: properly convert return values of snd_strerror() to utf8
85fb360 sample: fix build on BE archs
c737337 core: cache requested latency only when we are running, not while we are still constructing
c41d9c7 core: introduce pa_{sink,source}_set_fixed_latency()
1ab53c4 rescue: make we don't end up in an endless loop when we can't move a sink input
11a048b alsa: be a bit more verbose when a hwparam call fails
100af7e sconv: fix a few minor conversion issues
55244f7 sample-util: properly allocate silence block for s24-32 formats
397f517 sample-util: fix iteration loop when adjusting volume of s24 samples
79510a3 sample: correctly pass s24-32 formats
b7eff40 rescue-streams: when one stream move fails try to continue with the remaining ones
bee02ee idxset: add enumeration macro PA_IDXSET_FOREACH
b8e05f1 simple-protocol: don't hit an assert when we call connection_unlink() early
776b081 oss: don't deadlock when we try to resume an OSS device that lacks a mixer
977f593 mutex: when we fail to fill in mutex into static mutex ptr free it again
b8219d5 man: document that tsched doesn't use fragment settings
ba74527 man: document log related daemon.conf options
4a080c4 man: document 24bit sample types in man page
11c1763 log: print file name only when we have it
7f17882 endian: fix LE/BE order for 24 bit accessor functions
f9bfc37 core: make sure soft mute status stays in sync with hw mute status
313ac6b conf: remove obsolete module-idle-time directive from default config file/man page
314241e alsa: initialize buffer size before number of periods to improve compat with some backends
b14f2f1 alsa: fix wording, we are speaking of card profiles, not output profiles
6e1f6ca alsa: don't hit an assert when invalid module arguments are passed
876624e util: if NULL is passed to pa_path_get_filename() just hand it through

Summary of changes:
 man/pulse-daemon.conf.5.xml.in                  |   41 ++++--
 src/daemon/daemon.conf.in                       |    1 -
 src/modules/alsa/alsa-sink.c                    |   37 +++---
 src/modules/alsa/alsa-source.c                  |   33 +++---
 src/modules/alsa/alsa-util.c                    |  159 ++++++++++++++++-------
 src/modules/alsa/alsa-util.h                    |    2 +
 src/modules/alsa/module-alsa-card.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-rescue-streams.c             |   48 ++++----
 src/modules/module-sine-source.c                |    3 +-
 src/modules/oss/module-oss.c                    |   15 ++-
 src/pulse/sample.c                              |    8 +-
 src/pulse/util.c                                |    3 +-
 src/pulse/util.h                                |    2 +-
 src/pulsecore/endianmacros.h                    |    8 +-
 src/pulsecore/idxset.h                          |    4 +
 src/pulsecore/log.c                             |    2 +-
 src/pulsecore/mutex-posix.c                     |    2 +
 src/pulsecore/protocol-simple.c                 |    2 +-
 src/pulsecore/sample-util.c                     |   12 +-
 src/pulsecore/sconv-s16le.c                     |   10 +-
 src/pulsecore/sconv.c                           |    2 +-
 src/pulsecore/sink.c                            |   29 ++++-
 src/pulsecore/sink.h                            |    1 +
 src/pulsecore/source.c                          |   28 ++++-
 src/pulsecore/source.h                          |    1 +
 28 files changed, 307 insertions(+), 166 deletions(-)
-----------------------------------------------------------------------
Details of changes:

commit a15f3868f0b645fa07e1555a5c2812516af86b1e
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sun Apr 19 19:25:42 2009 +0200

    alsa: remove debug code

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) {

commit 42885f1f9743a0e2cd7f1ded1cab688e5df10bc8
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sun Apr 19 19:22:51 2009 +0200

    alsa: properly convert return values of snd_strerror() to utf8

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;
     }
 

commit 85fb360fe3b9d3b3fb4e537373f4dc9202ca5e13
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Jun 8 18:22:19 2009 +0200

    sample: fix build on BE archs

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);

commit c73733777f11080373264ed4e992c6860809898e
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri May 8 02:02:36 2009 +0200

    core: cache requested latency only when we are running, not while we are still constructing

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;
 }

commit c41d9c71667de6d6e9aab077ac58b7371594bbef
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri May 8 01:56:21 2009 +0200

    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().

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);

commit 1ab53c43c17943d49fc80c86ef2b513354eddc63
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu May 14 03:52:13 2009 +0200

    rescue: make we don't end up in an endless loop when we can't move a sink input

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)

commit 11a048bd9dbef1a7ea3c79799248bc2d661cee5f
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu May 14 01:25:07 2009 +0200

    alsa: be a bit more verbose when a hwparam call fails

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) {
 

commit 100af7efac584be9f229f4daf663dbb939f5d929
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri May 1 04:22:08 2009 +0200

    sconv: fix a few minor conversion issues

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 */

commit 55244f7a07335115caf2b9cc57aecc0f8cd08030
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri May 1 04:14:02 2009 +0200

    sample-util: properly allocate silence block for s24-32 formats

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;

commit 397f517aafda4efd00532ba7f19e7045aa853c2a
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri May 1 04:14:40 2009 +0200

    sample-util: fix iteration loop when adjusting volume of s24 samples

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));

commit 79510a3b15652b04bffbb798221d27e8d16f4ce2
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri May 1 04:12:24 2009 +0200

    sample: correctly pass s24-32 formats

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;
 }

commit b7eff401100af0de381fba66293d21aca7ff36fa
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Apr 17 20:30:09 2009 +0200

    rescue-streams: when one stream move fails try to continue with the remaining ones

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);
     }
 
 

commit bee02ee03fc82f447a358a564a4d922c0f29cfcf
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Apr 29 01:46:12 2009 +0200

    idxset: add enumeration macro PA_IDXSET_FOREACH

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

commit b8e05f113a44f46a91d3343e3e4a1eb15c98e1c9
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Apr 29 04:13:07 2009 +0200

    simple-protocol: don't hit an assert when we call connection_unlink() early

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);
 }

commit 776b0817f79b475c9725b53c185484b5e3ff6fbb
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue May 26 22:30:36 2009 +0200

    oss: don't deadlock when we try to resume an OSS device that lacks a mixer

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;

commit 977f59368ba55fac3fe21d7549bc0552daf07d91
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Apr 21 21:24:33 2009 +0200

    mutex: when we fail to fill in mutex into static mutex ptr free it again

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));

commit b8219d533e631a5e574e7d7a060b44723a951dd9
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sun Jun 7 00:45:21 2009 +0200

    man: document that tsched doesn't use fragment settings

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

commit ba745277dfbffeb0a4aac3bcad8fc74b11bf27d1
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sun Jun 7 00:44:49 2009 +0200

    man: document log related daemon.conf options

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">

commit 4a080c4f93c254c58736728d9b85bbbfc4e4ec9c
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sun Jun 7 00:45:05 2009 +0200

    man: document 24bit sample types in man page

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>

commit 11c17636d1d6c7eb4d6278869d3fa91715433ab2
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sun Apr 19 19:04:50 2009 +0200

    log: print file name only when we have it

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;

commit 7f17882bae9d2b694f440d28dc9bb3fcf133fa1a
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri May 1 04:13:15 2009 +0200

    endian: fix LE/BE order for 24 bit accessor functions

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;

commit f9bfc3780f14df0def0558e9265a89a7526ebb16
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Jun 8 00:02:15 2009 +0200

    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.

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;

commit 313ac6bf0f63515ff4754208ca5d2749fe1096a8
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sun Jun 7 00:44:16 2009 +0200

    conf: remove obsolete module-idle-time directive from default config file/man page

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)

commit 314241e6002e7c78ee87a171ee337be382b3e0d7
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri May 1 04:16:17 2009 +0200

    alsa: initialize buffer size before number of periods to improve compat with some backends

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)

commit b14f2f1aa66e2806849c32e1dbd6d57b19a6d3ee
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue May 26 22:29:33 2009 +0200

    alsa: fix wording, we are speaking of card profiles, not output profiles

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));
 

commit 6e1f6ca6e2279fdd8601d95419aeeaa29445dd5b
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri May 1 04:11:30 2009 +0200

    alsa: don't hit an assert when invalid module arguments are passed

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;
 }

commit 876624e3147cf3deac847b11bde4b04988971eee
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sun Apr 19 19:02:16 2009 +0200

    util: if NULL is passed to pa_path_get_filename() just hand it through

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 */

-- 
pulseaudio packaging



More information about the Pkg-pulseaudio-devel mailing list