[pulseaudio-commits] [SCM] PulseAudio Sound Server branch, master-tx, updated. v0.9.15-test1-18-g4bd9737

Lennart Poettering gitmailer-noreply at 0pointer.de
Thu Feb 5 17:17:05 PST 2009


This is an automated email from the git hooks/post-receive script. It was
generated because of a push to the "PulseAudio Sound Server" repository.

The master-tx branch has been updated
      from  108e08c8021c551ae6c88fc84ae6f38ba542a518 (commit)

- Log -----------------------------------------------------------------
4bd9737... Merge branch 'master-tx'
64926ff... RTP segfault/uninitialized resampler
6bb2c49... add #defines for all enums that lacked it
04c3c67... A few MacOS X portability fixes
9f39a44... add new module-augment-properties module for augmenting properties from .desktop files
d6201cf... parse ini-style sections properly
ee5abc3... make native protocol use pa_{sink_input|source_output|card}_update_proplist()
524d78f... add missing hook
291589e... allow overwriting of process properties with environment variables
f42afc4... make return value of pa_{sink_input|source_output}_update_proplist() void
a67406d... add pa_client_update_proplist() call
63e2343... handle default volume initialization properly
f6ffd2d... make module-position-event-sounds use volume factor
de86c6e... add a 'volume factor' that is implicitly multiplied into the volume of a sink input without being visible to the outside
3fc1233... add a .mailmap file for git shortlog
12c29e1... store the identification key in the module-stream-restore.id property
9e2a2f8... run make update-po
9a4e03c... bump version and soname
ae06517... make pacmd work in a pipe
3d33172... rate limit underrun messages
0933f1a... Merge commit 'flameeyes/flameeyes'
d4618c8... Merge commit 'vudentz/master'
9a93157... Merge commit 'coling/master'
d802a76... remove soft volume from pa_sink_input_new_info since it should be handled internally and automatically by the sink input
b2c923e... properly handle failing stream creation
786398d... fix a validity check
1db6478... version all entries in the database
4cf82c7... merge in properties earlier to make identification of streams from hooks easier
f6ec971... clarify things a bit
12b7359... add a few additional validity checks
83ddc09... add new calls pa_replace() and pa_unescape()
a625ca7... make gcc shut up
078a8d5... rearrange a few things
d6dd907... simplify code a bit by using pa_sample_size_of_format()
a6fe991... beef up proplist test a bit
9a27b8f... in addition to per-property env vars PULSE_PROP_xxx look for for a stringified PULSE_PROP env var
b445741... fix up parser in pa_proplist_from_string() to handle escapes correctly; make pa_proplist_to_string() escape quotes properly
0fc59e4... add new API pa_ascii_valid(), pa_ascii_filter()
ce76216... add pa_sample_size_of_format()
004b38f... Prevent changing volume on wrong device.
871389a... A couple of dependancy ordering fixes.
d1957b8... Trivial typo in a comment
e28903e... Clean up volume/mute settings a bit. As the APEX device only has one channel of volume (e.g. it's always matched) we emulate any variation in channel volumes in software. Remove the unnecessary callback defininitions.
32e5e64... add a lot of validity checking
b51ed38... add a bit of missing i18n
543115a... add new API pa_cvolume_compatible_with_channel_map()
921882d... Load module gconf earlier
fc31d21... when moving a sink between sinks make volume relative
554c818... before applying balance/fade check it actually makes sense
f9696c0... add a macro definition for each error code
e9ca8b1... Disable portability warnings from automake.
-----------------------------------------------------------------------

Summary of changes:
 .mailmap                                        |    7 +
 configure.ac                                    |    6 +-
 po/ca.po                                        | 1084 +++++++++++++----------
 po/cs.po                                        |   61 +-
 po/de.po                                        |   61 +-
 po/el.po                                        |   61 +-
 po/es.po                                        |   61 +-
 po/fi.po                                        |   61 +-
 po/fr.po                                        |   61 +-
 po/pt_BR.po                                     |   61 +-
 po/sv.po                                        |   61 +-
 po/zh_CN.po                                     |  940 +++++++++++---------
 src/Makefile.am                                 |   29 +-
 src/daemon/daemon-conf.c                        |  120 ++--
 src/daemon/default.pa.in                        |   22 +-
 src/map-file                                    |    4 +
 src/modules/alsa/alsa-sink.c                    |    4 +-
 src/modules/alsa/alsa-source.c                  |    3 +-
 src/modules/bluetooth/module-bluetooth-device.c |    3 +
 src/modules/module-augment-properties.c         |  286 ++++++
 src/modules/module-card-restore.c               |   13 +-
 src/modules/module-device-restore.c             |   15 +-
 src/modules/module-match.c                      |    1 -
 src/modules/module-position-event-sounds.c      |   15 +-
 src/modules/module-raop-sink.c                  |   65 +-
 src/modules/module-stream-restore.c             |   91 ++-
 src/modules/rtp/module-rtp-recv.c               |    2 +-
 src/pulse/channelmap.c                          |   49 +-
 src/pulse/channelmap.h                          |   70 ++
 src/pulse/client-conf.c                         |   20 +-
 src/pulse/def.h                                 |   93 ++
 src/pulse/ext-stream-restore.c                  |   48 +-
 src/pulse/ext-stream-restore.h                  |    8 +-
 src/pulse/operation.c                           |    1 +
 src/pulse/proplist.c                            |  384 +++++++--
 src/pulse/proplist.h                            |    8 +-
 src/pulse/sample.c                              |   38 +-
 src/pulse/sample.h                              |    4 +
 src/pulse/utf8.c                                |   26 +
 src/pulse/utf8.h                                |    6 +
 src/pulse/volume.c                              |   74 ++-
 src/pulse/volume.h                              |   29 +-
 src/pulsecore/client.c                          |   13 +
 src/pulsecore/client.h                          |    2 +
 src/pulsecore/conf-parser.c                     |   55 +-
 src/pulsecore/conf-parser.h                     |   15 +-
 src/pulsecore/core-util.c                       |   51 ++
 src/pulsecore/core-util.h                       |    4 +
 src/pulsecore/core.h                            |    1 +
 src/pulsecore/envelope.c                        |    7 +
 src/pulsecore/modargs.c                         |  179 ++--
 src/pulsecore/play-memblockq.c                  |    2 +-
 src/pulsecore/proplist-util.c                   |   25 +-
 src/pulsecore/protocol-native.c                 |   23 +-
 src/pulsecore/resampler.c                       |   12 +-
 src/pulsecore/sink-input.c                      |  122 ++--
 src/pulsecore/sink-input.h                      |   14 +-
 src/pulsecore/sink.c                            |    1 +
 src/pulsecore/sound-file-stream.c               |    2 +-
 src/pulsecore/source-output.c                   |   24 +-
 src/pulsecore/source-output.h                   |    2 +-
 src/tests/proplist-test.c                       |   19 +-
 src/utils/pacmd.c                               |  104 ++-
 63 files changed, 3187 insertions(+), 1546 deletions(-)
 create mode 100644 .mailmap
 create mode 100644 src/modules/module-augment-properties.c

-----------------------------------------------------------------------

commit e9ca8b1c5447d9fa177e33a12e40fbf624701625
Author: Diego Elio 'Flameeyes' Pettenò <flameeyes at gmail.com>
Date:   Sat Jan 31 19:26:14 2009 +0100

    Disable portability warnings from automake.
    
    The portability warning class warns during automake calls about non-POSIX
    variable names and GNU make extensions. Since both happens with the current
    Makefile.am files and it's reasonable to expect that they wouldn't be
    rewritten (GNU make is a reasonable requirement), just avoid the warnings.

diff --git a/configure.ac b/configure.ac
index c02b20e..3d9cfcd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -30,7 +30,7 @@ AC_INIT([pulseaudio],[pa_major.pa_minor.pa_micro],[mzchyfrnhqvb (at) 0pointer (d
 AC_CONFIG_SRCDIR([src/daemon/main.c])
 AC_CONFIG_MACRO_DIR([m4])
 AC_CONFIG_HEADERS([config.h])
-AM_INIT_AUTOMAKE([foreign 1.10 -Wall])
+AM_INIT_AUTOMAKE([foreign 1.10 -Wall -Wno-portability])
 
 AC_SUBST(PA_MAJOR, pa_major)
 AC_SUBST(PA_MINOR, pa_minor)

commit f9696c0e7fb38b77dedeafb0e3c4dbdf6df6c4ff
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Feb 3 03:38:40 2009 +0100

    add a macro definition for each error code

diff --git a/src/pulse/def.h b/src/pulse/def.h
index 1acf19a..6149888 100644
--- a/src/pulse/def.h
+++ b/src/pulse/def.h
@@ -368,6 +368,34 @@ enum {
     PA_ERR_MAX                     /**< Not really an error but the first invalid error code */
 };
 
+/** \cond fulldocs */
+#define PA_OK PA_OK
+#define PA_ERR_ACCESS PA_ERR_ACCESS
+#define PA_ERR_COMMAND PA_ERR_COMMAND
+#define PA_ERR_INVALID PA_ERR_INVALID
+#define PA_ERR_EXIST PA_ERR_EXIST
+#define PA_ERR_NOENTITY PA_ERR_NOENTITY
+#define PA_ERR_CONNECTIONREFUSED PA_ERR_CONNECTIONREFUSED
+#define PA_ERR_PROTOCOL PA_ERR_PROTOCOL
+#define PA_ERR_TIMEOUT PA_ERR_TIMEOUT
+#define PA_ERR_AUTHKEY PA_ERR_AUTHKEY
+#define PA_ERR_INTERNAL PA_ERR_INTERNAL
+#define PA_ERR_CONNECTIONTERMINATED PA_ERR_CONNECTIONTERMINATED
+#define PA_ERR_KILLED PA_ERR_KILLED
+#define PA_ERR_INVALIDSERVER PA_ERR_INVALIDSERVER
+#define PA_ERR_MODINITFAILED PA_ERR_MODINITFAILED
+#define PA_ERR_BADSTATE PA_ERR_BADSTATE
+#define PA_ERR_NODATA PA_ERR_NODATA
+#define PA_ERR_VERSION PA_ERR_VERSION
+#define PA_ERR_TOOLARGE PA_ERR_TOOLARGE
+#define PA_ERR_NOTSUPPORTED PA_ERR_NOTSUPPORTED
+#define PA_ERR_UNKNOWN PA_ERR_UNKNOWN
+#define PA_ERR_NOEXTENSION PA_ERR_NOEXTENSION
+#define PA_ERR_OBSOLETE PA_ERR_OBSOLETE
+#define PA_ERR_NOTIMPLEMENTED PA_ERR_NOTIMPLEMENTED
+#define PA_ERR_MAX PA_ERR_MAX
+/** \endcond */
+
 /** Subscription event mask, as used by pa_context_subscribe() */
 typedef enum pa_subscription_mask {
     PA_SUBSCRIPTION_MASK_NULL = 0x0000U,

commit 554c818d21acb66dbfdd477165f6a25f88c334f1
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Feb 3 04:05:41 2009 +0100

    before applying balance/fade check it actually makes sense

diff --git a/src/pulse/volume.c b/src/pulse/volume.c
index ba2ee8f..01a28e8 100644
--- a/src/pulse/volume.c
+++ b/src/pulse/volume.c
@@ -467,6 +467,9 @@ float pa_cvolume_get_balance(const pa_cvolume *v, const pa_channel_map *map) {
     pa_assert(map);
     pa_assert(map->channels == v->channels);
 
+    if (!pa_channel_map_can_balance(map))
+        return 0.0f;
+
     get_avg_lr(map, v, &left, &right);
 
     if (left == right)
@@ -497,6 +500,9 @@ pa_cvolume* pa_cvolume_set_balance(pa_cvolume *v, const pa_channel_map *map, flo
     pa_assert(new_balance >= -1.0f);
     pa_assert(new_balance <= 1.0f);
 
+    if (!pa_channel_map_can_balance(map))
+        return v;
+
     get_avg_lr(map, v, &left, &right);
 
     m = PA_MAX(left, right);
@@ -584,6 +590,9 @@ float pa_cvolume_get_fade(const pa_cvolume *v, const pa_channel_map *map) {
     pa_assert(map);
     pa_assert(map->channels == v->channels);
 
+    if (!pa_channel_map_can_fade(map))
+        return 0.0f;
+
     get_avg_fr(map, v, &front, &rear);
 
     if (front == rear)
@@ -605,6 +614,9 @@ pa_cvolume* pa_cvolume_set_fade(pa_cvolume *v, const pa_channel_map *map, float
     pa_assert(new_fade >= -1.0f);
     pa_assert(new_fade <= 1.0f);
 
+    if (!pa_channel_map_can_fade(map))
+        return v;
+
     get_avg_fr(map, v, &front, &rear);
 
     m = PA_MAX(front, rear);
diff --git a/src/pulse/volume.h b/src/pulse/volume.h
index 8eef467..9ad3e9b 100644
--- a/src/pulse/volume.h
+++ b/src/pulse/volume.h
@@ -236,7 +236,9 @@ int pa_cvolume_compatible(const pa_cvolume *v, const pa_sample_spec *ss) PA_GCC_
 
 /** Calculate a 'balance' value for the specified volume with the
  * specified channel map. The return value will range from -1.0f
- * (left) to +1.0f (right) \since 0.9.15 */
+ * (left) to +1.0f (right). If no balance value is applicable to this
+ * channel map the return value will always be 0.0f. See
+ * pa_channel_map_can_balance(). \since 0.9.15 */
 float pa_cvolume_get_balance(const pa_cvolume *v, const pa_channel_map *map) PA_GCC_PURE;
 
 /** Adjust the 'balance' value for the specified volume with the
@@ -245,22 +247,27 @@ float pa_cvolume_get_balance(const pa_cvolume *v, const pa_channel_map *map) PA_
  * operation might not be reversible! Also, after this call
  * pa_cvolume_get_balance() is not guaranteed to actually return the
  * requested balance value (e.g. when the input volume was zero anyway for
- * all channels) \since 0.9.15 */
+ * all channels). If no balance value is applicable to
+ * this channel map the volume will not be modified. See
+ * pa_channel_map_can_balance(). \since 0.9.15 */
 pa_cvolume* pa_cvolume_set_balance(pa_cvolume *v, const pa_channel_map *map, float new_balance);
 
 /** Calculate a 'fade' value (i.e. 'balance' between front and rear)
  * for the specified volume with the specified channel map. The return
- * value will range from -1.0f (rear) to +1.0f (left) \since
- * 0.9.15 */
+ * value will range from -1.0f (rear) to +1.0f (left). If no fade
+ * value is applicable to this channel map the return value will
+ * always be 0.0f. See pa_channel_map_can_fade(). \since 0.9.15 */
 float pa_cvolume_get_fade(const pa_cvolume *v, const pa_channel_map *map) PA_GCC_PURE;
 
 /** Adjust the 'fade' value (i.e. 'balance' between front and rear)
  * for the specified volume with the specified channel map. v will be
  * modified in place and returned. The balance is a value between
  * -1.0f and +1.0f. This operation might not be reversible! Also,
- * after this call pa_cvolume_get_fade() is not guaranteed to
- * actually return the requested fade value (e.g. when the input volume
- * was zero anyway for all channels) \since 0.9.15 */
+ * after this call pa_cvolume_get_fade() is not guaranteed to actually
+ * return the requested fade value (e.g. when the input volume was
+ * zero anyway for all channels). If no fade value is applicable to
+ * this channel map the volume will not be modified. See
+ * pa_channel_map_can_fade(). \since 0.9.15 */
 pa_cvolume* pa_cvolume_set_fade(pa_cvolume *v, const pa_channel_map *map, float new_fade);
 
 /** Scale the passed pa_cvolume structure so that the maximum volume

commit fc31d21353ef3b50c6b47371b8cb10c173bc3a14
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Feb 3 04:06:52 2009 +0100

    when moving a sink between sinks make volume relative

diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index a3a29e9..fc87d5d 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -1073,9 +1073,15 @@ int pa_sink_input_start_move(pa_sink_input *i) {
     if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
         pa_assert_se(i->sink->n_corked-- >= 1);
 
-    /* We might need to update the sink's volume if we are in flat volume mode. */
     if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
         pa_cvolume new_volume;
+
+        /* Make the absolute volume relative */
+        i->virtual_volume = i->soft_volume;
+        pa_cvolume_reset(&i->soft_volume, i->sample_spec.channels);
+
+        /* We might need to update the sink's volume if we are in flat
+         * volume mode. */
         pa_sink_update_flat_volume(i->sink, &new_volume);
         pa_sink_set_volume(i->sink, &new_volume, FALSE, FALSE);
     }
@@ -1156,9 +1162,15 @@ int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
 
     pa_sink_update_status(dest);
 
-    /* We might need to update the sink's volume if we are in flat volume mode. */
     if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
         pa_cvolume new_volume;
+
+        /* Make relative volume absolute again */
+        pa_cvolume t = dest->virtual_volume;
+        pa_cvolume_remap(&t, &dest->channel_map, &i->channel_map);
+        pa_sw_cvolume_multiply(&i->virtual_volume, &i->virtual_volume, &t);
+
+        /* We might need to update the sink's volume if we are in flat volume mode. */
         pa_sink_update_flat_volume(i->sink, &new_volume);
         pa_sink_set_volume(i->sink, &new_volume, FALSE, FALSE);
     }

commit 921882de548e17bbdd79bd8eb2c2ce7d36412cf4
Author: Sjoerd Simons <sjoerd at debian.org>
Date:   Sun Oct 19 13:39:50 2008 +0100

    Load module gconf earlier
    
    This makes sure that module-default-device-restore can actually work
    when GConf enables additional sinks.
    
    Signed-off-by: Lennart Poettering <lennart at poettering.net>

diff --git a/src/daemon/default.pa.in b/src/daemon/default.pa.in
index 5d69926..91a1c61 100755
--- a/src/daemon/default.pa.in
+++ b/src/daemon/default.pa.in
@@ -77,6 +77,15 @@ load-module module-native-protocol-unix
 #load-module module-null-sink sink_name=rtp format=s16be channels=2 rate=44100 description="RTP Multicast Sink"
 #load-module module-rtp-send source=rtp.monitor
 
+### Load additional modules from GConf settings. This can be configured with the paprefs tool.
+### Please keep in mind that the modules configured by paprefs might conflict with manually
+### loaded modules.
+.ifexists module-gconf at PA_SOEXT@
+.nofail
+load-module module-gconf
+.fail
+.endif
+
 ### Automatically restore the default sink/source when changed by the user during runtime
 load-module module-default-device-restore
 
@@ -97,15 +106,6 @@ load-module module-console-kit
 ### Enable positioned event sounds
 load-module module-position-event-sounds
 
-### Load additional modules from GConf settings. This can be configured with the paprefs tool.
-### Please keep in mind that the modules configured by paprefs might conflict with manually
-### loaded modules.
-.ifexists module-gconf at PA_SOEXT@
-.nofail
-load-module module-gconf
-.fail
-.endif
-
 # X11 modules should not be started from default.pa so that one daemon
 # can be shared by multiple sessions.
 

commit 543115ae1726e853624a6214ad58187f6d84c95a
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Feb 3 21:15:32 2009 +0100

    add new API pa_cvolume_compatible_with_channel_map()

diff --git a/src/map-file b/src/map-file
index 3aa1d7a..d7addfe 100644
--- a/src/map-file
+++ b/src/map-file
@@ -109,6 +109,7 @@ pa_context_unref;
 pa_cvolume_avg;
 pa_cvolume_channels_equal_to;
 pa_cvolume_compatible;
+pa_cvolume_compatible_with_channel_map;
 pa_cvolume_equal;
 pa_cvolume_get_balance;
 pa_cvolume_get_fade;
diff --git a/src/pulse/volume.c b/src/pulse/volume.c
index 01a28e8..e920288 100644
--- a/src/pulse/volume.c
+++ b/src/pulse/volume.c
@@ -428,6 +428,19 @@ int pa_cvolume_compatible(const pa_cvolume *v, const pa_sample_spec *ss) {
     return v->channels == ss->channels;
 }
 
+int pa_cvolume_compatible_with_channel_map(const pa_cvolume *v, const pa_channel_map *cm) {
+    pa_assert(v);
+    pa_assert(cm);
+
+    if (!pa_cvolume_valid(v))
+        return 0;
+
+    if (!pa_channel_map_valid(cm))
+        return 0;
+
+    return v->channels == cm->channels;
+}
+
 static void get_avg_lr(const pa_channel_map *map, const pa_cvolume *v, pa_volume_t *l, pa_volume_t *r) {
     int c;
     pa_volume_t left = 0, right = 0;
diff --git a/src/pulse/volume.h b/src/pulse/volume.h
index 9ad3e9b..8bfd068 100644
--- a/src/pulse/volume.h
+++ b/src/pulse/volume.h
@@ -230,10 +230,14 @@ double pa_sw_volume_to_linear(pa_volume_t v) PA_GCC_CONST;
 /** Remap a volume from one channel mapping to a different channel mapping. \since 0.9.12 */
 pa_cvolume *pa_cvolume_remap(pa_cvolume *v, const pa_channel_map *from, const pa_channel_map *to);
 
-/** Return non-zero if the specified volume is compatible with
- * the specified sample spec. \since 0.9.13 */
+/** Return non-zero if the specified volume is compatible with the
+ * specified sample spec. \since 0.9.13 */
 int pa_cvolume_compatible(const pa_cvolume *v, const pa_sample_spec *ss) PA_GCC_PURE;
 
+/** Return non-zero if the specified volume is compatible with the
+ * specified sample spec. \since 0.9.15 */
+int pa_cvolume_compatible_with_channel_map(const pa_cvolume *v, const pa_channel_map *cm) PA_GCC_PURE;
+
 /** Calculate a 'balance' value for the specified volume with the
  * specified channel map. The return value will range from -1.0f
  * (left) to +1.0f (right). If no balance value is applicable to this

commit b51ed381162b43e55c665dbdb61e2ce4a796a4df
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Feb 3 21:56:52 2009 +0100

    add a bit of missing i18n

diff --git a/src/pulse/channelmap.c b/src/pulse/channelmap.c
index 6ff30c2..43e5f83 100644
--- a/src/pulse/channelmap.c
+++ b/src/pulse/channelmap.c
@@ -434,11 +434,11 @@ const char* pa_channel_position_to_string(pa_channel_position_t pos) {
 
 const char* pa_channel_position_to_pretty_string(pa_channel_position_t pos) {
 
-    pa_init_i18n();
-
     if (pos < 0 || pos >= PA_CHANNEL_POSITION_MAX)
         return NULL;
 
+    pa_init_i18n();
+
     return _(pretty_table[pos]);
 }
 
@@ -502,19 +502,19 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) {
      * "mono" here explicitly, because that can be understood as
      * listing with one channel called "mono". */
 
-    if (strcmp(s, "stereo") == 0) {
+    if (pa_streq(s, "stereo")) {
         map.channels = 2;
         map.map[0] = PA_CHANNEL_POSITION_LEFT;
         map.map[1] = PA_CHANNEL_POSITION_RIGHT;
         goto finish;
-    } else if (strcmp(s, "surround-40") == 0) {
+    } else if (pa_streq(s, "surround-40")) {
         map.channels = 4;
         map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
         map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
         map.map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
         map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
         goto finish;
-    } else if (strcmp(s, "surround-41") == 0) {
+    } else if (pa_streq(s, "surround-41")) {
         map.channels = 5;
         map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
         map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
@@ -522,7 +522,7 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) {
         map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
         map.map[4] = PA_CHANNEL_POSITION_LFE;
         goto finish;
-    } else if (strcmp(s, "surround-50") == 0) {
+    } else if (pa_streq(s, "surround-50")) {
         map.channels = 5;
         map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
         map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
@@ -530,7 +530,7 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) {
         map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
         map.map[4] = PA_CHANNEL_POSITION_FRONT_CENTER;
         goto finish;
-    } else if (strcmp(s, "surround-51") == 0) {
+    } else if (pa_streq(s, "surround-51")) {
         map.channels = 6;
         map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
         map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
@@ -539,7 +539,7 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) {
         map.map[4] = PA_CHANNEL_POSITION_FRONT_CENTER;
         map.map[5] = PA_CHANNEL_POSITION_LFE;
         goto finish;
-    } else if (strcmp(s, "surround-71") == 0) {
+    } else if (pa_streq(s, "surround-71")) {
         map.channels = 8;
         map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
         map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
@@ -563,13 +563,13 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) {
         }
 
         /* Some special aliases */
-        if (strcmp(p, "left") == 0)
+        if (pa_streq(p, "left"))
             map.map[map.channels++] = PA_CHANNEL_POSITION_LEFT;
-        else if (strcmp(p, "right") == 0)
+        else if (pa_streq(p, "right"))
             map.map[map.channels++] = PA_CHANNEL_POSITION_RIGHT;
-        else if (strcmp(p, "center") == 0)
+        else if (pa_streq(p, "center"))
             map.map[map.channels++] = PA_CHANNEL_POSITION_CENTER;
-        else if (strcmp(p, "subwoofer") == 0)
+        else if (pa_streq(p, "subwoofer"))
             map.map[map.channels++] = PA_CHANNEL_POSITION_SUBWOOFER;
         else {
             pa_channel_position_t i;
@@ -784,6 +784,8 @@ const char* pa_channel_map_to_pretty_name(const pa_channel_map *map) {
     for (c = 0; c < map->channels; c++)
         pa_bitset_set(in_map, map->map[c], TRUE);
 
+    pa_init_i18n();
+
     if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
                          PA_CHANNEL_POSITION_MONO, -1))
         return _("Mono");
diff --git a/src/pulse/sample.c b/src/pulse/sample.c
index a6c7734..5528a59 100644
--- a/src/pulse/sample.c
+++ b/src/pulse/sample.c
@@ -151,22 +151,25 @@ char *pa_sample_spec_snprint(char *s, size_t l, const pa_sample_spec *spec) {
     if (!pa_sample_spec_valid(spec))
         pa_snprintf(s, l, _("(invalid)"));
     else
-        pa_snprintf(s, l, "%s %uch %uHz", pa_sample_format_to_string(spec->format), spec->channels, spec->rate);
+        pa_snprintf(s, l, _("%s %uch %uHz"), pa_sample_format_to_string(spec->format), spec->channels, spec->rate);
 
     return s;
 }
 
 char* pa_bytes_snprint(char *s, size_t l, unsigned v) {
     pa_assert(s);
+    pa_assert(l > 0);
+
+    pa_init_i18n();
 
     if (v >= ((unsigned) 1024)*1024*1024)
-        pa_snprintf(s, l, "%0.1f GiB", ((double) v)/1024/1024/1024);
+        pa_snprintf(s, l, _("%0.1f GiB"), ((double) v)/1024/1024/1024);
     else if (v >= ((unsigned) 1024)*1024)
-        pa_snprintf(s, l, "%0.1f MiB", ((double) v)/1024/1024);
+        pa_snprintf(s, l, _("%0.1f MiB"), ((double) v)/1024/1024);
     else if (v >= (unsigned) 1024)
-        pa_snprintf(s, l, "%0.1f KiB", ((double) v)/1024);
+        pa_snprintf(s, l, _("%0.1f KiB"), ((double) v)/1024);
     else
-        pa_snprintf(s, l, "%u B", (unsigned) v);
+        pa_snprintf(s, l, _("%u B"), (unsigned) v);
 
     return s;
 }

commit 32e5e64921febb219c0b7ed8ca7da141b4ad0f23
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Feb 3 21:57:58 2009 +0100

    add a lot of validity checking

diff --git a/src/pulse/channelmap.c b/src/pulse/channelmap.c
index 43e5f83..983b897 100644
--- a/src/pulse/channelmap.c
+++ b/src/pulse/channelmap.c
@@ -448,6 +448,9 @@ int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) {
     pa_assert(a);
     pa_assert(b);
 
+    pa_return_val_if_fail(pa_channel_map_valid(a), 0);
+    pa_return_val_if_fail(pa_channel_map_valid(b), 0);
+
     if (a->channels != b->channels)
         return 0;
 
@@ -617,11 +620,8 @@ int pa_channel_map_compatible(const pa_channel_map *map, const pa_sample_spec *s
     pa_assert(map);
     pa_assert(ss);
 
-    if (!pa_channel_map_valid(map))
-        return 0;
-
-    if (!pa_sample_spec_valid(ss))
-        return 0;
+    pa_return_val_if_fail(pa_channel_map_valid(map), 0);
+    pa_return_val_if_fail(pa_sample_spec_valid(ss), 0);
 
     return map->channels == ss->channels;
 }
@@ -633,6 +633,9 @@ int pa_channel_map_superset(const pa_channel_map *a, const pa_channel_map *b) {
     pa_assert(a);
     pa_assert(b);
 
+    pa_return_val_if_fail(pa_channel_map_valid(a), 0);
+    pa_return_val_if_fail(pa_channel_map_valid(b), 0);
+
     memset(in_a, 0, sizeof(in_a));
 
     for (i = 0; i < a->channels; i++)
@@ -651,6 +654,8 @@ int pa_channel_map_can_balance(const pa_channel_map *map) {
 
     pa_assert(map);
 
+    pa_return_val_if_fail(pa_channel_map_valid(map), 0);
+
     for (c = 0; c < map->channels; c++) {
 
         switch (map->map[c]) {
@@ -687,6 +692,10 @@ int pa_channel_map_can_fade(const pa_channel_map *map) {
     unsigned c;
     pa_bool_t front = FALSE, rear = FALSE;
 
+    pa_assert(map);
+
+    pa_return_val_if_fail(pa_channel_map_valid(map), 0);
+
     for (c = 0; c < map->channels; c++) {
 
         switch (map->map[c]) {
@@ -727,6 +736,8 @@ const char* pa_channel_map_to_name(const pa_channel_map *map) {
 
     pa_assert(map);
 
+    pa_return_val_if_fail(pa_channel_map_valid(map), NULL);
+
     memset(in_map, 0, sizeof(in_map));
 
     for (c = 0; c < map->channels; c++)
@@ -779,6 +790,8 @@ const char* pa_channel_map_to_pretty_name(const pa_channel_map *map) {
 
     pa_assert(map);
 
+    pa_return_val_if_fail(pa_channel_map_valid(map), NULL);
+
     memset(in_map, 0, sizeof(in_map));
 
     for (c = 0; c < map->channels; c++)
diff --git a/src/pulse/sample.c b/src/pulse/sample.c
index 5528a59..ff86d0b 100644
--- a/src/pulse/sample.c
+++ b/src/pulse/sample.c
@@ -55,31 +55,35 @@ size_t pa_sample_size(const pa_sample_spec *spec) {
     };
 
     pa_assert(spec);
-    pa_assert(spec->format >= 0);
-    pa_assert(spec->format < PA_SAMPLE_MAX);
+    pa_return_val_if_fail(pa_sample_spec_valid(spec), 0);
 
     return table[spec->format];
 }
 
 size_t pa_frame_size(const pa_sample_spec *spec) {
     pa_assert(spec);
+    pa_return_val_if_fail(pa_sample_spec_valid(spec), 0);
 
     return pa_sample_size(spec) * spec->channels;
 }
 
 size_t pa_bytes_per_second(const pa_sample_spec *spec) {
     pa_assert(spec);
+    pa_return_val_if_fail(pa_sample_spec_valid(spec), 0);
+
     return spec->rate*pa_frame_size(spec);
 }
 
 pa_usec_t pa_bytes_to_usec(uint64_t length, const pa_sample_spec *spec) {
     pa_assert(spec);
+    pa_return_val_if_fail(pa_sample_spec_valid(spec), 0);
 
     return (((pa_usec_t) (length / pa_frame_size(spec)) * PA_USEC_PER_SEC) / spec->rate);
 }
 
 size_t pa_usec_to_bytes(pa_usec_t t, const pa_sample_spec *spec) {
     pa_assert(spec);
+    pa_return_val_if_fail(pa_sample_spec_valid(spec), 0);
 
     return (size_t) (((t * spec->rate) / PA_USEC_PER_SEC)) * pa_frame_size(spec);
 }
@@ -112,6 +116,9 @@ int pa_sample_spec_equal(const pa_sample_spec*a, const pa_sample_spec*b) {
     pa_assert(a);
     pa_assert(b);
 
+    pa_return_val_if_fail(pa_sample_spec_valid(a), 0);
+    pa_return_val_if_fail(pa_sample_spec_valid(b), 0);
+
     return
         (a->format == b->format) &&
         (a->rate == b->rate) &&
@@ -143,7 +150,7 @@ const char *pa_sample_format_to_string(pa_sample_format_t f) {
 
 char *pa_sample_spec_snprint(char *s, size_t l, const pa_sample_spec *spec) {
     pa_assert(s);
-    pa_assert(l);
+    pa_assert(l > 0);
     pa_assert(spec);
 
     pa_init_i18n();
diff --git a/src/pulse/volume.c b/src/pulse/volume.c
index e920288..54838e8 100644
--- a/src/pulse/volume.c
+++ b/src/pulse/volume.c
@@ -37,6 +37,9 @@ int pa_cvolume_equal(const pa_cvolume *a, const pa_cvolume *b) {
     pa_assert(a);
     pa_assert(b);
 
+    pa_return_val_if_fail(pa_cvolume_valid(a), 0);
+    pa_return_val_if_fail(pa_cvolume_valid(b), 0);
+
     if (a->channels != b->channels)
         return 0;
 
@@ -78,7 +81,9 @@ pa_cvolume* pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v) {
 pa_volume_t pa_cvolume_avg(const pa_cvolume *a) {
     uint64_t sum = 0;
     int i;
+
     pa_assert(a);
+    pa_return_val_if_fail(pa_cvolume_valid(a), PA_VOLUME_MUTED);
 
     for (i = 0; i < a->channels; i++)
         sum += a->values[i];
@@ -91,7 +96,9 @@ pa_volume_t pa_cvolume_avg(const pa_cvolume *a) {
 pa_volume_t pa_cvolume_max(const pa_cvolume *a) {
     pa_volume_t m = 0;
     int i;
+
     pa_assert(a);
+    pa_return_val_if_fail(pa_cvolume_valid(a), PA_VOLUME_MUTED);
 
     for (i = 0; i < a->channels; i++)
         if (a->values[i] > m)
@@ -247,11 +254,12 @@ char *pa_sw_volume_snprint_dB(char *s, size_t l, pa_volume_t v) {
     return s;
 }
 
-/** Return non-zero if the volume of all channels is equal to the specified value */
 int pa_cvolume_channels_equal_to(const pa_cvolume *a, pa_volume_t v) {
     unsigned c;
     pa_assert(a);
 
+    pa_return_val_if_fail(pa_cvolume_valid(a), 0);
+
     for (c = 0; c < a->channels; c++)
         if (a->values[c] != v)
             return 0;
@@ -266,6 +274,9 @@ pa_cvolume *pa_sw_cvolume_multiply(pa_cvolume *dest, const pa_cvolume *a, const
     pa_assert(a);
     pa_assert(b);
 
+    pa_return_val_if_fail(pa_cvolume_valid(a), NULL);
+    pa_return_val_if_fail(pa_cvolume_valid(b), NULL);
+
     for (i = 0; i < a->channels && i < b->channels && i < PA_CHANNELS_MAX; i++)
         dest->values[i] = pa_sw_volume_multiply(a->values[i], b->values[i]);
 
@@ -281,6 +292,9 @@ pa_cvolume *pa_sw_cvolume_divide(pa_cvolume *dest, const pa_cvolume *a, const pa
     pa_assert(a);
     pa_assert(b);
 
+    pa_return_val_if_fail(pa_cvolume_valid(a), NULL);
+    pa_return_val_if_fail(pa_cvolume_valid(b), NULL);
+
     for (i = 0; i < a->channels && i < b->channels && i < PA_CHANNELS_MAX; i++)
         dest->values[i] = pa_sw_volume_divide(a->values[i], b->values[i]);
 
@@ -373,7 +387,11 @@ pa_cvolume *pa_cvolume_remap(pa_cvolume *v, const pa_channel_map *from, const pa
     pa_assert(v);
     pa_assert(from);
     pa_assert(to);
-    pa_assert(v->channels == from->channels);
+
+    pa_return_val_if_fail(pa_cvolume_valid(v), NULL);
+    pa_return_val_if_fail(pa_channel_map_valid(from), NULL);
+    pa_return_val_if_fail(pa_channel_map_valid(to), NULL);
+    pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, from), NULL);
 
     if (pa_channel_map_equal(from, to))
         return v;
@@ -419,11 +437,8 @@ int pa_cvolume_compatible(const pa_cvolume *v, const pa_sample_spec *ss) {
     pa_assert(v);
     pa_assert(ss);
 
-    if (!pa_cvolume_valid(v))
-        return 0;
-
-    if (!pa_sample_spec_valid(ss))
-        return 0;
+    pa_return_val_if_fail(pa_cvolume_valid(v), 0);
+    pa_return_val_if_fail(pa_sample_spec_valid(ss), 0);
 
     return v->channels == ss->channels;
 }
@@ -432,11 +447,8 @@ int pa_cvolume_compatible_with_channel_map(const pa_cvolume *v, const pa_channel
     pa_assert(v);
     pa_assert(cm);
 
-    if (!pa_cvolume_valid(v))
-        return 0;
-
-    if (!pa_channel_map_valid(cm))
-        return 0;
+    pa_return_val_if_fail(pa_cvolume_valid(v), 0);
+    pa_return_val_if_fail(pa_channel_map_valid(cm), 0);
 
     return v->channels == cm->channels;
 }
@@ -478,7 +490,10 @@ float pa_cvolume_get_balance(const pa_cvolume *v, const pa_channel_map *map) {
 
     pa_assert(v);
     pa_assert(map);
-    pa_assert(map->channels == v->channels);
+
+    pa_return_val_if_fail(pa_cvolume_valid(v), 0.0f);
+    pa_return_val_if_fail(pa_channel_map_valid(map), 0.0f);
+    pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, map), 0.0f);
 
     if (!pa_channel_map_can_balance(map))
         return 0.0f;
@@ -507,12 +522,15 @@ pa_cvolume* pa_cvolume_set_balance(pa_cvolume *v, const pa_channel_map *map, flo
     pa_volume_t left, nleft, right, nright, m;
     unsigned c;
 
-    pa_assert(map->channels == v->channels);
     pa_assert(map);
     pa_assert(v);
     pa_assert(new_balance >= -1.0f);
     pa_assert(new_balance <= 1.0f);
 
+    pa_return_val_if_fail(pa_cvolume_valid(v), NULL);
+    pa_return_val_if_fail(pa_channel_map_valid(map), NULL);
+    pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, map), NULL);
+
     if (!pa_channel_map_can_balance(map))
         return v;
 
@@ -551,6 +569,9 @@ pa_cvolume* pa_cvolume_scale(pa_cvolume *v, pa_volume_t max) {
 
     pa_assert(v);
 
+    pa_return_val_if_fail(pa_cvolume_valid(v), NULL);
+    pa_return_val_if_fail(max != (pa_volume_t) -1, NULL);
+
     for (c = 0; c < v->channels; c++)
         if (v->values[c] > t)
             t = v->values[c];
@@ -601,7 +622,10 @@ float pa_cvolume_get_fade(const pa_cvolume *v, const pa_channel_map *map) {
 
     pa_assert(v);
     pa_assert(map);
-    pa_assert(map->channels == v->channels);
+
+    pa_return_val_if_fail(pa_cvolume_valid(v), 0.0f);
+    pa_return_val_if_fail(pa_channel_map_valid(map), 0.0f);
+    pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, map), 0.0f);
 
     if (!pa_channel_map_can_fade(map))
         return 0.0f;
@@ -621,12 +645,15 @@ pa_cvolume* pa_cvolume_set_fade(pa_cvolume *v, const pa_channel_map *map, float
     pa_volume_t front, nfront, rear, nrear, m;
     unsigned c;
 
-    pa_assert(map->channels == v->channels);
     pa_assert(map);
     pa_assert(v);
     pa_assert(new_fade >= -1.0f);
     pa_assert(new_fade <= 1.0f);
 
+    pa_return_val_if_fail(pa_cvolume_valid(v), NULL);
+    pa_return_val_if_fail(pa_channel_map_valid(map), NULL);
+    pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, map), NULL);
+
     if (!pa_channel_map_can_fade(map))
         return v;
 

commit e28903e9e024702625f164a5e069fb2f4c275def
Author: Colin Guthrie <pulse at colin.guthr.ie>
Date:   Wed Jan 28 22:39:29 2009 +0000

    Clean up volume/mute settings a bit.
    As the APEX device only has one channel of volume (e.g. it's always matched) we emulate any variation in channel volumes in software.
    Remove the unnecessary callback defininitions.

diff --git a/src/modules/module-raop-sink.c b/src/modules/module-raop-sink.c
index 74ee612..cfdda8d 100644
--- a/src/modules/module-raop-sink.c
+++ b/src/modules/module-raop-sink.c
@@ -100,9 +100,6 @@ struct userdata {
 
     pa_usec_t latency;
 
-    pa_volume_t volume;
-    pa_bool_t muted;
-
     /*esd_format_t format;*/
     int32_t rate;
 
@@ -133,6 +130,9 @@ enum {
     SINK_MESSAGE_RIP_SOCKET
 };
 
+/* Forward declaration */
+static void sink_set_volume_cb(pa_sink *);
+
 static void on_connection(PA_GCC_UNUSED int fd, void*userdata) {
     struct userdata *u = userdata;
     pa_assert(u);
@@ -141,7 +141,7 @@ static void on_connection(PA_GCC_UNUSED int fd, void*userdata) {
     u->fd = fd;
 
     /* Set the initial volume */
-    pa_raop_client_set_volume(u->raop, u->volume);
+    sink_set_volume_cb(u->sink);
 
     pa_log_debug("Connection authenticated, handing fd to IO thread...");
 
@@ -255,43 +255,36 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
     return pa_sink_process_msg(o, code, data, offset, chunk);
 }
 
-static void sink_get_volume_cb(pa_sink *s) {
-    struct userdata *u = s->userdata;
-    int i;
-
-    pa_assert(u);
-
-    for (i = 0; i < s->sample_spec.channels; i++)
-        s->virtual_volume.values[i] = u->volume;
-}
-
 static void sink_set_volume_cb(pa_sink *s) {
     struct userdata *u = s->userdata;
-    int rv;
+    pa_cvolume hw;
+    pa_volume_t v;
+    char t[PA_CVOLUME_SNPRINT_MAX];
 
     pa_assert(u);
 
-    /* If we're muted, we fake it */
-    if (u->muted)
+    /* If we're muted we don't need to do anything */
+    if (s->muted)
         return;
 
-    pa_assert(s->sample_spec.channels > 0);
+    /* Calculate the max volume of all channels.
+       We'll use this as our (single) volume on the APEX device and emulate
+       any variation in channel volumes in software */
+    v = pa_cvolume_max(&s->virtual_volume);
 
-    /* Avoid pointless volume sets */
-    if (u->volume == s->virtual_volume.values[0])
-        return;
+    /* Create a pa_cvolume version of our single value */
+    pa_cvolume_set(&hw, s->sample_spec.channels, v);
 
-    rv = pa_raop_client_set_volume(u->raop, s->virtual_volume.values[0]);
-    if (0 == rv)
-        u->volume = s->virtual_volume.values[0];
-}
+    /* Perfome any software manipulation of the volume needed */
+    pa_sw_cvolume_divide(&s->soft_volume, &s->virtual_volume, &hw);
 
-static void sink_get_mute_cb(pa_sink *s) {
-    struct userdata *u = s->userdata;
+    pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->virtual_volume));
+    pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &hw));
+    pa_log_debug("Calculated software volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->soft_volume));
 
-    pa_assert(u);
-
-    s->muted = u->muted;
+    /* Any necessary software volume manipulateion is done so set
+       our hw volume (or v as a single value) on the device */
+    pa_raop_client_set_volume(u->raop, v);
 }
 
 static void sink_set_mute_cb(pa_sink *s) {
@@ -299,8 +292,11 @@ static void sink_set_mute_cb(pa_sink *s) {
 
     pa_assert(u);
 
-    pa_raop_client_set_volume(u->raop, (s->muted ? PA_VOLUME_MUTED : u->volume));
-    u->muted = s->muted;
+    if (s->muted) {
+        pa_raop_client_set_volume(u->raop, PA_VOLUME_MUTED);
+    } else {
+        sink_set_volume_cb(s);
+    }
 }
 
 static void thread_func(void *userdata) {
@@ -541,9 +537,6 @@ int pa__init(pa_module*m) {
     u->next_encoding_overhead = 0;
     u->encoding_ratio = 1.0;
 
-    u->volume = roundf(0.7 * PA_VOLUME_NORM);
-    u->muted = FALSE;
-
     u->rtpoll = pa_rtpoll_new();
     pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
     u->rtpoll_item = NULL;
@@ -583,9 +576,7 @@ int pa__init(pa_module*m) {
 
     u->sink->parent.process_msg = sink_process_msg;
     u->sink->userdata = u;
-    u->sink->get_volume = sink_get_volume_cb;
     u->sink->set_volume = sink_set_volume_cb;
-    u->sink->get_mute = sink_get_mute_cb;
     u->sink->set_mute = sink_set_mute_cb;
     u->sink->flags = PA_SINK_LATENCY|PA_SINK_NETWORK|PA_SINK_HW_VOLUME_CTRL;
 

commit d1957b8325dc66ac6f691b13c8408e820685248a
Author: Colin Guthrie <pulse at colin.guthr.ie>
Date:   Tue Feb 3 23:46:03 2009 +0000

    Trivial typo in a comment

diff --git a/src/modules/module-raop-sink.c b/src/modules/module-raop-sink.c
index cfdda8d..1784b2c 100644
--- a/src/modules/module-raop-sink.c
+++ b/src/modules/module-raop-sink.c
@@ -275,7 +275,7 @@ static void sink_set_volume_cb(pa_sink *s) {
     /* Create a pa_cvolume version of our single value */
     pa_cvolume_set(&hw, s->sample_spec.channels, v);
 
-    /* Perfome any software manipulation of the volume needed */
+    /* Perform any software manipulation of the volume needed */
     pa_sw_cvolume_divide(&s->soft_volume, &s->virtual_volume, &hw);
 
     pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->virtual_volume));

commit 871389ac5d89d7979819ca677efaaad8e80bf6d1
Author: Colin Guthrie <pulse at colin.guthr.ie>
Date:   Tue Feb 3 23:49:43 2009 +0000

    A couple of dependancy ordering fixes.
    
    Make sure libdbus-util.so is installed/relinked prior to libalsa-util.so
    Make sure libbluetooth-util.so is installed/relinked prior to module-bluetooth-discover.so

diff --git a/src/Makefile.am b/src/Makefile.am
index d2917a0..1910a82 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -862,6 +862,13 @@ libavahi_wrap_la_LIBADD = $(AM_LIBADD) $(AVAHI_CFLAGS) libpulsecore- at PA_MAJORMIN
 #        Plug-in libraries        #
 ###################################
 
+if HAVE_DBUS
+# Serveral module (e.g. libalsa-util.la)
+modlibexec_LTLIBRARIES += \
+		libdbus-util.la \
+		module-console-kit.la
+endif
+
 modlibexec_LTLIBRARIES += \
 		module-cli.la \
 		module-cli-protocol-tcp.la \
@@ -989,21 +996,14 @@ endif
 
 if HAVE_HAL
 modlibexec_LTLIBRARIES += \
-		libdbus-util.la \
 		module-hal-detect.la
 endif
 
-if HAVE_DBUS
-modlibexec_LTLIBRARIES += \
-		libdbus-util.la \
-		module-console-kit.la
-endif
-
 if HAVE_BLUEZ
 modlibexec_LTLIBRARIES += \
+		libbluetooth-util.la \
 		module-bluetooth-proximity.la \
 		module-bluetooth-discover.la \
-		libbluetooth-util.la \
 		libbluetooth-ipc.la \
 		libbluetooth-sbc.la \
 		module-bluetooth-device.la

commit 004b38f0f812b7f92d21267deb6d5990eac982ad
Author: Luiz Augusto von Dentz <luiz.dentz at openbossa.org>
Date:   Mon Feb 2 18:18:34 2009 -0300

    Prevent changing volume on wrong device.

diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c
index de6bded..d909d70 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -1068,6 +1068,9 @@ finish:
 
 /*     dbus_error_init(&err); */
 
+/*    if (!dbus_message_has_path(msg, u->path)) */
+/*        goto done; */
+
 /*     if (dbus_message_is_signal(msg, "org.bluez.Headset", "PropertyChanged") || */
 /*         dbus_message_is_signal(msg, "org.bluez.AudioSink", "PropertyChanged")) { */
 

commit ce76216bce9981c31ebab2ca5a97d6c5c0509edd
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 17:10:15 2009 +0100

    add pa_sample_size_of_format()

diff --git a/src/map-file b/src/map-file
index d7addfe..cdb9deb 100644
--- a/src/map-file
+++ b/src/map-file
@@ -181,6 +181,7 @@ pa_proplist_unset_many;
 pa_proplist_update;
 pa_sample_format_to_string;
 pa_sample_size;
+pa_sample_size_of_format;
 pa_sample_spec_equal;
 pa_sample_spec_init;
 pa_sample_spec_snprint;
diff --git a/src/pulse/sample.c b/src/pulse/sample.c
index ff86d0b..4b13a33 100644
--- a/src/pulse/sample.c
+++ b/src/pulse/sample.c
@@ -36,7 +36,7 @@
 
 #include "sample.h"
 
-size_t pa_sample_size(const pa_sample_spec *spec) {
+size_t pa_sample_size_of_format(pa_sample_format_t f) {
 
     static const size_t table[] = {
         [PA_SAMPLE_U8] = 1,
@@ -54,10 +54,18 @@ size_t pa_sample_size(const pa_sample_spec *spec) {
         [PA_SAMPLE_S24_32BE] = 4
     };
 
+    pa_assert(f >= 0);
+    pa_assert(f < PA_SAMPLE_MAX);
+
+    return table[f];
+}
+
+size_t pa_sample_size(const pa_sample_spec *spec) {
+
     pa_assert(spec);
     pa_return_val_if_fail(pa_sample_spec_valid(spec), 0);
 
-    return table[spec->format];
+    return pa_sample_size_of_format(spec->format);
 }
 
 size_t pa_frame_size(const pa_sample_spec *spec) {
diff --git a/src/pulse/sample.h b/src/pulse/sample.h
index 45a481f..3c05b54 100644
--- a/src/pulse/sample.h
+++ b/src/pulse/sample.h
@@ -261,6 +261,10 @@ size_t pa_frame_size(const pa_sample_spec *spec) PA_GCC_PURE;
 /** Return the size of a sample with the specific sample type */
 size_t pa_sample_size(const pa_sample_spec *spec) PA_GCC_PURE;
 
+/** Similar to pa_sample_size() but take a sample format instead of a
+ * full sample spec. \since 0.9.15 */
+size_t pa_sample_size_of_format(pa_sample_format_t f) PA_GCC_PURE;
+
 /** Calculate the time the specified bytes take to play with the
  * specified sample type. The return value will always be rounded
  * down for non-integral return values. */

commit 0fc59e4585937b155125ef01b0e8c2ae9e5f6cee
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 17:11:56 2009 +0100

    add new API pa_ascii_valid(), pa_ascii_filter()

diff --git a/src/map-file b/src/map-file
index cdb9deb..ca4e7a7 100644
--- a/src/map-file
+++ b/src/map-file
@@ -1,5 +1,7 @@
 PULSE_0 {
 global:
+pa_ascii_filter;
+pa_ascii_valid;
 pa_browser_new;
 pa_browser_new_full;
 pa_browser_ref;
diff --git a/src/pulse/utf8.c b/src/pulse/utf8.c
index 7671be4..6b58bde 100644
--- a/src/pulse/utf8.c
+++ b/src/pulse/utf8.c
@@ -263,3 +263,29 @@ char* pa_locale_to_utf8 (const char *str) {
 }
 
 #endif
+
+char *pa_ascii_valid(const char *str) {
+    const char *p;
+    pa_assert(str);
+
+    for (p = str; *p; p++)
+        if ((unsigned char) *p >= 128)
+            return NULL;
+
+    return (char*) str;
+}
+
+char *pa_ascii_filter(const char *str) {
+    char *r, *s, *d;
+    pa_assert(str);
+
+    r = pa_xstrdup(str);
+
+    for (s = r, d = r; *s; s++)
+        if ((unsigned char) *s < 128)
+            *(d++) = *s;
+
+    *d = 0;
+
+    return r;
+}
diff --git a/src/pulse/utf8.h b/src/pulse/utf8.h
index 4d75195..b9f7495 100644
--- a/src/pulse/utf8.h
+++ b/src/pulse/utf8.h
@@ -36,9 +36,15 @@ PA_C_DECL_BEGIN
 /** Test if the specified strings qualifies as valid UTF8. Return the string if so, otherwise NULL */
 char *pa_utf8_valid(const char *str) PA_GCC_PURE;
 
+/** Test if the specified strings qualifies as valid 7-bit ASCII. Return the string if so, otherwise NULL. \since 0.9.15 */
+char *pa_ascii_valid(const char *str) PA_GCC_PURE;
+
 /** Filter all invalid UTF8 characters from the specified string, returning a new fully UTF8 valid string. Don't forget to free the returned string with pa_xfree() */
 char *pa_utf8_filter(const char *str);
 
+/** Filter all invalid ASCII characters from the specified string, returning a new fully ASCII valid string. Don't forget to free the returned string with pa_xfree(). \since 0.9.15 */
+char *pa_ascii_filter(const char *str);
+
 /** Convert a UTF-8 string to the current locale. Free the string using pa_xfree(). */
 char* pa_utf8_to_locale (const char *str);
 

commit b445741ddf61de662eddbbe9fc90817ac0e24c5b
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 17:14:59 2009 +0100

    fix up parser in pa_proplist_from_string() to handle escapes correctly; make pa_proplist_to_string() escape quotes properly

diff --git a/src/pulse/proplist.c b/src/pulse/proplist.c
index 282fe5c..db4c934 100644
--- a/src/pulse/proplist.c
+++ b/src/pulse/proplist.c
@@ -24,6 +24,7 @@
 #endif
 
 #include <string.h>
+#include <ctype.h>
 
 #include <pulse/xmalloc.h>
 #include <pulse/utf8.h>
@@ -46,7 +47,7 @@ struct property {
 
 static pa_bool_t property_name_valid(const char *key) {
 
-    if (!pa_utf8_valid(key))
+    if (!pa_ascii_valid(key))
         return FALSE;
 
     if (strlen(key) <= 0)
@@ -64,8 +65,6 @@ static void property_free(struct property *prop) {
 }
 
 pa_proplist* pa_proplist_new(void) {
-    pa_init_i18n();
-
     return MAKE_PROPLIST(pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func));
 }
 
@@ -83,6 +82,7 @@ int pa_proplist_sets(pa_proplist *p, const char *key, const char *value) {
 
     pa_assert(p);
     pa_assert(key);
+    pa_assert(value);
 
     if (!property_name_valid(key) || !pa_utf8_valid(value))
         return -1;
@@ -104,25 +104,130 @@ int pa_proplist_sets(pa_proplist *p, const char *key, const char *value) {
 }
 
 /** Will accept only valid UTF-8 */
+static int proplist_setn(pa_proplist *p, const char *key, size_t key_length, const char *value, size_t value_length) {
+    struct property *prop;
+    pa_bool_t add = FALSE;
+    char *k, *v;
+
+    pa_assert(p);
+    pa_assert(key);
+    pa_assert(value);
+
+    k = pa_xstrndup(key, key_length);
+    v = pa_xstrndup(value, value_length);
+
+    if (!property_name_valid(k) || !pa_utf8_valid(v)) {
+        pa_xfree(k);
+        pa_xfree(v);
+        return -1;
+    }
+
+    if (!(prop = pa_hashmap_get(MAKE_HASHMAP(p), k))) {
+        prop = pa_xnew(struct property, 1);
+        prop->key = k;
+        add = TRUE;
+    } else {
+        pa_xfree(prop->value);
+        pa_xfree(k);
+    }
+
+    prop->value = v;
+    prop->nbytes = strlen(v)+1;
+
+    if (add)
+        pa_hashmap_put(MAKE_HASHMAP(p), prop->key, prop);
+
+    return 0;
+}
+
+static int proplist_sethex(pa_proplist *p, const char *key, size_t key_length, const char *value, size_t value_length) {
+    struct property *prop;
+    pa_bool_t add = FALSE;
+    char *k, *v;
+    uint8_t *d;
+    size_t dn;
+
+    pa_assert(p);
+    pa_assert(key);
+    pa_assert(value);
+
+    k = pa_xstrndup(key, key_length);
+
+    if (!property_name_valid(k)) {
+        pa_xfree(k);
+        return -1;
+    }
+
+    v = pa_xstrndup(value, value_length);
+    d = pa_xmalloc(value_length*2+1);
+
+    if ((dn = pa_parsehex(v, d, value_length*2)) == (size_t) -1) {
+        pa_xfree(k);
+        pa_xfree(v);
+        pa_xfree(d);
+        return -1;
+    }
+
+    pa_xfree(v);
+
+    if (!(prop = pa_hashmap_get(MAKE_HASHMAP(p), k))) {
+        prop = pa_xnew(struct property, 1);
+        prop->key = k;
+        add = TRUE;
+    } else {
+        pa_xfree(prop->value);
+        pa_xfree(k);
+    }
+
+    d[dn] = 0;
+    prop->value = d;
+    prop->nbytes = dn;
+
+    if (add)
+        pa_hashmap_put(MAKE_HASHMAP(p), prop->key, prop);
+
+    return 0;
+}
+
+/** Will accept only valid UTF-8 */
 int pa_proplist_setf(pa_proplist *p, const char *key, const char *format, ...) {
+    struct property *prop;
+    pa_bool_t add = FALSE;
     va_list ap;
-    int r;
-    char *t;
+    char *v;
 
     pa_assert(p);
     pa_assert(key);
+    pa_assert(format);
 
     if (!property_name_valid(key) || !pa_utf8_valid(format))
         return -1;
 
     va_start(ap, format);
-    t = pa_vsprintf_malloc(format, ap);
+    v = pa_vsprintf_malloc(format, ap);
     va_end(ap);
 
-    r = pa_proplist_sets(p, key, t);
+    if (!pa_utf8_valid(v))
+        goto fail;
 
-    pa_xfree(t);
-    return r;
+    if (!(prop = pa_hashmap_get(MAKE_HASHMAP(p), key))) {
+        prop = pa_xnew(struct property, 1);
+        prop->key = pa_xstrdup(key);
+        add = TRUE;
+    } else
+        pa_xfree(prop->value);
+
+    prop->value = v;
+    prop->nbytes = strlen(v)+1;
+
+    if (add)
+        pa_hashmap_put(MAKE_HASHMAP(p), prop->key, prop);
+
+    return 0;
+
+fail:
+    pa_xfree(v);
+    return -1;
 }
 
 int pa_proplist_set(pa_proplist *p, const char *key, const void *data, size_t nbytes) {
@@ -131,6 +236,7 @@ int pa_proplist_set(pa_proplist *p, const char *key, const void *data, size_t nb
 
     pa_assert(p);
     pa_assert(key);
+    pa_assert(data);
 
     if (!property_name_valid(key))
         return -1;
@@ -142,7 +248,9 @@ int pa_proplist_set(pa_proplist *p, const char *key, const void *data, size_t nb
     } else
         pa_xfree(prop->value);
 
-    prop->value = pa_xmemdup(data, nbytes);
+    prop->value = pa_xmalloc(nbytes+1);
+    memcpy(prop->value, data, nbytes);
+    ((char*) prop->value)[nbytes] = 0;
     prop->nbytes = nbytes;
 
     if (add)
@@ -183,6 +291,8 @@ int pa_proplist_get(pa_proplist *p, const char *key, const void **data, size_t *
 
     pa_assert(p);
     pa_assert(key);
+    pa_assert(data);
+    pa_assert(nbytes);
 
     if (!property_name_valid(key))
         return -1;
@@ -275,9 +385,32 @@ char *pa_proplist_to_string_sep(pa_proplist *p, const char *sep) {
         if (!pa_strbuf_isempty(buf))
             pa_strbuf_puts(buf, sep);
 
-        if ((v = pa_proplist_gets(p, key)))
-            pa_strbuf_printf(buf, "%s = \"%s\"", key, v);
-        else {
+        if ((v = pa_proplist_gets(p, key))) {
+            const char *t;
+
+            pa_strbuf_printf(buf, "%s = \"", key);
+
+            for (t = v;;) {
+                size_t h;
+
+                h = strcspn(t, "\"");
+
+                if (h > 0)
+                    pa_strbuf_putsn(buf, t, h);
+
+                t += h;
+
+                if (*t == 0)
+                    break;
+
+                pa_assert(*t == '"');
+                pa_strbuf_puts(buf, "\\\"");
+
+                t++;
+            }
+
+            pa_strbuf_puts(buf, "\"");
+        } else {
             const void *value;
             size_t nbytes;
             char *c;
@@ -304,88 +437,189 @@ char *pa_proplist_to_string(pa_proplist *p) {
     return t;
 }
 
-/* Remove all whitepsapce from the beginning and the end of *s. *s may
- * be modified. (from conf-parser.c) */
-#define WHITESPACE " \t\n"
-#define in_string(c,s) (strchr(s,c) != NULL)
-
-static char *strip(char *s) {
-    char *b = s+strspn(s, WHITESPACE);
-    char *e, *l = NULL;
-
-    for (e = b; *e; e++)
-        if (!in_string(*e, WHITESPACE))
-            l = e;
+pa_proplist *pa_proplist_from_string(const char *s) {
+    enum {
+        WHITESPACE,
+        KEY,
+        AFTER_KEY,
+        VALUE_START,
+        VALUE_SIMPLE,
+        VALUE_DOUBLE_QUOTES,
+        VALUE_DOUBLE_QUOTES_ESCAPE,
+        VALUE_TICKS,
+        VALUE_TICKS_ESCAPED,
+        VALUE_HEX
+    } state;
+
+    pa_proplist *pl;
+    const char *p, *key = NULL, *value = NULL;
+    size_t key_len = 0, value_len = 0;
+
+    pa_assert(s);
+
+    pl = pa_proplist_new();
+
+    state = WHITESPACE;
+
+    for (p = s;; p++) {
+        switch (state) {
+
+            case WHITESPACE:
+                if (*p == 0)
+                    goto success;
+                else if (*p == '=')
+                    goto fail;
+                else if (!isspace(*p)) {
+                    key = p;
+                    state = KEY;
+                    key_len = 1;
+                }
+                break;
 
-    if (l)
-        *(l+1) = 0;
+            case KEY:
+                if (*p == 0)
+                    goto fail;
+                else if (*p == '=')
+                    state = VALUE_START;
+                else if (isspace(*p))
+                    state = AFTER_KEY;
+                else
+                    key_len++;
+                break;
 
-    return b;
-}
+            case AFTER_KEY:
+                if (*p == 0)
+                    goto fail;
+                else if (*p == '=')
+                    state = VALUE_START;
+                else if (!isspace(*p))
+                    goto fail;
+                break;
 
-pa_proplist *pa_proplist_from_string(const char *str) {
-    pa_proplist *p;
-    char *s, *v, *k, *e;
+            case VALUE_START:
+                if (*p == 0)
+                    goto fail;
+                else if (strncmp(p, "hex:", 4) == 0) {
+                    state = VALUE_HEX;
+                    value = p+4;
+                    value_len = 0;
+                    p += 3;
+                } else if (*p == '\'') {
+                    state = VALUE_TICKS;
+                    value = p+1;
+                    value_len = 0;
+                } else if (*p == '"') {
+                    state = VALUE_DOUBLE_QUOTES;
+                    value = p+1;
+                    value_len = 0;
+                } else if (!isspace(*p)) {
+                    state = VALUE_SIMPLE;
+                    value = p;
+                    value_len = 1;
+                }
+                break;
 
-    pa_assert(str);
-    pa_assert_se(p = pa_proplist_new());
-    pa_assert_se(s = strdup(str));
+            case VALUE_SIMPLE:
+                if (*p == 0 || isspace(*p)) {
+                    if (proplist_setn(pl, key, key_len, value, value_len) < 0)
+                        goto fail;
 
-    for (k = s; *k; k = e) {
-        k = k+strspn(k, WHITESPACE);
+                    if (*p == 0)
+                        goto success;
 
-        if (!*k)
-            break;
+                    state = WHITESPACE;
+                } else
+                    value_len++;
+                break;
 
-        if (!(v = strchr(k, '='))) {
-            pa_log("Missing '='.");
-            break;
-        }
+            case VALUE_DOUBLE_QUOTES:
+                if (*p == 0)
+                    goto fail;
+                else if (*p == '"') {
+                    char *v;
+
+                    v = pa_unescape(pa_xstrndup(value, value_len));
+
+                    if (proplist_setn(pl, key, key_len, v, strlen(v)) < 0) {
+                        pa_xfree(v);
+                        goto fail;
+                    }
+
+                    pa_xfree(v);
+                    state = WHITESPACE;
+                } else if (*p == '\\') {
+                    state = VALUE_DOUBLE_QUOTES_ESCAPE;
+                    value_len++;
+                } else
+                    value_len++;
+                break;
 
-        *v++ = '\0';
-        k = strip(k);
+            case VALUE_DOUBLE_QUOTES_ESCAPE:
+                if (*p == 0)
+                    goto fail;
+                else {
+                    state = VALUE_DOUBLE_QUOTES;
+                    value_len++;
+                }
+                break;
 
-        v = v+strspn(v, WHITESPACE);
-        if (*v == '"') {
-            v++;
-            if (!(e = strchr(v, '"'))) { /* FIXME: handle escape */
-                pa_log("Missing '\"' at end of string value.");
+            case VALUE_TICKS:
+                if (*p == 0)
+                    goto fail;
+                else if (*p == '\'') {
+                    char *v;
+
+                    v = pa_unescape(pa_xstrndup(value, value_len));
+
+                    if (proplist_setn(pl, key, key_len, v, strlen(v)) < 0) {
+                        pa_xfree(v);
+                        goto fail;
+                    }
+
+                    pa_xfree(v);
+                    state = WHITESPACE;
+                } else if (*p == '\\') {
+                    state = VALUE_TICKS_ESCAPED;
+                    value_len++;
+                } else
+                    value_len++;
                 break;
-            }
-            *e++ = '\0';
-            pa_proplist_sets(p, k, v);
-        } else {
-            uint8_t *blob;
 
-            if (*v++ != 'h' || *v++ != 'e' || *v++ != 'x' || *v++ != ':') {
-                pa_log("Value must be a string or \"hex:\"");
+            case VALUE_TICKS_ESCAPED:
+                if (*p == 0)
+                    goto fail;
+                else {
+                    state = VALUE_TICKS;
+                    value_len++;
+                }
                 break;
-            }
 
-            e = v;
-            while (in_string(*e, "0123456789abcdefABCDEF"))
-                ++e;
+            case VALUE_HEX:
+                if ((*p >= '0' && *p <= '9') ||
+                    (*p >= 'A' && *p <= 'F') ||
+                    (*p >= 'a' && *p <= 'f')) {
+                    value_len++;
+                } else if (*p == 0 || isspace(*p)) {
 
-            if ((e - v) % 2) {
-                pa_log("Invalid \"hex:\" value data");
-                break;
-            }
+                    if (proplist_sethex(pl, key, key_len, value, value_len) < 0)
+                        goto fail;
 
-            blob = pa_xmalloc((size_t)(e-v)/2);
-            if (pa_parsehex(v, blob, (e-v)/2) != (size_t)((e-v)/2)) {
-                pa_log("Invalid \"hex:\" value data");
-                pa_xfree(blob);
-                break;
-            }
+                    if (*p == 0)
+                        goto success;
 
-            pa_proplist_set(p, k, blob, (e-v)/2);
-            pa_xfree(blob);
+                    state = WHITESPACE;
+                } else
+                    goto fail;
+                break;
         }
     }
 
-    pa_xfree(s);
+success:
+    return MAKE_PROPLIST(pl);
 
-    return p;
+fail:
+    pa_proplist_free(pl);
+    return NULL;
 }
 
 int pa_proplist_contains(pa_proplist *p, const char *key) {
diff --git a/src/pulse/proplist.h b/src/pulse/proplist.h
index 990ffd1..d611406 100644
--- a/src/pulse/proplist.h
+++ b/src/pulse/proplist.h
@@ -136,7 +136,7 @@ PA_C_DECL_BEGIN
 #define PA_PROP_MODULE_USAGE                   "module.usage"
 #define PA_PROP_MODULE_VERSION                 "module.version"
 
-/** A property list object. Basically a dictionary with UTF-8 strings
+/** A property list object. Basically a dictionary with ASCII strings
  * as keys and arbitrary data as values. \since 0.9.11 */
 typedef struct pa_proplist pa_proplist;
 

commit 9a27b8f0e8a6cd1863c95770777aa2536ec5fbb2
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 17:16:13 2009 +0100

    in addition to per-property env vars PULSE_PROP_xxx look for for a stringified PULSE_PROP env var

diff --git a/src/pulsecore/proplist-util.c b/src/pulsecore/proplist-util.c
index 4920c27..522c7af 100644
--- a/src/pulsecore/proplist-util.c
+++ b/src/pulsecore/proplist-util.c
@@ -41,6 +41,7 @@ void pa_init_proplist(pa_proplist *p) {
     extern char **environ;
 #endif
     char **e;
+    const char *pp;
 
     pa_assert(p);
 
@@ -75,6 +76,15 @@ void pa_init_proplist(pa_proplist *p) {
         }
     }
 
+    if ((pp = getenv("PULSE_PROP"))) {
+        pa_proplist *t;
+
+        if ((t = pa_proplist_from_string(pp))) {
+            pa_proplist_update(p, PA_UPDATE_MERGE, t);
+            pa_proplist_free(t);
+        }
+    }
+
     if (!pa_proplist_contains(p, PA_PROP_APPLICATION_PROCESS_ID)) {
         char t[32];
         pa_snprintf(t, sizeof(t), "%lu", (unsigned long) getpid());

commit a6fe99171669ae03fd5453cc8fa924f21dc9a050
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 17:16:32 2009 +0100

    beef up proplist test a bit

diff --git a/src/tests/proplist-test.c b/src/tests/proplist-test.c
index f69fa68..5526bb7 100644
--- a/src/tests/proplist-test.c
+++ b/src/tests/proplist-test.c
@@ -29,8 +29,9 @@
 #include <pulsecore/core-util.h>
 
 int main(int argc, char*argv[]) {
-    pa_proplist *a, *b, *c;
-    char *s, *t, *u;
+    pa_proplist *a, *b, *c, *d;
+    char *s, *t, *u, *v;
+    const char *text;
 
     a = pa_proplist_new();
     pa_assert_se(pa_proplist_sets(a, PA_PROP_MEDIA_TITLE, "Brandenburgische Konzerte") == 0);
@@ -63,5 +64,19 @@ int main(int argc, char*argv[]) {
     pa_proplist_free(b);
     pa_proplist_free(c);
 
+    text = "  eins = zwei drei = \"\\\"vier\\\"\" fuenf=sechs sieben ='\\a\\c\\h\\t\\'\\\"' neun= hex:0123456789abCDef ";
+
+    printf("%s\n", text);
+    d = pa_proplist_from_string(text);
+    v = pa_proplist_to_string(d);
+    pa_proplist_free(d);
+    printf("%s\n", v);
+    d = pa_proplist_from_string(v);
+    pa_xfree(v);
+    v = pa_proplist_to_string(d);
+    pa_proplist_free(d);
+    printf("%s\n", v);
+    pa_xfree(v);
+
     return 0;
 }

commit d6dd907cc87e3c6c86ec4d05a2f533bb8fcf677b
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 17:16:53 2009 +0100

    simplify code a bit by using pa_sample_size_of_format()

diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c
index be390db..78ad553 100644
--- a/src/pulsecore/resampler.c
+++ b/src/pulsecore/resampler.c
@@ -156,16 +156,6 @@ static int (* const init_table[])(pa_resampler*r) = {
     [PA_RESAMPLER_PEAKS]                   = peaks_init,
 };
 
-static inline size_t sample_size(pa_sample_format_t f) {
-    pa_sample_spec ss = {
-        .format = f,
-        .rate = 0,
-        .channels = 1
-    };
-
-    return pa_sample_size(&ss);
-}
-
 pa_resampler* pa_resampler_new(
         pa_mempool *pool,
         const pa_sample_spec *a,
@@ -275,7 +265,7 @@ pa_resampler* pa_resampler_new(
 
     pa_log_info("Using %s as working format.", pa_sample_format_to_string(r->work_format));
 
-    r->w_sz = sample_size(r->work_format);
+    r->w_sz = pa_sample_size_of_format(r->work_format);
 
     if (r->i_ss.format == r->work_format)
         r->to_work_format_func = NULL;

commit 078a8d583f205f57b99b32fe12d33e04742c07f6
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 17:17:32 2009 +0100

    rearrange a few things

diff --git a/src/pulsecore/modargs.c b/src/pulsecore/modargs.c
index 9e60125..866e6e0 100644
--- a/src/pulsecore/modargs.c
+++ b/src/pulsecore/modargs.c
@@ -79,106 +79,111 @@ static int add_key_value(pa_hashmap *map, char *key, char *value, const char* co
 }
 
 pa_modargs *pa_modargs_new(const char *args, const char* const* valid_keys) {
-    pa_hashmap *map = NULL;
+    enum {
+        WHITESPACE,
+        KEY,
+        VALUE_START,
+        VALUE_SIMPLE,
+        VALUE_DOUBLE_QUOTES,
+        VALUE_TICKS
+    } state;
+
+    const char *p, *key = NULL, *value = NULL;
+    size_t key_len = 0, value_len = 0;
+    pa_hashmap *map;
 
     map = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
 
-    if (args) {
-        enum {
-            WHITESPACE,
-            KEY,
-            VALUE_START,
-            VALUE_SIMPLE,
-            VALUE_DOUBLE_QUOTES,
-            VALUE_TICKS
-        } state;
-
-        const char *p, *key, *value;
-        size_t key_len = 0, value_len = 0;
-
-        key = value = NULL;
-        state = WHITESPACE;
-        for (p = args; *p; p++) {
-            switch (state) {
-                case WHITESPACE:
-                    if (*p == '=')
+    if (!args)
+        return (pa_modargs*) map;
+
+    state = WHITESPACE;
+
+    for (p = args; *p; p++) {
+        switch (state) {
+
+            case WHITESPACE:
+                if (*p == '=')
+                    goto fail;
+                else if (!isspace(*p)) {
+                    key = p;
+                    state = KEY;
+                    key_len = 1;
+                }
+                break;
+
+            case KEY:
+                if (*p == '=')
+                    state = VALUE_START;
+                else if (isspace(*p))
+                    goto fail;
+                else
+                    key_len++;
+                break;
+
+            case  VALUE_START:
+                if (*p == '\'') {
+                    state = VALUE_TICKS;
+                    value = p+1;
+                    value_len = 0;
+                } else if (*p == '"') {
+                    state = VALUE_DOUBLE_QUOTES;
+                    value = p+1;
+                    value_len = 0;
+                } else if (isspace(*p)) {
+                    if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(""), valid_keys) < 0)
                         goto fail;
-                    else if (!isspace(*p)) {
-                        key = p;
-                        state = KEY;
-                        key_len = 1;
-                    }
-                    break;
-                case KEY:
-                    if (*p == '=')
-                        state = VALUE_START;
-                    else if (isspace(*p))
+                    state = WHITESPACE;
+                } else {
+                    state = VALUE_SIMPLE;
+                    value = p;
+                    value_len = 1;
+                }
+                break;
+
+            case VALUE_SIMPLE:
+                if (isspace(*p)) {
+                    if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0)
                         goto fail;
-                    else
-                        key_len++;
-                    break;
-                case  VALUE_START:
-                    if (*p == '\'') {
-                        state = VALUE_TICKS;
-                        value = p+1;
-                        value_len = 0;
-                    } else if (*p == '"') {
-                        state = VALUE_DOUBLE_QUOTES;
-                        value = p+1;
-                        value_len = 0;
-                    } else if (isspace(*p)) {
-                        if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(""), valid_keys) < 0)
-                            goto fail;
-                        state = WHITESPACE;
-                    } else {
-                        state = VALUE_SIMPLE;
-                        value = p;
-                        value_len = 1;
-                    }
-                    break;
-                case VALUE_SIMPLE:
-                    if (isspace(*p)) {
-                        if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0)
-                            goto fail;
-                        state = WHITESPACE;
-                    } else
-                        value_len++;
-                    break;
-                case VALUE_DOUBLE_QUOTES:
-                    if (*p == '"') {
-                        if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0)
-                            goto fail;
-                        state = WHITESPACE;
-                    } else
-                        value_len++;
-                    break;
-                case VALUE_TICKS:
-                    if (*p == '\'') {
-                        if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0)
-                            goto fail;
-                        state = WHITESPACE;
-                    } else
-                        value_len++;
-                    break;
-            }
+                    state = WHITESPACE;
+                } else
+                    value_len++;
+                break;
+
+            case VALUE_DOUBLE_QUOTES:
+                if (*p == '"') {
+                    if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0)
+                        goto fail;
+                    state = WHITESPACE;
+                } else
+                    value_len++;
+                break;
+
+            case VALUE_TICKS:
+                if (*p == '\'') {
+                    if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0)
+                        goto fail;
+                    state = WHITESPACE;
+                } else
+                    value_len++;
+                break;
         }
+    }
 
-        if (state == VALUE_START) {
-            if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(""), valid_keys) < 0)
-                goto fail;
-        } else if (state == VALUE_SIMPLE) {
-            if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(value), valid_keys) < 0)
-                goto fail;
-        } else if (state != WHITESPACE)
+    if (state == VALUE_START) {
+        if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(""), valid_keys) < 0)
             goto fail;
-    }
+    } else if (state == VALUE_SIMPLE) {
+        if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(value), valid_keys) < 0)
+            goto fail;
+    } else if (state != WHITESPACE)
+        goto fail;
 
     return (pa_modargs*) map;
 
 fail:
 
-    if (map)
-        pa_modargs_free((pa_modargs*) map);
+    pa_modargs_free((pa_modargs*) map);
 
     return NULL;
 }

commit a625ca7c74d8a21b36527c06524ac281e67308f3
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 17:17:48 2009 +0100

    make gcc shut up

diff --git a/src/pulsecore/envelope.c b/src/pulsecore/envelope.c
index b57b643..fd6a948 100644
--- a/src/pulsecore/envelope.c
+++ b/src/pulsecore/envelope.c
@@ -744,6 +744,13 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) {
                 break;
             }
 
+            case PA_SAMPLE_S24LE:
+            case PA_SAMPLE_S24BE:
+            case PA_SAMPLE_S24_32LE:
+            case PA_SAMPLE_S24_32BE:
+                /* FIXME */
+                pa_assert_not_reached();
+
             case PA_SAMPLE_MAX:
             case PA_SAMPLE_INVALID:
                 pa_assert_not_reached();

commit 83ddc0936e52120f2af86a552f3adb240a4f0ac4
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 17:19:15 2009 +0100

    add new calls pa_replace() and pa_unescape()

diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index e65b179..b7ebdeb 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -97,6 +97,7 @@
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/thread.h>
+#include <pulsecore/strbuf.h>
 
 #include "core-util.h"
 
@@ -2553,3 +2554,49 @@ unsigned pa_ncpus(void) {
 
     return ncpus <= 0 ? 1 : (unsigned) ncpus;
 }
+
+char *pa_replace(const char*s, const char*a, const char *b) {
+    pa_strbuf *sb;
+    size_t an;
+
+    pa_assert(s);
+    pa_assert(a);
+    pa_assert(b);
+
+    an = strlen(a);
+    sb = pa_strbuf_new();
+
+    for (;;) {
+        const char *p;
+
+        if (!(p = strstr(s, a)))
+            break;
+
+        pa_strbuf_putsn(sb, s, p-s);
+        pa_strbuf_puts(sb, b);
+        s = p + an;
+    }
+
+    pa_strbuf_puts(sb, s);
+
+    return pa_strbuf_tostring_free(sb);
+}
+
+char *pa_unescape(char *p) {
+    char *s, *d;
+    pa_bool_t escaped = FALSE;
+
+    for (s = p, d = p; *s; s++) {
+        if (!escaped && *s == '\\') {
+            escaped = TRUE;
+            continue;
+        }
+
+        *(d++) = *s;
+        escaped = FALSE;
+    }
+
+    *d = 0;
+
+    return p;
+}
diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h
index 18901f4..442815f 100644
--- a/src/pulsecore/core-util.h
+++ b/src/pulsecore/core-util.h
@@ -215,4 +215,8 @@ void pa_reduce(unsigned *num, unsigned *den);
 
 unsigned pa_ncpus(void);
 
+char *pa_replace(const char*s, const char*a, const char *b);
+
+char *pa_unescape(char *p);
+
 #endif

commit 12b735962a3794f1e64c7bf54d67dc7d8c4b8643
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 17:20:36 2009 +0100

    add a few additional validity checks

diff --git a/src/pulse/ext-stream-restore.c b/src/pulse/ext-stream-restore.c
index 703179c..469c822 100644
--- a/src/pulse/ext-stream-restore.c
+++ b/src/pulse/ext-stream-restore.c
@@ -30,6 +30,7 @@
 #include <pulsecore/pstream-util.h>
 
 #include "internal.h"
+#include "operation.h"
 
 #include "ext-stream-restore.h"
 
@@ -191,8 +192,8 @@ pa_operation *pa_ext_stream_restore_write(
         void *userdata) {
 
     uint32_t tag;
-    pa_operation *o;
-    pa_tagstruct *t;
+    pa_operation *o = NULL;
+    pa_tagstruct *t = NULL;
 
     pa_assert(c);
     pa_assert(PA_REFCNT_VALUE(c) >= 1);
@@ -213,7 +214,15 @@ pa_operation *pa_ext_stream_restore_write(
     pa_tagstruct_put_boolean(t, apply_immediately);
 
     for (; n > 0; n--, data++) {
+        if (!data->name || !*data->name)
+            goto fail;
+
         pa_tagstruct_puts(t, data->name);
+
+        if (data->volume.channels > 0 &&
+            !pa_cvolume_compatible_with_channel_map(&data->volume, &data->channel_map))
+            goto fail;
+
         pa_tagstruct_put_channel_map(t, &data->channel_map);
         pa_tagstruct_put_cvolume(t, &data->volume);
         pa_tagstruct_puts(t, data->device);
@@ -224,6 +233,18 @@ pa_operation *pa_ext_stream_restore_write(
     pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
 
     return o;
+
+fail:
+    if (o) {
+        pa_operation_cancel(o);
+        pa_operation_unref(o);
+    }
+
+    if (t)
+        pa_tagstruct_free(t);
+
+    pa_context_set_error(c, PA_ERR_INVALID);
+    return NULL;
 }
 
 pa_operation *pa_ext_stream_restore_delete(
@@ -233,8 +254,8 @@ pa_operation *pa_ext_stream_restore_delete(
         void *userdata) {
 
     uint32_t tag;
-    pa_operation *o;
-    pa_tagstruct *t;
+    pa_operation *o = NULL;
+    pa_tagstruct *t = NULL;
     const char *const *k;
 
     pa_assert(c);
@@ -251,13 +272,29 @@ pa_operation *pa_ext_stream_restore_delete(
     pa_tagstruct_puts(t, "module-stream-restore");
     pa_tagstruct_putu32(t, SUBCOMMAND_DELETE);
 
-    for (k = s; *k; k++)
+    for (k = s; *k; k++) {
+        if (!*k || !**k)
+            goto fail;
+
         pa_tagstruct_puts(t, *k);
+    }
 
     pa_pstream_send_tagstruct(c->pstream, t);
     pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
 
     return o;
+
+fail:
+    if (o) {
+        pa_operation_cancel(o);
+        pa_operation_unref(o);
+    }
+
+    if (t)
+        pa_tagstruct_free(t);
+
+    pa_context_set_error(c, PA_ERR_INVALID);
+    return NULL;
 }
 
 pa_operation *pa_ext_stream_restore_subscribe(
@@ -322,5 +359,4 @@ void pa_ext_stream_restore_command(pa_context *c, uint32_t tag, pa_tagstruct *t)
 
     if (c->ext_stream_restore.callback)
         c->ext_stream_restore.callback(c, c->ext_stream_restore.userdata);
-
 }
diff --git a/src/pulse/operation.c b/src/pulse/operation.c
index 13b470a..aa2bbc0 100644
--- a/src/pulse/operation.c
+++ b/src/pulse/operation.c
@@ -62,6 +62,7 @@ pa_operation *pa_operation_ref(pa_operation *o) {
     PA_REFCNT_INC(o);
     return o;
 }
+
 void pa_operation_unref(pa_operation *o) {
     pa_assert(o);
     pa_assert(PA_REFCNT_VALUE(o) >= 1);

commit f6ec971e887e68ba74fb7132dcedddc9b6f2b2db
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 17:20:58 2009 +0100

    clarify things a bit

diff --git a/src/pulse/ext-stream-restore.h b/src/pulse/ext-stream-restore.h
index ac01d23..cf9f4cc 100644
--- a/src/pulse/ext-stream-restore.h
+++ b/src/pulse/ext-stream-restore.h
@@ -36,10 +36,10 @@ PA_C_DECL_BEGIN
  * maintained by module-stream-restore. \since 0.9.12 */
 typedef struct pa_ext_stream_restore_info {
     const char *name;            /**< Identifier string of the stream. A string like "sink-input-by-role:" or similar followed by some arbitrary property value. */
-    pa_channel_map channel_map;  /**< The channel map for the volume field */
-    pa_cvolume volume;           /**< The volume of the stream when it was seen last, if applicable */
-    const char *device;          /**< The sink/source of the stream when it was last seen */
-    int mute;                    /**< The boolean mute state of the stream when it was last seen, if applicable */
+    pa_channel_map channel_map;  /**< The channel map for the volume field, if applicable */
+    pa_cvolume volume;           /**< The volume of the stream when it was seen last, if applicable and saved */
+    const char *device;          /**< The sink/source of the stream when it was last seen, if applicable and saved */
+    int mute;                    /**< The boolean mute state of the stream when it was last seen, if applicable and saved */
 } pa_ext_stream_restore_info;
 
 /** Callback prototype for pa_ext_stream_restore_test(). \since 0.9.12 */

commit 4cf82c74a1401dc5fa678b1367daa71242536d4b
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 18:28:52 2009 +0100

    merge in properties earlier to make identification of streams from hooks easier

diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index fc87d5d..71642bb 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -136,6 +136,9 @@ int pa_sink_input_new(
     pa_assert(core);
     pa_assert(data);
 
+    if (data->client)
+        pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->client->proplist);
+
     if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], data)) < 0)
         return r;
 
@@ -224,9 +227,6 @@ int pa_sink_input_new(
 
     pa_return_val_if_fail(data->resample_method < PA_RESAMPLER_MAX, -PA_ERR_INVALID);
 
-    if (data->client)
-        pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->client->proplist);
-
     if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], data)) < 0)
         return r;
 
diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c
index c5cb16d..63d56d5 100644
--- a/src/pulsecore/source-output.c
+++ b/src/pulsecore/source-output.c
@@ -110,6 +110,9 @@ int pa_source_output_new(
     pa_assert(core);
     pa_assert(data);
 
+    if (data->client)
+        pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->client->proplist);
+
     if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_NEW], data)) < 0)
         return r;
 
@@ -159,9 +162,6 @@ int pa_source_output_new(
 
     pa_return_val_if_fail(data->resample_method < PA_RESAMPLER_MAX, -PA_ERR_INVALID);
 
-    if (data->client)
-        pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->client->proplist);
-
     if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_FIXATE], data)) < 0)
         return r;
 

commit 1db64781bf514e6bb04685d428ecb6347af23ce9
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 18:31:24 2009 +0100

    version all entries in the database

diff --git a/src/modules/module-card-restore.c b/src/modules/module-card-restore.c
index 02e973c..4dffd36 100644
--- a/src/modules/module-card-restore.c
+++ b/src/modules/module-card-restore.c
@@ -68,7 +68,10 @@ struct userdata {
     GDBM_FILE gdbm_file;
 };
 
-struct entry {
+#define ENTRY_VERSION 1
+
+struct entry PA_GCC_PACKED {
+    uint8_t version;
     char profile[PA_NAME_MAX];
 };
 
@@ -104,12 +107,17 @@ static struct entry* read_entry(struct userdata *u, const char *name) {
         goto fail;
 
     if (data.dsize != sizeof(struct entry)) {
-        pa_log_warn("Database contains entry for card %s of wrong size %lu != %lu", name, (unsigned long) data.dsize, (unsigned long) sizeof(struct entry));
+        pa_log_debug("Database contains entry for card %s of wrong size %lu != %lu. Probably due to upgrade, ignoring.", name, (unsigned long) data.dsize, (unsigned long) sizeof(struct entry));
         goto fail;
     }
 
     e = (struct entry*) data.dptr;
 
+    if (e->version != ENTRY_VERSION) {
+        pa_log_debug("Version of database entry for card %s doesn't match our version. Probably due to upgrade, ignoring.", name);
+        goto fail;
+    }
+
     if (!memchr(e->profile, 0, sizeof(e->profile))) {
         pa_log_warn("Database contains entry for card %s with missing NUL byte in profile name", name);
         goto fail;
@@ -148,6 +156,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
         return;
 
     memset(&entry, 0, sizeof(entry));
+    entry.version = ENTRY_VERSION;
 
     if (!(card = pa_idxset_get_by_index(c->cards, idx)))
         return;
diff --git a/src/modules/module-device-restore.c b/src/modules/module-device-restore.c
index 8e0cf92..7c56c24 100644
--- a/src/modules/module-device-restore.c
+++ b/src/modules/module-device-restore.c
@@ -79,10 +79,13 @@ struct userdata {
     pa_bool_t restore_muted:1;
 };
 
-struct entry {
+#define ENTRY_VERSION 1
+
+struct entry PA_GCC_PACKED {
+    uint8_t version;
+    pa_bool_t muted:1;
     pa_channel_map channel_map;
     pa_cvolume volume;
-    pa_bool_t muted:1;
 };
 
 static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *tv, void *userdata) {
@@ -117,12 +120,17 @@ static struct entry* read_entry(struct userdata *u, const char *name) {
         goto fail;
 
     if (data.dsize != sizeof(struct entry)) {
-        pa_log_warn("Database contains entry for device %s of wrong size %lu != %lu", name, (unsigned long) data.dsize, (unsigned long) sizeof(struct entry));
+        pa_log_debug("Database contains entry for device %s of wrong size %lu != %lu. Probably due to upgrade, ignoring.", name, (unsigned long) data.dsize, (unsigned long) sizeof(struct entry));
         goto fail;
     }
 
     e = (struct entry*) data.dptr;
 
+    if (e->version != ENTRY_VERSION) {
+        pa_log_debug("Version of database entry for device %s doesn't match our version. Probably due to upgrade, ignoring.", name);
+        goto fail;
+    }
+
     if (!(pa_cvolume_valid(&e->volume))) {
         pa_log_warn("Invalid volume stored in database for device %s", name);
         goto fail;
@@ -173,6 +181,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
         return;
 
     memset(&entry, 0, sizeof(entry));
+    entry.version = ENTRY_VERSION;
 
     if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK) {
         pa_sink *sink;
diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c
index 0c9bd4f..1444192 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -90,16 +90,18 @@ struct userdata {
     pa_idxset *subscribed;
 };
 
-struct entry {
+#define ENTRY_VERSION 1
+
+struct entry PA_GCC_PACKED {
+    uint8_t version;
+    pa_bool_t muted_valid:1, relative_volume_valid:1, absolute_volume_valid:1, device_valid:1;
+    pa_bool_t muted:1;
     pa_channel_map channel_map;
-    char device[PA_NAME_MAX];
     pa_cvolume relative_volume;
     pa_cvolume absolute_volume;
-    pa_bool_t muted:1;
-    pa_bool_t device_valid:1, relative_volume_valid:1, absolute_volume_valid:1, muted_valid:1;
+    char device[PA_NAME_MAX];
 };
 
-
 enum {
     SUBCOMMAND_TEST,
     SUBCOMMAND_READ,
@@ -161,19 +163,19 @@ static struct entry* read_entry(struct userdata *u, const char *name) {
     if (data.dsize != sizeof(struct entry)) {
         /* This is probably just a database upgrade, hence let's not
          * consider this more than a debug message */
-        pa_log_debug("Database contains entry for stream %s of wrong size %lu != %lu", name, (unsigned long) data.dsize, (unsigned long) sizeof(struct entry));
+        pa_log_debug("Database contains entry for stream %s of wrong size %lu != %lu. Probably due to uprade, ignoring.", name, (unsigned long) data.dsize, (unsigned long) sizeof(struct entry));
         goto fail;
     }
 
     e = (struct entry*) data.dptr;
 
-    if (!memchr(e->device, 0, sizeof(e->device))) {
-        pa_log_warn("Database contains entry for stream %s with missing NUL byte in device name", name);
+    if (e->version != ENTRY_VERSION) {
+        pa_log_debug("Version of database entry for stream %s doesn't match our version. Probably due to upgrade, ignoring.", name);
         goto fail;
     }
 
-    if (!(pa_channel_map_valid(&e->channel_map))) {
-        pa_log_warn("Invalid channel map stored in database for stream %s", name);
+    if (!memchr(e->device, 0, sizeof(e->device))) {
+        pa_log_warn("Database contains entry for stream %s with missing NUL byte in device name", name);
         goto fail;
     }
 
@@ -182,6 +184,11 @@ static struct entry* read_entry(struct userdata *u, const char *name) {
         goto fail;
     }
 
+    if ((e->relative_volume_valid || e->absolute_volume_valid) && !(pa_channel_map_valid(&e->channel_map))) {
+        pa_log_warn("Invalid channel map stored in database for stream %s", name);
+        goto fail;
+    }
+
     if ((e->relative_volume_valid && (!pa_cvolume_valid(&e->relative_volume) || e->relative_volume.channels != e->channel_map.channels)) ||
         (e->absolute_volume_valid && (!pa_cvolume_valid(&e->absolute_volume) || e->absolute_volume.channels != e->channel_map.channels))) {
         pa_log_warn("Invalid volume stored in database for stream %s", name);
@@ -265,6 +272,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
         return;
 
     memset(&entry, 0, sizeof(entry));
+    entry.version = ENTRY_VERSION;
 
     if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK_INPUT) {
         pa_sink_input *sink_input;
@@ -697,6 +705,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
                 int k;
 
                 memset(&entry, 0, sizeof(entry));
+                entry.version = ENTRY_VERSION;
 
                 if (pa_tagstruct_gets(t, &name) < 0 ||
                     pa_tagstruct_get_channel_map(t, &entry.channel_map) ||

commit 786398dc6312263ec4a14abd474fd0fd3def1ea4
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 18:32:15 2009 +0100

    fix a validity check

diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c
index 1444192..65cdcbe 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -240,7 +240,7 @@ static pa_bool_t entries_equal(const struct entry *a, const struct entry *b) {
         return FALSE;
 
     if (a->muted_valid != b->muted_valid ||
-        (a->muted && (a->muted != b->muted)))
+        (a->muted_valid && (a->muted != b->muted)))
         return FALSE;
 
     t = b->relative_volume;

commit b2c923e727f302a9e9c3a33f74a707cb47944a77
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 18:33:01 2009 +0100

    properly handle failing stream creation

diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 21a2cfb..0931854 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -595,7 +595,7 @@ static record_stream* record_stream_new(
         int *ret) {
 
     record_stream *s;
-    pa_source_output *source_output;
+    pa_source_output *source_output = NULL;
     size_t base;
     pa_source_output_new_data data;
 
@@ -618,7 +618,7 @@ static record_stream* record_stream_new(
     if (peak_detect)
         data.resample_method = PA_RESAMPLER_PEAKS;
 
-    *ret = pa_source_output_new(&source_output, c->protocol->core, &data, flags);
+    *ret = -pa_source_output_new(&source_output, c->protocol->core, &data, flags);
 
     pa_source_output_new_data_done(&data);
 
@@ -971,7 +971,7 @@ static playback_stream* playback_stream_new(
         int *ret) {
 
     playback_stream *s, *ssync;
-    pa_sink_input *sink_input;
+    pa_sink_input *sink_input = NULL;
     pa_memchunk silence;
     uint32_t idx;
     int64_t start_index;
@@ -1023,7 +1023,7 @@ static playback_stream* playback_stream_new(
         pa_sink_input_new_data_set_muted(&data, muted);
     data.sync_base = ssync ? ssync->sink_input : NULL;
 
-    *ret = pa_sink_input_new(&sink_input, c->protocol->core, &data, flags);
+    *ret = -pa_sink_input_new(&sink_input, c->protocol->core, &data, flags);
 
     pa_sink_input_new_data_done(&data);
 

commit d802a76963e32bd821edfa89d6fe39764f1942f6
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 18:34:08 2009 +0100

    remove soft volume from pa_sink_input_new_info since it should be handled internally and automatically by the sink input

diff --git a/src/modules/module-position-event-sounds.c b/src/modules/module-position-event-sounds.c
index 8e4f4c3..e17cbe8 100644
--- a/src/modules/module-position-event-sounds.c
+++ b/src/modules/module-position-event-sounds.c
@@ -80,16 +80,16 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *core, pa_sink_i
 
     pa_log_debug("Positioning event sound '%s' at %0.2f.", pa_strnull(pa_proplist_gets(data->proplist, PA_PROP_EVENT_ID)), f);
 
-    if (!data->virtual_volume_is_set) {
-        pa_cvolume_reset(&data->virtual_volume, data->sample_spec.channels);
-        data->virtual_volume_is_set = TRUE;
-        data->virtual_volume_is_absolute = FALSE;
+    if (!data->volume_is_set) {
+        pa_cvolume_reset(&data->volume, data->sample_spec.channels);
+        data->volume_is_set = TRUE;
+        data->volume_is_absolute = FALSE;
     }
 
-    pa_cvolume_set_balance(&data->virtual_volume, &data->channel_map, f*2.0-1.0);
+    pa_cvolume_set_balance(&data->volume, &data->channel_map, f*2.0-1.0);
     data->save_volume = FALSE;
 
-    pa_log_debug("Final volume %s.", pa_cvolume_snprint(t, sizeof(t), &data->virtual_volume));
+    pa_log_debug("Final volume %s.", pa_cvolume_snprint(t, sizeof(t), &data->volume));
 
     return PA_HOOK_OK;
 }
diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c
index 65cdcbe..b1630fe 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -396,32 +396,33 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_inpu
 
         if (u->restore_volume) {
 
-            if (!new_data->virtual_volume_is_set) {
+            if (!new_data->volume_is_set) {
                 pa_cvolume v;
                 pa_cvolume_init(&v);
 
                 if (new_data->sink->flags & PA_SINK_FLAT_VOLUME) {
 
+                    /* We don't check for e->device_valid here because
+                    that bit marks whether it is a good choice for
+                    restoring, not just if the data is filled in. */
                     if (e->absolute_volume_valid &&
-                        e->device_valid &&
-                        pa_streq(new_data->sink->name, e->device)) {
+                        (e->device[0] == 0 || pa_streq(new_data->sink->name, e->device))) {
 
                         v = e->absolute_volume;
-                        new_data->virtual_volume_is_absolute = TRUE;
+                        new_data->volume_is_absolute = TRUE;
                     } else if (e->relative_volume_valid) {
-
                         v = e->relative_volume;
-                        new_data->virtual_volume_is_absolute = FALSE;
+                        new_data->volume_is_absolute = FALSE;
                     }
 
                 } else if (e->relative_volume_valid) {
                     v = e->relative_volume;
-                    new_data->virtual_volume_is_absolute = FALSE;
+                    new_data->volume_is_absolute = FALSE;
                 }
 
                 if (v.channels > 0) {
                     pa_log_info("Restoring volume for sink input %s.", name);
-                    pa_sink_input_new_data_set_virtual_volume(new_data, pa_cvolume_remap(&v, &e->channel_map, &new_data->channel_map));
+                    pa_sink_input_new_data_set_volume(new_data, pa_cvolume_remap(&v, &e->channel_map, &new_data->channel_map));
                     new_data->save_volume = TRUE;
                 }
             } else
@@ -531,11 +532,10 @@ static void apply_entry(struct userdata *u, const char *name, struct entry *e) {
             if (si->sink->flags & PA_SINK_FLAT_VOLUME) {
 
                 if (e->absolute_volume_valid &&
-                    e->device_valid &&
-                    pa_streq(e->device, si->sink->name))
+                    (e->device[0] == 0 || pa_streq(e->device, si->sink->name)))
                     v = e->absolute_volume;
                 else if (e->relative_volume_valid) {
-                    pa_cvolume t = si->sink->virtual_volume;
+                    pa_cvolume t = *pa_sink_get_volume(si->sink, FALSE);
                     pa_sw_cvolume_multiply(&v, &e->relative_volume, pa_cvolume_remap(&t, &si->sink->channel_map, &e->channel_map));
                 }
             } else if (e->relative_volume_valid)
@@ -663,10 +663,11 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
 
                 if ((e = read_entry(u, name))) {
                     pa_cvolume r;
+                    pa_channel_map cm;
 
                     pa_tagstruct_puts(reply, name);
-                    pa_tagstruct_put_channel_map(reply, &e->channel_map);
-                    pa_tagstruct_put_cvolume(reply, e->relative_volume_valid ? &e->relative_volume : pa_cvolume_init(&r));
+                    pa_tagstruct_put_channel_map(reply, (e->relative_volume_valid || e->absolute_volume_valid) ? &e->channel_map : pa_channel_map_init(&cm));
+                    pa_tagstruct_put_cvolume(reply, e->absolute_volume_valid ? &e->absolute_volume : (e->relative_volume_valid ? &e->relative_volume : pa_cvolume_init(&r)));
                     pa_tagstruct_puts(reply, e->device_valid ? e->device : NULL);
                     pa_tagstruct_put_boolean(reply, e->muted_valid ? e->muted : FALSE);
 
@@ -709,18 +710,21 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
 
                 if (pa_tagstruct_gets(t, &name) < 0 ||
                     pa_tagstruct_get_channel_map(t, &entry.channel_map) ||
-                    pa_tagstruct_get_cvolume(t, &entry.relative_volume) < 0 ||
+                    pa_tagstruct_get_cvolume(t, &entry.absolute_volume) < 0 ||
                     pa_tagstruct_gets(t, &device) < 0 ||
                     pa_tagstruct_get_boolean(t, &muted) < 0)
                     goto fail;
 
-                entry.absolute_volume_valid = FALSE;
-                entry.relative_volume_valid = entry.relative_volume.channels > 0;
-
-                if (entry.relative_volume_valid &&
-                    entry.channel_map.channels != entry.relative_volume.channels)
+                if (!name || !*name)
                     goto fail;
 
+                entry.relative_volume = entry.absolute_volume;
+                entry.absolute_volume_valid = entry.relative_volume_valid = entry.relative_volume.channels > 0;
+
+                if (entry.relative_volume_valid)
+                    if (!pa_cvolume_compatible_with_channel_map(&entry.relative_volume, &entry.channel_map))
+                        goto fail;
+
                 entry.muted = muted;
                 entry.muted_valid = TRUE;
 
diff --git a/src/pulsecore/play-memblockq.c b/src/pulsecore/play-memblockq.c
index d163126..44aa6bf 100644
--- a/src/pulsecore/play-memblockq.c
+++ b/src/pulsecore/play-memblockq.c
@@ -197,7 +197,7 @@ pa_sink_input* pa_memblockq_sink_input_new(
     data.driver = __FILE__;
     pa_sink_input_new_data_set_sample_spec(&data, ss);
     pa_sink_input_new_data_set_channel_map(&data, map);
-    pa_sink_input_new_data_set_virtual_volume(&data, volume);
+    pa_sink_input_new_data_set_volume(&data, volume);
     pa_proplist_update(data.proplist, PA_UPDATE_REPLACE, p);
 
     pa_sink_input_new(&u->sink_input, sink->core, &data, 0);
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 0931854..39c834d 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -1018,7 +1018,7 @@ static playback_stream* playback_stream_new(
     pa_sink_input_new_data_set_sample_spec(&data, ss);
     pa_sink_input_new_data_set_channel_map(&data, map);
     if (volume)
-        pa_sink_input_new_data_set_virtual_volume(&data, volume);
+        pa_sink_input_new_data_set_volume(&data, volume);
     if (muted_set)
         pa_sink_input_new_data_set_muted(&data, muted);
     data.sync_base = ssync ? ssync->sink_input : NULL;
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 71642bb..df42cae 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -72,18 +72,11 @@ void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data *data, const
         data->channel_map = *map;
 }
 
-void pa_sink_input_new_data_set_soft_volume(pa_sink_input_new_data *data, const pa_cvolume *volume) {
+void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume) {
     pa_assert(data);
 
-    if ((data->soft_volume_is_set = !!volume))
-        data->soft_volume = *volume;
-}
-
-void pa_sink_input_new_data_set_virtual_volume(pa_sink_input_new_data *data, const pa_cvolume *volume) {
-    pa_assert(data);
-
-    if ((data->virtual_volume_is_set = !!volume))
-        data->virtual_volume = *volume;
+    if ((data->volume_is_set = !!volume))
+        data->volume = *volume;
 }
 
 void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mute) {
@@ -169,35 +162,20 @@ int pa_sink_input_new(
     pa_return_val_if_fail(pa_channel_map_valid(&data->channel_map), -PA_ERR_INVALID);
     pa_return_val_if_fail(pa_channel_map_compatible(&data->channel_map, &data->sample_spec), -PA_ERR_INVALID);
 
-    if (!data->virtual_volume_is_set) {
+    if (!data->volume_is_set) {
 
         if (data->sink->flags & PA_SINK_FLAT_VOLUME) {
-            data->virtual_volume = data->sink->virtual_volume;
-            pa_cvolume_remap(&data->virtual_volume, &data->sink->channel_map, &data->channel_map);
+            data->volume = *pa_sink_get_volume(data->sink, FALSE);
+            pa_cvolume_remap(&data->volume, &data->sink->channel_map, &data->channel_map);
         } else
-            pa_cvolume_reset(&data->virtual_volume, data->sample_spec.channels);
+            pa_cvolume_reset(&data->volume, data->sample_spec.channels);
 
         data->save_volume = FALSE;
 
-    } else if (!data->virtual_volume_is_absolute) {
-
-        /* When the 'absolute' bool is set then we'll treat the volume
-         * as relative to the sink volume even in flat volume mode */
-        if (data->sink->flags & PA_SINK_FLAT_VOLUME) {
-            pa_cvolume t = data->sink->virtual_volume;
-            pa_cvolume_remap(&t, &data->sink->channel_map, &data->channel_map);
-            pa_sw_cvolume_multiply(&data->virtual_volume, &data->virtual_volume, &t);
-        }
     }
 
-    pa_return_val_if_fail(pa_cvolume_valid(&data->virtual_volume), -PA_ERR_INVALID);
-    pa_return_val_if_fail(pa_cvolume_compatible(&data->virtual_volume, &data->sample_spec), -PA_ERR_INVALID);
-
-    if (!data->soft_volume_is_set)
-        data->soft_volume = data->virtual_volume;
-
-    pa_return_val_if_fail(pa_cvolume_valid(&data->soft_volume), -PA_ERR_INVALID);
-    pa_return_val_if_fail(pa_cvolume_compatible(&data->soft_volume, &data->sample_spec), -PA_ERR_INVALID);
+    pa_return_val_if_fail(pa_cvolume_valid(&data->volume), -PA_ERR_INVALID);
+    pa_return_val_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec), -PA_ERR_INVALID);
 
     if (!data->muted_is_set)
         data->muted = FALSE;
@@ -219,8 +197,7 @@ int pa_sink_input_new(
     pa_assert(pa_channel_map_valid(&data->channel_map));
 
     /* Due to the fixing of the sample spec the volume might not match anymore */
-    pa_cvolume_remap(&data->soft_volume, &original_cm, &data->channel_map);
-    pa_cvolume_remap(&data->virtual_volume, &original_cm, &data->channel_map);
+    pa_cvolume_remap(&data->volume, &original_cm, &data->channel_map);
 
     if (data->resample_method == PA_RESAMPLER_INVALID)
         data->resample_method = core->resample_method;
@@ -271,8 +248,18 @@ int pa_sink_input_new(
     i->sample_spec = data->sample_spec;
     i->channel_map = data->channel_map;
 
-    i->virtual_volume = data->virtual_volume;
-    i->soft_volume = data->soft_volume;
+    if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !data->volume_is_absolute) {
+        /* When the 'absolute' bool is not set then we'll treat the volume
+         * as relative to the sink volume even in flat volume mode */
+
+        pa_cvolume t = *pa_sink_get_volume(data->sink, FALSE);
+        pa_cvolume_remap(&t, &data->sink->channel_map, &data->channel_map);
+
+        pa_sw_cvolume_multiply(&i->virtual_volume, &data->volume, &t);
+    } else
+        i->virtual_volume = data->volume;
+
+    pa_cvolume_init(&i->soft_volume);
     i->save_volume = data->save_volume;
     i->save_sink = data->save_sink;
     i->save_muted = data->save_muted;
@@ -502,9 +489,6 @@ void pa_sink_input_put(pa_sink_input *i) {
     pa_assert(i->process_rewind);
     pa_assert(i->kill);
 
-    i->thread_info.soft_volume = i->soft_volume;
-    i->thread_info.muted = i->muted;
-
     state = i->flags & PA_SINK_INPUT_START_CORKED ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING;
 
     update_n_corked(i, state);
@@ -515,7 +499,11 @@ void pa_sink_input_put(pa_sink_input *i) {
         pa_cvolume new_volume;
         pa_sink_update_flat_volume(i->sink, &new_volume);
         pa_sink_set_volume(i->sink, &new_volume, FALSE, FALSE);
-    }
+    } else
+        i->soft_volume = i->virtual_volume;
+
+    i->thread_info.soft_volume = i->soft_volume;
+    i->thread_info.muted = i->muted;
 
     pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_ADD_INPUT, i, 0, NULL) == 0);
 
diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h
index d82a3a6..f6c5aa1 100644
--- a/src/pulsecore/sink-input.h
+++ b/src/pulsecore/sink-input.h
@@ -233,16 +233,16 @@ typedef struct pa_sink_input_new_data {
     pa_sample_spec sample_spec;
     pa_channel_map channel_map;
 
-    pa_cvolume virtual_volume, soft_volume;
+    pa_cvolume volume;
     pa_bool_t muted:1;
 
     pa_bool_t sample_spec_is_set:1;
     pa_bool_t channel_map_is_set:1;
 
-    pa_bool_t virtual_volume_is_set:1, soft_volume_is_set:1;
+    pa_bool_t volume_is_set:1;
     pa_bool_t muted_is_set:1;
 
-    pa_bool_t virtual_volume_is_absolute:1;
+    pa_bool_t volume_is_absolute:1;
 
     pa_bool_t save_sink:1, save_volume:1, save_muted:1;
 } pa_sink_input_new_data;
@@ -250,8 +250,7 @@ typedef struct pa_sink_input_new_data {
 pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data);
 void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data *data, const pa_sample_spec *spec);
 void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data *data, const pa_channel_map *map);
-void pa_sink_input_new_data_set_soft_volume(pa_sink_input_new_data *data, const pa_cvolume *volume);
-void pa_sink_input_new_data_set_virtual_volume(pa_sink_input_new_data *data, const pa_cvolume *volume);
+void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume);
 void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mute);
 void pa_sink_input_new_data_done(pa_sink_input_new_data *data);
 
diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c
index 67b072b..c3de306 100644
--- a/src/pulsecore/sound-file-stream.c
+++ b/src/pulsecore/sound-file-stream.c
@@ -322,7 +322,7 @@ int pa_play_file(
     data.sink = sink;
     data.driver = __FILE__;
     pa_sink_input_new_data_set_sample_spec(&data, &ss);
-    pa_sink_input_new_data_set_virtual_volume(&data, volume);
+    pa_sink_input_new_data_set_volume(&data, volume);
     pa_proplist_sets(data.proplist, PA_PROP_MEDIA_NAME, pa_path_get_filename(fname));
     pa_proplist_sets(data.proplist, PA_PROP_MEDIA_FILENAME, fname);
 

commit 9a93157f5dc22467be952e7ff2f10c7ef00a0c76
Merge: d802a76... 871389a...
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 18:41:44 2009 +0100

    Merge commit 'coling/master'


commit d4618c8c84187dfddbb715aa285262a5780ac3ad
Merge: 9a93157... 004b38f...
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 18:42:13 2009 +0100

    Merge commit 'vudentz/master'


commit 0933f1a2a401a418a90dc948824e184b5dcc9c93
Merge: d4618c8... e9ca8b1...
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 18:42:43 2009 +0100

    Merge commit 'flameeyes/flameeyes'


commit 3d33172791197b76fb60d643b2b11c714713eb5b
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 20:55:30 2009 +0100

    rate limit underrun messages

diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
index 22460bb..c56614c 100644
--- a/src/modules/alsa/alsa-sink.c
+++ b/src/modules/alsa/alsa-sink.c
@@ -190,7 +190,9 @@ static size_t check_left_to_play(struct userdata *u, snd_pcm_sframes_t n) {
     if (left_to_play > 0) {
 /*         pa_log_debug("%0.2f ms left to play", (double) pa_bytes_to_usec(left_to_play, &u->sink->sample_spec) / PA_USEC_PER_MSEC); */
     } else if (!u->first && !u->after_rewind) {
-        pa_log_info("Underrun!");
+
+        if (pa_log_ratelimit())
+            pa_log_info("Underrun!");
 
         if (u->use_tsched) {
             size_t old_watermark = u->tsched_watermark;
diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
index 0fd9838..2b42d3f 100644
--- a/src/modules/alsa/alsa-source.c
+++ b/src/modules/alsa/alsa-source.c
@@ -187,7 +187,8 @@ static size_t check_left_to_record(struct userdata *u, snd_pcm_sframes_t n) {
     if (left_to_record > 0) {
 /*         pa_log_debug("%0.2f ms left to record", (double) pa_bytes_to_usec(left_to_record, &u->source->sample_spec) / PA_USEC_PER_MSEC); */
     } else {
-        pa_log_info("Overrun!");
+        if (pa_log_ratelimit())
+            pa_log_info("Overrun!");
 
         if (u->use_tsched) {
             size_t old_watermark = u->tsched_watermark;

commit ae0651728614042f840dbbb4bb8cb080d5e1f3db
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 21:22:18 2009 +0100

    make pacmd work in a pipe

diff --git a/src/utils/pacmd.c b/src/utils/pacmd.c
index 2c89c8d..507e229 100644
--- a/src/utils/pacmd.c
+++ b/src/utils/pacmd.c
@@ -47,16 +47,16 @@ int main(int argc, char*argv[]) {
     int fd = -1;
     int ret = 1, i;
     struct sockaddr_un sa;
-    char ibuf[256], obuf[256];
+    char ibuf[PIPE_BUF], obuf[PIPE_BUF];
     size_t ibuf_index, ibuf_length, obuf_index, obuf_length;
-    fd_set ifds, ofds;
     char *cli;
+    pa_bool_t ibuf_eof, obuf_eof, ibuf_closed, obuf_closed;
 
     setlocale(LC_ALL, "");
     bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR);
 
     if (pa_pid_file_check_running(&pid, "pulseaudio") < 0) {
-        pa_log("No PulseAudio daemon running");
+        pa_log("No PulseAudio daemon running, or not running as session daemon.");
         goto fail;
     }
 
@@ -99,15 +99,47 @@ int main(int argc, char*argv[]) {
     }
 
     ibuf_index = ibuf_length = obuf_index = obuf_length = 0;
+    ibuf_eof = obuf_eof = ibuf_closed = obuf_closed = FALSE;
 
+    if (argc > 1) {
+        for (i = 1; i < argc; i++) {
+            size_t k;
 
-    FD_ZERO(&ifds);
-    FD_SET(0, &ifds);
-    FD_SET(fd, &ifds);
+            k = PA_MIN(sizeof(ibuf) - ibuf_length, strlen(argv[i]));
+            memcpy(ibuf + ibuf_length, argv[1], k);
+            ibuf_length += k;
 
-    FD_ZERO(&ofds);
+            if (ibuf_length < sizeof(ibuf)) {
+                ibuf[ibuf_length] = i < argc-1 ? ' ' : '\n';
+                ibuf_length++;
+            }
+        }
+
+        ibuf_eof = TRUE;
+    }
 
     for (;;) {
+        fd_set ifds, ofds;
+
+        if (ibuf_eof &&
+            obuf_eof &&
+            ibuf_length <= 0 &&
+            obuf_length <= 0)
+            break;
+
+        FD_ZERO(&ifds);
+        FD_ZERO(&ofds);
+
+        if (obuf_length > 0)
+            FD_SET(1, &ofds);
+        else if (!obuf_eof)
+            FD_SET(fd, &ifds);
+
+        if (ibuf_length > 0)
+            FD_SET(fd, &ofds);
+        else if (!ibuf_eof)
+            FD_SET(0, &ifds);
+
         if (select(FD_SETSIZE, &ifds, &ofds, NULL, NULL) < 0) {
             pa_log(_("select(): %s"), strerror(errno));
             goto fail;
@@ -118,15 +150,16 @@ int main(int argc, char*argv[]) {
             assert(!ibuf_length);
 
             if ((r = read(0, ibuf, sizeof(ibuf))) <= 0) {
-                if (r == 0)
-                    break;
-
-                pa_log(_("read(): %s"), strerror(errno));
-                goto fail;
+                if (r < 0) {
+                    pa_log(_("read(): %s"), strerror(errno));
+                    goto fail;
+                }
+
+                ibuf_eof = TRUE;
+            } else {
+                ibuf_length = (size_t) r;
+                ibuf_index = 0;
             }
-
-            ibuf_length = (size_t) r;
-            ibuf_index = 0;
         }
 
         if (FD_ISSET(fd, &ifds)) {
@@ -134,15 +167,16 @@ int main(int argc, char*argv[]) {
             assert(!obuf_length);
 
             if ((r = read(fd, obuf, sizeof(obuf))) <= 0) {
-                if (r == 0)
-                    break;
-
-                pa_log(_("read(): %s"), strerror(errno));
-                goto fail;
+                if (r < 0) {
+                    pa_log(_("read(): %s"), strerror(errno));
+                    goto fail;
+                }
+
+                obuf_eof = TRUE;
+            } else {
+                obuf_length = (size_t) r;
+                obuf_index = 0;
             }
-
-            obuf_length = (size_t) r;
-            obuf_index = 0;
         }
 
         if (FD_ISSET(1, &ofds)) {
@@ -170,28 +204,26 @@ int main(int argc, char*argv[]) {
 
             ibuf_length -= (size_t) r;
             ibuf_index += obuf_index;
-
         }
 
-        FD_ZERO(&ifds);
-        FD_ZERO(&ofds);
-
-        if (obuf_length <= 0)
-            FD_SET(fd, &ifds);
-        else
-            FD_SET(1, &ofds);
+        if (ibuf_length <= 0 && ibuf_eof && !ibuf_closed) {
+            close(0);
+            shutdown(fd, SHUT_WR);
+            ibuf_closed = TRUE;
+        }
 
-        if (ibuf_length <= 0)
-            FD_SET(0, &ifds);
-        else
-            FD_SET(fd, &ofds);
+        if (obuf_length <= 0 && obuf_eof && !obuf_closed) {
+            shutdown(fd, SHUT_RD);
+            close(1);
+            obuf_closed = TRUE;
+        }
     }
 
     ret = 0;
 
 fail:
     if (fd >= 0)
-        close(fd);
+        pa_close(fd);
 
     return ret;
 }

commit 9a4e03c58ee2feb979d624f0016dc3d7ee7f1228
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 21:44:25 2009 +0100

    bump version and soname

diff --git a/configure.ac b/configure.ac
index 779732b..4852049 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,7 +26,7 @@ m4_define(pa_major, [0])
 m4_define(pa_minor, [9])
 m4_define(pa_micro, [15])
 
-AC_INIT([pulseaudio],[pa_major.pa_minor.pa_micro],[mzchyfrnhqvb (at) 0pointer (dot) net])
+AC_INIT([pulseaudio],[pa_major.pa_minor.pa_micro-test1],[mzchyfrnhqvb (at) 0pointer (dot) net])
 AC_CONFIG_SRCDIR([src/daemon/main.c])
 AC_CONFIG_MACRO_DIR([m4])
 AC_CONFIG_HEADERS([config.h])
@@ -44,7 +44,7 @@ AC_SUBST(PA_PROTOCOL_VERSION, 15)
 
 # The stable ABI for client applications, for the version info x:y:z
 # always will hold y=z
-AC_SUBST(LIBPULSE_VERSION_INFO, [7:1:7])
+AC_SUBST(LIBPULSE_VERSION_INFO, [8:0:8])
 
 # A simplified, synchronous, ABI-stable interface for client
 # applications, for the version info x:y:z always will hold y=z

commit 9e2a2f88df45dc709ba4867b888fad948aea8e36
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 21:49:17 2009 +0100

    run make update-po

diff --git a/po/ca.po b/po/ca.po
index fa4cb22..d52b327 100644
--- a/po/ca.po
+++ b/po/ca.po
@@ -19,7 +19,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-11-08 01:48+0000\n"
+"POT-Creation-Date: 2009-02-04 21:48+0100\n"
 "PO-Revision-Date: 2009-01-31 06:12+0100\n"
 "Last-Translator: Agustí Grau <fletxa at gmail.com>\n"
 "Language-Team: Catalan <fedora at softcatala.net>\n"
@@ -27,15 +27,20 @@ msgstr ""
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: ../src/daemon/ltdl-bind-now.c:177
-#: ../src/daemon/ltdl-bind-now.c:197
-msgid "Failed to add bind-now-loader."
-msgstr "S'ha produït un error en afegir bind-now-loader."
+#: ../src/daemon/ltdl-bind-now.c:124
+#, fuzzy
+msgid "Failed to find original lt_dlopen loader."
+msgstr "No s'ha trobat el carregador dlopen original."
 
-#: ../src/daemon/ltdl-bind-now.c:184
-msgid "Failed to find original dlopen loader."
+#: ../src/daemon/ltdl-bind-now.c:129
+#, fuzzy
+msgid "Failed to allocate new dl loader."
 msgstr "No s'ha trobat el carregador dlopen original."
 
+#: ../src/daemon/ltdl-bind-now.c:142
+msgid "Failed to add bind-now-loader."
+msgstr "S'ha produït un error en afegir bind-now-loader."
+
 #: ../src/daemon/polkit.c:55
 #, c-format
 msgid "Cannot connect to system bus: %s"
@@ -79,7 +84,8 @@ msgstr "No s'ha pogut inicialitzar PolKitContext: %s"
 #: ../src/daemon/polkit.c:119
 #, c-format
 msgid "Could not determine whether caller is authorized: %s"
-msgstr "S'ha produït un error en determinar si el cridador està autoritzada: %s"
+msgstr ""
+"S'ha produït un error en determinar si el cridador està autoritzada: %s"
 
 #: ../src/daemon/polkit.c:139
 #, c-format
@@ -125,8 +131,7 @@ msgstr "El GID de l'usuari '%s' i del grup '%s' no coincideixen"
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "El directori d'inici de l'usuari '%s' no és '%s', s'ignorarà."
 
-#: ../src/daemon/main.c:201
-#: ../src/daemon/main.c:206
+#: ../src/daemon/main.c:201 ../src/daemon/main.c:206
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "S'ha produït un error durant la creació de '%s': %s"
@@ -159,258 +164,275 @@ msgstr "El mode de sistema no està disponible en aquesta plataforma."
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "S'ha produït un error en setrlimit(%s, (%u, %u)): %s"
 
-#: ../src/daemon/main.c:425
+#: ../src/daemon/main.c:429
 msgid "Failed to parse command line."
 msgstr "S'ha produït un error en interpretar la línia d'ordres."
 
-#: ../src/daemon/main.c:441
+#: ../src/daemon/main.c:451
 #, c-format
 msgid "We're in the group '%s', allowing high-priority scheduling."
-msgstr "Aquesta aplicació està en el grup '%s', s'està establint la planificació amb prioritat alta."
+msgstr ""
+"Aquesta aplicació està en el grup '%s', s'està establint la planificació amb "
+"prioritat alta."
 
-#: ../src/daemon/main.c:448
+#: ../src/daemon/main.c:458
 #, c-format
 msgid "We're in the group '%s', allowing real-time scheduling."
-msgstr "Aquesta aplicació està en el grup '%s', s'està establint la planificació amb prioritat en temps real."
+msgstr ""
+"Aquesta aplicació està en el grup '%s', s'està establint la planificació amb "
+"prioritat en temps real."
 
-#: ../src/daemon/main.c:456
+#: ../src/daemon/main.c:466
 msgid "PolicyKit grants us acquire-high-priority privilege."
 msgstr "PolicyKit ha permés el permís acquire-high-priority."
 
-#: ../src/daemon/main.c:459
+#: ../src/daemon/main.c:469
 msgid "PolicyKit refuses acquire-high-priority privilege."
 msgstr "PolicyKit ha rebutjat el permís acquire-high-priority."
 
-#: ../src/daemon/main.c:464
+#: ../src/daemon/main.c:474
 msgid "PolicyKit grants us acquire-real-time privilege."
 msgstr "PolicyKit ha permés el permís acquire-real-time."
 
-#: ../src/daemon/main.c:467
+#: ../src/daemon/main.c:477
 msgid "PolicyKit refuses acquire-real-time privilege."
 msgstr "PolicyKit ha rebutjat el permís acquire-real-time."
 
-#: ../src/daemon/main.c:479
+#: ../src/daemon/main.c:506
+#, fuzzy
 msgid ""
-"Called SUID root and real-time/high-priority scheduling was requested in the configuration. However, we lack the necessary priviliges:\n"
+"Called SUID root and real-time and/or high-priority scheduling was requested "
+"in the configuration. However, we lack the necessary privileges:\n"
 "We are not in group '"
 msgstr ""
-"S'han especificat la crida SUID root i la planificació amb prioritat alta/temps real en la configuració, però no té els permissos necessaris:\n"
+"S'han especificat la crida SUID root i la planificació amb prioritat alta/"
+"temps real en la configuració, però no té els permissos necessaris:\n"
 "No es pertany al grup '"
 
-#: ../src/daemon/main.c:480
+#: ../src/daemon/main.c:530
 msgid ""
-"' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n"
-"For enabling real-time scheduling please acquire the appropriate PolicyKit priviliges, or become a member of '"
+"High-priority scheduling enabled in configuration but not allowed by policy."
 msgstr ""
-"' i PolicyKit ha denegat els permissos. S'està lliberant SUID. \n"
-"Per habilitar la prioritat en temps real, s'ha d'adquirir els permissos de PolicyKit, o pertanyer a '"
-
-#: ../src/daemon/main.c:481
-msgid "', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user."
-msgstr "', o incrementar els límits de recursos RLIMIT_NICE/RLIMIT_RTPRIO per a aquest usuari."
-
-#: ../src/daemon/main.c:497
-msgid "High-priority scheduling enabled in configuration but not allowed by policy."
-msgstr "La prioritat alta està habilitada en la configuració però no està permesa per la política."
+"La prioritat alta està habilitada en la configuració però no està permesa "
+"per la política."
 
-#: ../src/daemon/main.c:522
+#: ../src/daemon/main.c:559
 msgid "Successfully increased RLIMIT_RTPRIO"
 msgstr "S'ha incrementat el valor de RLIMIT_RTPRIO amb éxit."
 
-#: ../src/daemon/main.c:525
+#: ../src/daemon/main.c:562
 #, c-format
 msgid "RLIMIT_RTPRIO failed: %s"
 msgstr "S'ha produït un error amb RLIMIT_RTPRIO: %s"
 
-#: ../src/daemon/main.c:532
+#: ../src/daemon/main.c:569
 msgid "Giving up CAP_NICE"
 msgstr "No es continuarà amb CAP_NICE"
 
-#: ../src/daemon/main.c:539
-msgid "Real-time scheduling enabled in configuration but not allowed by policy."
-msgstr "La prioritat de planificació de temps real està habilitada en la configuració però no està permesa per la política."
+#: ../src/daemon/main.c:576
+msgid ""
+"Real-time scheduling enabled in configuration but not allowed by policy."
+msgstr ""
+"La prioritat de planificació de temps real està habilitada en la "
+"configuració però no està permesa per la política."
 
-#: ../src/daemon/main.c:597
+#: ../src/daemon/main.c:637
 msgid "Daemon not running"
 msgstr "El dimoni no s'està executant."
 
-#: ../src/daemon/main.c:599
+#: ../src/daemon/main.c:639
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "El dimoni s'està executant amb PID %u"
 
-#: ../src/daemon/main.c:609
+#: ../src/daemon/main.c:649
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "S'ha produït un error en matar el dimoni: %s"
 
-#: ../src/daemon/main.c:627
-msgid "This program is not intended to be run as root (unless --system is specified)."
-msgstr "No és necessari executar aquesta aplicació com a root (excepte si s'especifica --system)"
+#: ../src/daemon/main.c:667
+msgid ""
+"This program is not intended to be run as root (unless --system is "
+"specified)."
+msgstr ""
+"No és necessari executar aquesta aplicació com a root (excepte si "
+"s'especifica --system)"
 
-#: ../src/daemon/main.c:629
-msgid "Root priviliges required."
+#: ../src/daemon/main.c:669
+#, fuzzy
+msgid "Root privileges required."
 msgstr "Es requereixen permisos de root."
 
-#: ../src/daemon/main.c:634
+#: ../src/daemon/main.c:674
 msgid "--start not supported for system instances."
 msgstr "L'opció --start no està disponible per a instàncies de sistema."
 
-#: ../src/daemon/main.c:639
+#: ../src/daemon/main.c:679
 msgid "Running in system mode, but --disallow-exit not set!"
-msgstr "S'està executant en mode sistema, però no s'ha especificat l'opció --disallow-exit."
+msgstr ""
+"S'està executant en mode sistema, però no s'ha especificat l'opció --"
+"disallow-exit."
 
-#: ../src/daemon/main.c:642
+#: ../src/daemon/main.c:682
 msgid "Running in system mode, but --disallow-module-loading not set!"
-msgstr "S'està executant en mode sistema, però no s'ha especificat l'opció --disallow-module-loading."
+msgstr ""
+"S'està executant en mode sistema, però no s'ha especificat l'opció --"
+"disallow-module-loading."
 
-#: ../src/daemon/main.c:645
+#: ../src/daemon/main.c:685
 msgid "Running in system mode, forcibly disabling SHM mode!"
-msgstr "S'està executant en mode sistema, es forçarà la inhabilitació del mode SHM"
+msgstr ""
+"S'està executant en mode sistema, es forçarà la inhabilitació del mode SHM"
 
-#: ../src/daemon/main.c:650
+#: ../src/daemon/main.c:690
 msgid "Running in system mode, forcibly disabling exit idle time!"
-msgstr "S'està executant en mode sistema, la sortida per temps d'inactivitat es deshabilita."
+msgstr ""
+"S'està executant en mode sistema, la sortida per temps d'inactivitat es "
+"deshabilita."
 
-#: ../src/daemon/main.c:677
+#: ../src/daemon/main.c:717
 msgid "Failed to acquire stdio."
 msgstr "S'ha produït un error en adquirir stdio."
 
-#: ../src/daemon/main.c:683
+#: ../src/daemon/main.c:723
 #, c-format
 msgid "pipe failed: %s"
 msgstr "Ha fallat la canonada: %s"
 
-#: ../src/daemon/main.c:688
+#: ../src/daemon/main.c:728
 #, c-format
 msgid "fork() failed: %s"
 msgstr "Ha fallat fork(): %s"
 
-#: ../src/daemon/main.c:702
+#: ../src/daemon/main.c:742
 #, c-format
 msgid "read() failed: %s"
 msgstr "Ha fallat read(): %s"
 
-#: ../src/daemon/main.c:708
+#: ../src/daemon/main.c:748
 msgid "Daemon startup failed."
 msgstr "S'ha produït un error en iniciar el dimoni."
 
-#: ../src/daemon/main.c:710
+#: ../src/daemon/main.c:750
 msgid "Daemon startup successful."
 msgstr "S'ha iniciat el dimoni."
 
-#: ../src/daemon/main.c:780
+#: ../src/daemon/main.c:820
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "Aquest és el PulseAudio %s"
 
-#: ../src/daemon/main.c:781
+#: ../src/daemon/main.c:821
 #, c-format
 msgid "Compilation host: %s"
 msgstr "Host de compilació: %s"
 
-#: ../src/daemon/main.c:782
+#: ../src/daemon/main.c:822
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "CFLAGS de compilació: %s"
 
-#: ../src/daemon/main.c:785
+#: ../src/daemon/main.c:825
 #, c-format
 msgid "Running on host: %s"
 msgstr "S'està executant en el host: %s"
 
-#: ../src/daemon/main.c:788
+#: ../src/daemon/main.c:828
+#, c-format
+msgid "Found %u CPUs."
+msgstr ""
+
+#: ../src/daemon/main.c:830
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "La mida de pàgina és de %lu bytes."
 
-#: ../src/daemon/main.c:791
+#: ../src/daemon/main.c:833
 msgid "Compiled with Valgrind support: yes"
 msgstr "Compilat amb suport per a Valgrind: sí"
 
-#: ../src/daemon/main.c:793
+#: ../src/daemon/main.c:835
 msgid "Compiled with Valgrind support: no"
 msgstr "Compilat amb suport per a Valgrind: no"
 
-#: ../src/daemon/main.c:796
+#: ../src/daemon/main.c:838
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "S'està executant amb el mode valgrind: %s"
 
-#: ../src/daemon/main.c:799
+#: ../src/daemon/main.c:841
 msgid "Optimized build: yes"
 msgstr "Construcció optimitzada: sí"
 
-#: ../src/daemon/main.c:801
+#: ../src/daemon/main.c:843
 msgid "Optimized build: no"
 msgstr "Construcció optmitzada: no"
 
-#: ../src/daemon/main.c:805
+#: ../src/daemon/main.c:847
 msgid "Failed to get machine ID"
 msgstr "S'ha produït un error en obtenir l'ID de la màquina"
 
-#: ../src/daemon/main.c:808
+#: ../src/daemon/main.c:850
 #, c-format
 msgid "Machine ID is %s."
 msgstr "La ID de la màquina és %s."
 
-#: ../src/daemon/main.c:813
+#: ../src/daemon/main.c:855
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "S'esta utilitzant el directori d'execució %s."
 
-#: ../src/daemon/main.c:818
+#: ../src/daemon/main.c:860
 #, c-format
 msgid "Using state directory %s."
 msgstr "S'està utilitzant el directori d'estat %s."
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:863
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "S'està executant en mode sistema: %s"
 
-#: ../src/daemon/main.c:836
+#: ../src/daemon/main.c:878
 msgid "pa_pid_file_create() failed."
 msgstr "S'ha produït un error en pa_pid_file_create()."
 
-#: ../src/daemon/main.c:848
+#: ../src/daemon/main.c:890
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "Estan disponibles els temporitzadors d'alta resolució."
 
-#: ../src/daemon/main.c:850
-msgid "Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"
-msgstr "Es recomana la utilització d'un nucli amb els temporitzadors d'alta resolució habilitats."
+#: ../src/daemon/main.c:892
+msgid ""
+"Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
+"resolution timers enabled!"
+msgstr ""
+"Es recomana la utilització d'un nucli amb els temporitzadors d'alta "
+"resolució habilitats."
 
-#: ../src/daemon/main.c:860
+#: ../src/daemon/main.c:904
 msgid "pa_core_new() failed."
 msgstr "S'ha produït un error en pa_core_new()."
 
-#: ../src/daemon/main.c:921
+#: ../src/daemon/main.c:965
 msgid "Failed to initialize daemon."
 msgstr "S'ha produït un error en inicialitzar el dimoni."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:970
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "El dimoni s'ha iniciat sense cap mòdul carregat, no funcionarà."
 
-#: ../src/daemon/main.c:931
-#, c-format
-msgid "Default sink name (%s) does not exist in name register."
-msgstr "El nom per omissió del conducte (%s) no existeix en el registre de noms."
-
-#: ../src/daemon/main.c:944
+#: ../src/daemon/main.c:983
 msgid "Daemon startup complete."
 msgstr "S'ha completat la inicialització del dimoni."
 
-#: ../src/daemon/main.c:950
+#: ../src/daemon/main.c:989
 msgid "Daemon shutdown initiated."
 msgstr "S'ha iniciat l'aturada del dimoni."
 
-#: ../src/daemon/main.c:971
+#: ../src/daemon/main.c:1010
 msgid "Daemon terminated."
 msgstr "S'ha aturat el dimoni."
 
-#: ../src/daemon/cmdline.c:117
+#: ../src/daemon/cmdline.c:121
 #, fuzzy, c-format
 msgid ""
 "%s [options]\n"
@@ -421,34 +443,48 @@ msgid ""
 "      --dump-conf                       Dump default configuration\n"
 "      --dump-modules                    Dump list of available modules\n"
 "      --dump-resample-methods           Dump available resample methods\n"
-"      --cleanup-shm                     Cleanup stale shared memory segments\n"
-"      --start                           Start the daemon if it is not running\n"
+"      --cleanup-shm                     Cleanup stale shared memory "
+"segments\n"
+"      --start                           Start the daemon if it is not "
+"running\n"
 "  -k  --kill                            Kill a running daemon\n"
-"      --check                           Check for a running daemon\n"
+"      --check                           Check for a running daemon (only "
+"returns exit code)\n"
 "\n"
 "OPTIONS:\n"
 "      --system[=BOOL]                   Run as system-wide instance\n"
 "  -D, --daemonize[=BOOL]                Daemonize after startup\n"
 "      --fail[=BOOL]                     Quit when startup fails\n"
 "      --high-priority[=BOOL]            Try to set high nice level\n"
-"                                        (only available as root, when SUID or\n"
+"                                        (only available as root, when SUID "
+"or\n"
 "                                        with elevated RLIMIT_NICE)\n"
 "      --realtime[=BOOL]                 Try to enable realtime scheduling\n"
-"                                        (only available as root, when SUID or\n"
+"                                        (only available as root, when SUID "
+"or\n"
 "                                        with elevated RLIMIT_RTPRIO)\n"
-"      --disallow-module-loading[=BOOL]  Disallow module user requested module\n"
+"      --disallow-module-loading[=BOOL]  Disallow module user requested "
+"module\n"
 "                                        loading/unloading after startup\n"
 "      --disallow-exit[=BOOL]            Disallow user requested exit\n"
-"      --exit-idle-time=SECS             Terminate the daemon when idle and this\n"
+"      --exit-idle-time=SECS             Terminate the daemon when idle and "
+"this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle and\n"
+"      --module-idle-time=SECS           Unload autoloaded modules when idle "
+"and\n"
 "                                        this time passed\n"
-"      --scache-idle-time=SECS           Unload autoloaded samples when idle and\n"
+"      --scache-idle-time=SECS           Unload autoloaded samples when idle "
+"and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
 "      --log-target={auto,syslog,stderr} Specify the log target\n"
-"  -p, --dl-search-path=PATH             Set the search path for dynamic shared\n"
+"      --log-meta[=BOOL]                 Include code location in log "
+"messages\n"
+"      --log-time[=BOOL]                 Include timestamps in log messages\n"
+"      --log-backtrace=FRAMES            Include a backtrace in log messages\n"
+"  -p, --dl-search-path=PATH             Set the search path for dynamic "
+"shared\n"
 "                                        objects (plugins)\n"
 "      --resample-method=METHOD          Use the specified resampling method\n"
 "                                        (See --dump-resample-methods for\n"
@@ -459,10 +495,12 @@ msgid ""
 "      --disable-shm[=BOOL]              Disable shared memory support.\n"
 "\n"
 "STARTUP SCRIPT:\n"
-"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module with\n"
+"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module "
+"with\n"
 "                                        the specified argument\n"
 "  -F, --file=FILENAME                   Run the specified script\n"
-"  -C                                    Open a command line on the running TTY\n"
+"  -C                                    Open a command line on the running "
+"TTY\n"
 "                                        after startup\n"
 "\n"
 "  -n                                    Don't load default script file\n"
@@ -474,35 +512,46 @@ msgstr ""
 "      --version                         Mostra la versió\n"
 "      --dump-conf                       Volca la configuració per omissió\n"
 "      --dump-modules                    Volca la llista de mòduls\n"
-"      --dump-resample-methods           Volca els mètodes disponibles de remostratge\n"
-"      --cleanup-shm                     Neteja els segments de memòria compartida no emprats\n"
+"      --dump-resample-methods           Volca els mètodes disponibles de "
+"remostratge\n"
+"      --cleanup-shm                     Neteja els segments de memòria "
+"compartida no emprats\n"
 "      --start                           Inicia el dimoni si no està corrent\n"
 "  -k  --kill                            Mata el dimoni en execució\n"
 "      --check                           Comprova l'execució del dimoni\n"
 "\n"
 "OPCIONS:\n"
 "      --system[=BOOL]                   Executa com a instància de sistema\n"
-"  -D, --daemonize[=BOOL]                Converteix en dimoni després de la inicialització\n"
+"  -D, --daemonize[=BOOL]                Converteix en dimoni després de la "
+"inicialització\n"
 "      --fail[=BOOL]                     Surt quan falli la inicialització\n"
 "      --high-priority[=BOOL]            Prova d'establir un nivell\n"
-"                                        de prioritat alt (només disponible com a root,\n"
-"                                        amb SUID o amb un elevat RLIMIT_NICE)\n"
+"                                        de prioritat alt (només disponible "
+"com a root,\n"
+"                                        amb SUID o amb un elevat "
+"RLIMIT_NICE)\n"
 "      --realtime[=BOOL]                 Try to enable realtime scheduling\n"
-"                                        (only available as root, when SUID or\n"
+"                                        (only available as root, when SUID "
+"or\n"
 "                                        with elevated RLIMIT_RTPRIO)\n"
-"      --disallow-module-loading[=BOOL]  Disallow module user requested module\n"
+"      --disallow-module-loading[=BOOL]  Disallow module user requested "
+"module\n"
 "                                        loading/unloading after startup\n"
 "      --disallow-exit[=BOOL]            Disallow user requested exit\n"
-"      --exit-idle-time=SECS             Terminate the daemon when idle and this\n"
+"      --exit-idle-time=SECS             Terminate the daemon when idle and "
+"this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle and\n"
+"      --module-idle-time=SECS           Unload autoloaded modules when idle "
+"and\n"
 "                                        this time passed\n"
-"      --scache-idle-time=SECS           Unload autoloaded samples when idle and\n"
+"      --scache-idle-time=SECS           Unload autoloaded samples when idle "
+"and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
 "      --log-target={auto,syslog,stderr} Specify the log target\n"
-"  -p, --dl-search-path=PATH             Set the search path for dynamic shared\n"
+"  -p, --dl-search-path=PATH             Set the search path for dynamic "
+"shared\n"
 "                                        objects (plugins)\n"
 "      --resample-method=METHOD          Use the specified resampling method\n"
 "                                        (See --dump-resample-methods for\n"
@@ -513,64 +562,80 @@ msgstr ""
 "      --disable-shm[=BOOL]              Disable shared memory support.\n"
 "\n"
 "STARTUP SCRIPT:\n"
-"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module with\n"
+"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module "
+"with\n"
 "                                        the specified argument\n"
 "  -F, --file=FILENAME                   Run the specified script\n"
-"  -C                                    Open a command line on the running TTY\n"
+"  -C                                    Open a command line on the running "
+"TTY\n"
 "                                        after startup\n"
 "\n"
 "  -n                                    Don't load default script file\n"
 
-#: ../src/daemon/cmdline.c:245
+#: ../src/daemon/cmdline.c:252
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize necessita un argument booleà"
 
-#: ../src/daemon/cmdline.c:252
+#: ../src/daemon/cmdline.c:259
 msgid "--fail expects boolean argument"
 msgstr "--fail necessita un argument booleà"
 
-#: ../src/daemon/cmdline.c:262
-msgid "--log-level expects log level argument (either numeric in range 0..4 or one of debug, info, notice, warn, error)."
-msgstr "--log-level necessita un argument de nivell de log (valor númeric 0..4 o 'debug', 'info', 'notice', 'warn', 'error')."
+#: ../src/daemon/cmdline.c:269
+msgid ""
+"--log-level expects log level argument (either numeric in range 0..4 or one "
+"of debug, info, notice, warn, error)."
+msgstr ""
+"--log-level necessita un argument de nivell de log (valor númeric 0..4 o "
+"'debug', 'info', 'notice', 'warn', 'error')."
 
-#: ../src/daemon/cmdline.c:274
+#: ../src/daemon/cmdline.c:281
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority necessita un argument booleà"
 
-#: ../src/daemon/cmdline.c:281
+#: ../src/daemon/cmdline.c:288
 msgid "--realtime expects boolean argument"
 msgstr "--realtime necessita un argument booleà"
 
-#: ../src/daemon/cmdline.c:288
+#: ../src/daemon/cmdline.c:295
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading necessita un argument booleà"
 
-#: ../src/daemon/cmdline.c:295
+#: ../src/daemon/cmdline.c:302
 msgid "--disallow-exit boolean argument"
 msgstr "--disallow-exit necessita un argument booleà"
 
-#: ../src/daemon/cmdline.c:302
+#: ../src/daemon/cmdline.c:309
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file necessita un argument booleà"
 
-#: ../src/daemon/cmdline.c:319
+#: ../src/daemon/cmdline.c:326
 msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
 msgstr "Objectiu de registre invàlid: utilitzeu 'syslog', 'stderr' o 'auto'."
 
-#: ../src/daemon/cmdline.c:338
+#: ../src/daemon/cmdline.c:333
+#, fuzzy
+msgid "--log-time boolean argument"
+msgstr "--disallow-exit necessita un argument booleà"
+
+#: ../src/daemon/cmdline.c:340
+#, fuzzy
+msgid "--log-meta boolean argument"
+msgstr "--disallow-exit necessita un argument booleà"
+
+#: ../src/daemon/cmdline.c:359
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "Mètode de remostratge invàlid '%s'."
 
-#: ../src/daemon/cmdline.c:345
+#: ../src/daemon/cmdline.c:366
 msgid "--system expects boolean argument"
 msgstr "--system necessita un argument booleà"
 
-#: ../src/daemon/cmdline.c:352
+#: ../src/daemon/cmdline.c:373
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit necessita un argument booleà"
 
-#: ../src/daemon/cmdline.c:359
+#: ../src/daemon/cmdline.c:380
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm necessita un argument booleà"
 
@@ -614,290 +679,314 @@ msgstr ""
 msgid "Path: %s\n"
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:205
+#: ../src/daemon/daemon-conf.c:212
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:221
+#: ../src/daemon/daemon-conf.c:228
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:237
+#: ../src/daemon/daemon-conf.c:244
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:260
+#: ../src/daemon/daemon-conf.c:267
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:267
+#: ../src/daemon/daemon-conf.c:274
 #, c-format
 msgid "[%s:%u] rlimit not supported on this platform."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:283
+#: ../src/daemon/daemon-conf.c:290
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:301
+#: ../src/daemon/daemon-conf.c:308
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:319
+#: ../src/daemon/daemon-conf.c:326
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:337
+#: ../src/daemon/daemon-conf.c:344
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:355
+#: ../src/daemon/daemon-conf.c:362
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:373
+#: ../src/daemon/daemon-conf.c:380
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:570
+#: ../src/daemon/daemon-conf.c:566
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:644
+#: ../src/daemon/daemon-conf.c:640
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr ""
 
 #: ../src/daemon/caps.c:63
-msgid "Dropping root priviliges."
-msgstr ""
+#, fuzzy
+msgid "Dropping root privileges."
+msgstr "S'han lliberat els permissos de root amb éxit."
 
 #: ../src/daemon/caps.c:103
 msgid "Limited capabilities successfully to CAP_SYS_NICE."
 msgstr ""
 
-#: ../src/pulse/channelmap.c:102
+#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:804
 msgid "Mono"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:104
+#: ../src/pulse/channelmap.c:105
 msgid "Front Center"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:105
+#: ../src/pulse/channelmap.c:106
 msgid "Front Left"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:106
+#: ../src/pulse/channelmap.c:107
 msgid "Front Right"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:108
+#: ../src/pulse/channelmap.c:109
 msgid "Rear Center"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:109
+#: ../src/pulse/channelmap.c:110
 msgid "Rear Left"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:110
+#: ../src/pulse/channelmap.c:111
 msgid "Rear Right"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:112
+#: ../src/pulse/channelmap.c:113
 msgid "Low Frequency Emmiter"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:114
+#: ../src/pulse/channelmap.c:115
 msgid "Front Left-of-center"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:115
+#: ../src/pulse/channelmap.c:116
 msgid "Front Right-of-center"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:117
+#: ../src/pulse/channelmap.c:118
 msgid "Side Left"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:118
+#: ../src/pulse/channelmap.c:119
 msgid "Side Right"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:120
+#: ../src/pulse/channelmap.c:121
 msgid "Auxiliary 0"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:121
+#: ../src/pulse/channelmap.c:122
 msgid "Auxiliary 1"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:122
+#: ../src/pulse/channelmap.c:123
 msgid "Auxiliary 2"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:123
+#: ../src/pulse/channelmap.c:124
 msgid "Auxiliary 3"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:124
+#: ../src/pulse/channelmap.c:125
 msgid "Auxiliary 4"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:125
+#: ../src/pulse/channelmap.c:126
 msgid "Auxiliary 5"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:126
+#: ../src/pulse/channelmap.c:127
 msgid "Auxiliary 6"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:127
+#: ../src/pulse/channelmap.c:128
 msgid "Auxiliary 7"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:128
+#: ../src/pulse/channelmap.c:129
 msgid "Auxiliary 8"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:129
+#: ../src/pulse/channelmap.c:130
 msgid "Auxiliary 9"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:130
+#: ../src/pulse/channelmap.c:131
 msgid "Auxiliary 10"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:131
+#: ../src/pulse/channelmap.c:132
 msgid "Auxiliary 11"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:132
+#: ../src/pulse/channelmap.c:133
 msgid "Auxiliary 12"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:133
+#: ../src/pulse/channelmap.c:134
 msgid "Auxiliary 13"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:134
+#: ../src/pulse/channelmap.c:135
 msgid "Auxiliary 14"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:135
+#: ../src/pulse/channelmap.c:136
 msgid "Auxiliary 15"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:136
+#: ../src/pulse/channelmap.c:137
 msgid "Auxiliary 16"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:137
+#: ../src/pulse/channelmap.c:138
 msgid "Auxiliary 17"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:138
+#: ../src/pulse/channelmap.c:139
 msgid "Auxiliary 18"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:139
+#: ../src/pulse/channelmap.c:140
 msgid "Auxiliary 19"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:140
+#: ../src/pulse/channelmap.c:141
 msgid "Auxiliary 20"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:141
+#: ../src/pulse/channelmap.c:142
 msgid "Auxiliary 21"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:142
+#: ../src/pulse/channelmap.c:143
 msgid "Auxiliary 22"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:143
+#: ../src/pulse/channelmap.c:144
 msgid "Auxiliary 23"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:144
+#: ../src/pulse/channelmap.c:145
 msgid "Auxiliary 24"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:145
+#: ../src/pulse/channelmap.c:146
 msgid "Auxiliary 25"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:146
+#: ../src/pulse/channelmap.c:147
 msgid "Auxiliary 26"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:147
+#: ../src/pulse/channelmap.c:148
 msgid "Auxiliary 27"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:148
+#: ../src/pulse/channelmap.c:149
 msgid "Auxiliary 28"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:149
+#: ../src/pulse/channelmap.c:150
 msgid "Auxiliary 29"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:150
+#: ../src/pulse/channelmap.c:151
 msgid "Auxiliary 30"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:151
+#: ../src/pulse/channelmap.c:152
 msgid "Auxiliary 31"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:153
+#: ../src/pulse/channelmap.c:154
 msgid "Top Center"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:155
+#: ../src/pulse/channelmap.c:156
 msgid "Top Front Center"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:156
+#: ../src/pulse/channelmap.c:157
 msgid "Top Front Left"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:157
+#: ../src/pulse/channelmap.c:158
 msgid "Top Front Right"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:159
+#: ../src/pulse/channelmap.c:160
 msgid "Top Rear Center"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:160
+#: ../src/pulse/channelmap.c:161
 msgid "Top Rear Left"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:161
+#: ../src/pulse/channelmap.c:162
 msgid "Top Rear Right"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:472
-#: ../src/pulse/sample.c:144
-#: ../src/pulse/volume.c:163
-#: ../src/pulse/volume.c:194
+#: ../src/pulse/channelmap.c:476 ../src/pulse/sample.c:167
+#: ../src/pulse/volume.c:170 ../src/pulse/volume.c:196
+#: ../src/pulse/volume.c:216 ../src/pulse/volume.c:246
 msgid "(invalid)"
 msgstr ""
 
+#: ../src/pulse/channelmap.c:808
+msgid "Stereo"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:813
+msgid "Surround 4.0"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:819
+msgid "Surround 4.1"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:825
+msgid "Surround 5.0"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:831
+msgid "Surround 5.1"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:838
+msgid "Surround 7.1"
+msgstr ""
+
 #: ../src/pulse/error.c:43
 msgid "OK"
 msgstr ""
@@ -986,8 +1075,40 @@ msgstr ""
 msgid "No such extension"
 msgstr ""
 
-#: ../src/pulse/client-conf-x11.c:55
-#: ../src/utils/pax11publish.c:100
+#: ../src/pulse/error.c:65
+msgid "Obsolete functionality"
+msgstr ""
+
+#: ../src/pulse/error.c:66
+msgid "Missing implementation"
+msgstr ""
+
+#: ../src/pulse/sample.c:169
+#, c-format
+msgid "%s %uch %uHz"
+msgstr ""
+
+#: ../src/pulse/sample.c:181
+#, c-format
+msgid "%0.1f GiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:183
+#, c-format
+msgid "%0.1f MiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:185
+#, c-format
+msgid "%0.1f KiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:187
+#, c-format
+msgid "%u B"
+msgstr ""
+
+#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
 msgid "XOpenDisplay() failed"
 msgstr ""
 
@@ -1000,45 +1121,35 @@ msgstr ""
 msgid "Failed to open configuration file '%s': %s"
 msgstr ""
 
-#: ../src/pulse/context.c:516
+#: ../src/pulse/context.c:517
 msgid "No cookie loaded. Attempting to connect without."
 msgstr ""
 
-#: ../src/pulse/context.c:642
+#: ../src/pulse/context.c:643
 #, c-format
 msgid "fork(): %s"
 msgstr ""
 
-#: ../src/pulse/context.c:695
+#: ../src/pulse/context.c:696
 #, c-format
 msgid "waitpid(): %s"
 msgstr ""
 
-#: ../src/pulse/context.c:1256
+#: ../src/pulse/context.c:1257
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr ""
 
-#: ../src/utils/pacat.c:93
+#: ../src/utils/pacat.c:94
 #, c-format
 msgid "pa_stream_write() failed: %s\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:132
+#: ../src/utils/pacat.c:133
 #, c-format
 msgid "pa_stream_peek() failed: %s\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:141
-#, c-format
-msgid "Buffer overrun, dropping incoming data\n"
-msgstr ""
-
-#: ../src/utils/pacat.c:143
-#, c-format
-msgid "pa_stream_drop() failed: %s\n"
-msgstr ""
-
 #: ../src/utils/pacat.c:169
 #, c-format
 msgid "Stream successfully created.\n"
@@ -1118,83 +1229,78 @@ msgstr ""
 msgid "pa_stream_new() failed: %s\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:287
+#: ../src/utils/pacat.c:288
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:293
+#: ../src/utils/pacat.c:294
 #, c-format
 msgid "pa_stream_connect_record() failed: %s\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:307
-#: ../src/utils/pasuspender.c:159
-#: ../src/utils/pactl.c:666
-#: ../src/utils/paplay.c:183
+#: ../src/utils/pacat.c:308 ../src/utils/pasuspender.c:159
+#: ../src/utils/pactl.c:758 ../src/utils/paplay.c:183
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:328
-#: ../src/utils/paplay.c:75
+#: ../src/utils/pacat.c:329 ../src/utils/paplay.c:75
 #, c-format
 msgid "Failed to drain stream: %s\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:333
-#: ../src/utils/paplay.c:80
+#: ../src/utils/pacat.c:334 ../src/utils/paplay.c:80
 #, c-format
 msgid "Playback stream drained.\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:343
-#: ../src/utils/paplay.c:92
+#: ../src/utils/pacat.c:344 ../src/utils/paplay.c:92
 #, c-format
 msgid "Draining connection to server.\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:370
 #, c-format
 msgid "Got EOF.\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:375
+#: ../src/utils/pacat.c:376
 #, c-format
 msgid "pa_stream_drain(): %s\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:385
+#: ../src/utils/pacat.c:386
 #, c-format
 msgid "read() failed: %s\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:417
+#: ../src/utils/pacat.c:418
 #, c-format
 msgid "write() failed: %s\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:438
+#: ../src/utils/pacat.c:439
 #, c-format
 msgid "Got signal, exiting.\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:452
+#: ../src/utils/pacat.c:453
 #, c-format
 msgid "Failed to get latency: %s\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:457
+#: ../src/utils/pacat.c:458
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec.  \r"
 msgstr ""
 
-#: ../src/utils/pacat.c:477
+#: ../src/utils/pacat.c:478
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:490
+#: ../src/utils/pacat.c:491
 #, c-format
 msgid ""
 "%s [options]\n"
@@ -1207,30 +1313,47 @@ msgid ""
 "\n"
 "  -v, --verbose                         Enable verbose operations\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
-"  -d, --device=DEVICE                   The name of the sink/source to connect to\n"
-"  -n, --client-name=NAME                How to call this client on the server\n"
-"      --stream-name=NAME                How to call this stream on the server\n"
-"      --volume=VOLUME                   Specify the initial (linear) volume in range 0...65536\n"
-"      --rate=SAMPLERATE                 The sample rate in Hz (defaults to 44100)\n"
-"      --format=SAMPLEFORMAT             The sample type, one of s16le, s16be, u8, float32le,\n"
-"                                        float32be, ulaw, alaw, s32le, s32be (defaults to s16ne)\n"
-"      --channels=CHANNELS               The number of channels, 1 for mono, 2 for stereo\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -d, --device=DEVICE                   The name of the sink/source to "
+"connect to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
+"      --stream-name=NAME                How to call this stream on the "
+"server\n"
+"      --volume=VOLUME                   Specify the initial (linear) volume "
+"in range 0...65536\n"
+"      --rate=SAMPLERATE                 The sample rate in Hz (defaults to "
+"44100)\n"
+"      --format=SAMPLEFORMAT             The sample type, one of s16le, "
+"s16be, u8, float32le,\n"
+"                                        float32be, ulaw, alaw, s32le, s32be "
+"(defaults to s16ne)\n"
+"      --channels=CHANNELS               The number of channels, 1 for mono, "
+"2 for stereo\n"
 "                                        (defaults to 2)\n"
-"      --channel-map=CHANNELMAP          Channel map to use instead of the default\n"
-"      --fix-format                      Take the sample format from the sink the stream is\n"
+"      --channel-map=CHANNELMAP          Channel map to use instead of the "
+"default\n"
+"      --fix-format                      Take the sample format from the sink "
+"the stream is\n"
 "                                        being connected to.\n"
-"      --fix-rate                        Take the sampling rate from the sink the stream is\n"
+"      --fix-rate                        Take the sampling rate from the sink "
+"the stream is\n"
 "                                        being connected to.\n"
-"      --fix-channels                    Take the number of channels and the channel map\n"
-"                                        from the sink the stream is being connected to.\n"
+"      --fix-channels                    Take the number of channels and the "
+"channel map\n"
+"                                        from the sink the stream is being "
+"connected to.\n"
 "      --no-remix                        Don't upmix or downmix channels.\n"
-"      --no-remap                        Map channels by index instead of name.\n"
-"      --latency=BYTES                   Request the specified latency in bytes.\n"
-"      --process-time=BYTES              Request the specified process time per request in bytes.\n"
+"      --no-remap                        Map channels by index instead of "
+"name.\n"
+"      --latency=BYTES                   Request the specified latency in "
+"bytes.\n"
+"      --process-time=BYTES              Request the specified process time "
+"per request in bytes.\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:591
+#: ../src/utils/pacat.c:592
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1238,94 +1361,88 @@ msgid ""
 "Linked with libpulse %s\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:647
+#: ../src/utils/pacat.c:649
 #, c-format
 msgid "Invalid channel map '%s'\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:676
+#: ../src/utils/pacat.c:678
 #, c-format
 msgid "Invalid latency specification '%s'\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:683
+#: ../src/utils/pacat.c:685
 #, c-format
 msgid "Invalid process time specification '%s'\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:694
+#: ../src/utils/pacat.c:696
 #, c-format
 msgid "Invalid sample specification\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:699
+#: ../src/utils/pacat.c:701
 #, c-format
 msgid "Channel map doesn't match sample specification\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:706
+#: ../src/utils/pacat.c:708
 #, c-format
 msgid "Opening a %s stream with sample specification '%s'.\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:706
+#: ../src/utils/pacat.c:708
 msgid "recording"
 msgstr ""
 
-#: ../src/utils/pacat.c:706
+#: ../src/utils/pacat.c:708
 msgid "playback"
 msgstr ""
 
-#: ../src/utils/pacat.c:714
+#: ../src/utils/pacat.c:716
 #, c-format
 msgid "open(): %s\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:719
+#: ../src/utils/pacat.c:721
 #, c-format
 msgid "dup2(): %s\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:729
+#: ../src/utils/pacat.c:731
 #, c-format
 msgid "Too many arguments.\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:742
-#: ../src/utils/pasuspender.c:280
-#: ../src/utils/pactl.c:909
-#: ../src/utils/paplay.c:381
+#: ../src/utils/pacat.c:744 ../src/utils/pasuspender.c:280
+#: ../src/utils/pactl.c:1013 ../src/utils/paplay.c:381
 #, c-format
 msgid "pa_mainloop_new() failed.\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:763
+#: ../src/utils/pacat.c:765
 #, c-format
 msgid "io_new() failed.\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:769
-#: ../src/utils/pasuspender.c:293
-#: ../src/utils/pactl.c:923
-#: ../src/utils/paplay.c:396
+#: ../src/utils/pacat.c:771 ../src/utils/pasuspender.c:293
+#: ../src/utils/pactl.c:1027 ../src/utils/paplay.c:396
 #, c-format
 msgid "pa_context_new() failed.\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:777
+#: ../src/utils/pacat.c:779
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr ""
 
-#: ../src/utils/pacat.c:788
+#: ../src/utils/pacat.c:790
 #, c-format
 msgid "time_new() failed.\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:795
-#: ../src/utils/pasuspender.c:301
-#: ../src/utils/pactl.c:931
-#: ../src/utils/paplay.c:407
+#: ../src/utils/pacat.c:797 ../src/utils/pasuspender.c:301
+#: ../src/utils/pactl.c:1035 ../src/utils/paplay.c:407
 #, c-format
 msgid "pa_mainloop_run() failed.\n"
 msgstr ""
@@ -1355,8 +1472,7 @@ msgstr ""
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr ""
 
-#: ../src/utils/pasuspender.c:176
-#: ../src/utils/pactl.c:672
+#: ../src/utils/pasuspender.c:176 ../src/utils/pactl.c:764
 #: ../src/utils/paplay.c:191
 #, c-format
 msgid "Got SIGINT, exiting.\n"
@@ -1374,7 +1490,8 @@ msgid ""
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
 "\n"
 msgstr ""
 
@@ -1386,32 +1503,32 @@ msgid ""
 "Linked with libpulse %s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:107
+#: ../src/utils/pactl.c:108
 #, c-format
 msgid "Failed to get statistics: %s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:113
+#: ../src/utils/pactl.c:114
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:116
+#: ../src/utils/pactl.c:117
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:119
+#: ../src/utils/pactl.c:120
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:128
+#: ../src/utils/pactl.c:129
 #, c-format
 msgid "Failed to get server information: %s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:136
 #, c-format
 msgid ""
 "User name: %s\n"
@@ -1424,206 +1541,212 @@ msgid ""
 "Cookie: %08x\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:160
+#: ../src/utils/pactl.c:175
 #, c-format
 msgid "Failed to get sink information: %s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:176
+#: ../src/utils/pactl.c:191
 #, c-format
 msgid ""
-"*** Sink #%u ***\n"
-"Name: %s\n"
-"Driver: %s\n"
-"Sample Specification: %s\n"
-"Channel Map: %s\n"
-"Owner Module: %u\n"
-"Volume: %s\n"
-"Monitor Source: %s\n"
-"Latency: %0.0f usec, configured %0.0f usec\n"
-"Flags: %s%s%s%s%s%s\n"
-"Properties:\n"
-"%s"
-msgstr ""
-
-#: ../src/utils/pactl.c:193
-#: ../src/utils/pactl.c:371
-msgid "muted"
-msgstr ""
-
-#: ../src/utils/pactl.c:212
+"Sink #%u\n"
+"\tState: %s\n"
+"\tName: %s\n"
+"\tDescription: %s\n"
+"\tDriver: %s\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tOwner Module: %u\n"
+"\tMute: %s\n"
+"\tVolume: %s%s%s\n"
+"\t        balance %0.2f\n"
+"\tBase Volume: %s%s%s\n"
+"\tMonitor Source: %s\n"
+"\tLatency: %0.0f usec, configured %0.0f usec\n"
+"\tFlags: %s%s%s%s%s%s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:255
 #, c-format
 msgid "Failed to get source information: %s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:228
+#: ../src/utils/pactl.c:271
 #, c-format
 msgid ""
-"*** Source #%u ***\n"
-"Name: %s\n"
-"Driver: %s\n"
-"Sample Specification: %s\n"
-"Channel Map: %s\n"
-"Owner Module: %u\n"
-"Volume: %s\n"
-"Monitor of Sink: %s\n"
-"Latency: %0.0f usec, configured %0.0f usec\n"
-"Flags: %s%s%s%s%s%s\n"
-"Properties:\n"
-"%s"
-msgstr ""
-
-#: ../src/utils/pactl.c:246
-#: ../src/utils/pactl.c:289
-#: ../src/utils/pactl.c:322
-#: ../src/utils/pactl.c:366
-#: ../src/utils/pactl.c:367
-#: ../src/utils/pactl.c:374
-#: ../src/utils/pactl.c:418
-#: ../src/utils/pactl.c:419
-#: ../src/utils/pactl.c:425
-#: ../src/utils/pactl.c:468
-#: ../src/utils/pactl.c:469
-#: ../src/utils/pactl.c:473
+"Source #%u\n"
+"\tState: %s\n"
+"\tName: %s\n"
+"\tDescription: %s\n"
+"\tDriver: %s\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tOwner Module: %u\n"
+"\tMute: %s\n"
+"\tVolume: %s%s%s\n"
+"\t        balance %0.2f\n"
+"\tBase Volume: %s%s%s\n"
+"\tMonitor of Sink: %s\n"
+"\tLatency: %0.0f usec, configured %0.0f usec\n"
+"\tFlags: %s%s%s%s%s%s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:303 ../src/utils/pactl.c:347 ../src/utils/pactl.c:382
+#: ../src/utils/pactl.c:419 ../src/utils/pactl.c:478 ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:489 ../src/utils/pactl.c:533 ../src/utils/pactl.c:534
+#: ../src/utils/pactl.c:540 ../src/utils/pactl.c:583 ../src/utils/pactl.c:584
+#: ../src/utils/pactl.c:591
 msgid "n/a"
 msgstr ""
 
-#: ../src/utils/pactl.c:263
+#: ../src/utils/pactl.c:321
 #, c-format
 msgid "Failed to get module information: %s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:281
+#: ../src/utils/pactl.c:339
 #, c-format
 msgid ""
-"*** Module #%u ***\n"
-"Name: %s\n"
-"Argument: %s\n"
-"Usage counter: %s\n"
-"Auto unload: %s\n"
+"Module #%u\n"
+"\tName: %s\n"
+"\tArgument: %s\n"
+"\tUsage counter: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:298
+#: ../src/utils/pactl.c:358
 #, c-format
 msgid "Failed to get client information: %s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:316
+#: ../src/utils/pactl.c:376
 #, c-format
 msgid ""
-"*** Client #%u ***\n"
-"Driver: %s\n"
-"Owner Module: %s\n"
-"Properties:\n"
-"%s"
+"Client #%u\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:333
+#: ../src/utils/pactl.c:393
+#, fuzzy, c-format
+msgid "Failed to get card information: %s\n"
+msgstr "S'ha produït un error en obtenir l'ID de la màquina"
+
+#: ../src/utils/pactl.c:411
 #, c-format
-msgid "Failed to get sink input information: %s\n"
+msgid ""
+"Card #%u\n"
+"\tName: %s\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:352
+#: ../src/utils/pactl.c:425
 #, c-format
-msgid ""
-"*** Sink Input #%u ***\n"
-"Driver: %s\n"
-"Owner Module: %s\n"
-"Client: %s\n"
-"Sink: %u\n"
-"Sample Specification: %s\n"
-"Channel Map: %s\n"
-"Volume: %s\n"
-"Buffer Latency: %0.0f usec\n"
-"Sink Latency: %0.0f usec\n"
-"Resample method: %s\n"
-"Properties:\n"
-"%s"
-msgstr ""
-
-#: ../src/utils/pactl.c:385
+msgid "\tProfiles:\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:431
+#, fuzzy, c-format
+msgid "\tActive Profile: %s\n"
+msgstr "Ha fallat la canonada: %s"
+
+#: ../src/utils/pactl.c:442
 #, c-format
-msgid "Failed to get source output information: %s\n"
+msgid "Failed to get sink input information: %s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:405
+#: ../src/utils/pactl.c:461
 #, c-format
 msgid ""
-"*** Source Output #%u ***\n"
-"Driver: %s\n"
-"Owner Module: %s\n"
-"Client: %s\n"
-"Source: %u\n"
-"Sample Specification: %s\n"
-"Channel Map: %s\n"
-"Buffer Latency: %0.0f usec\n"
-"Source Latency: %0.0f usec\n"
-"Resample method: %s\n"
-"Properties:\n"
-"%s"
-msgstr ""
-
-#: ../src/utils/pactl.c:436
+"Sink Input #%u\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tClient: %s\n"
+"\tSink: %u\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
+"\tBuffer Latency: %0.0f usec\n"
+"\tSink Latency: %0.0f usec\n"
+"\tResample method: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:500
 #, c-format
-msgid "Failed to get sample information: %s\n"
+msgid "Failed to get source output information: %s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:455
+#: ../src/utils/pactl.c:520
 #, c-format
 msgid ""
-"*** Sample #%u ***\n"
-"Name: %s\n"
-"Volume: %s\n"
-"Sample Specification: %s\n"
-"Channel Map: %s\n"
-"Duration: %0.1fs\n"
-"Size: %s\n"
-"Lazy: %s\n"
-"Filename: %s\n"
-"Properties:\n"
-"%s"
-msgstr ""
-
-#: ../src/utils/pactl.c:481
+"Source Output #%u\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tClient: %s\n"
+"\tSource: %u\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tBuffer Latency: %0.0f usec\n"
+"\tSource Latency: %0.0f usec\n"
+"\tResample method: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:551
 #, c-format
-msgid "Failed to get autoload information: %s\n"
+msgid "Failed to get sample information: %s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:497
+#: ../src/utils/pactl.c:569
 #, c-format
 msgid ""
-"*** Autoload Entry #%u ***\n"
-"Name: %s\n"
-"Type: %s\n"
-"Module: %s\n"
-"Argument: %s\n"
-msgstr ""
-
-#: ../src/utils/pactl.c:504
-msgid "sink"
-msgstr ""
-
-#: ../src/utils/pactl.c:504
-msgid "source"
-msgstr ""
-
-#: ../src/utils/pactl.c:511
-#: ../src/utils/pactl.c:521
+"Sample #%u\n"
+"\tName: %s\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
+"\tDuration: %0.1fs\n"
+"\tSize: %s\n"
+"\tLazy: %s\n"
+"\tFilename: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:599 ../src/utils/pactl.c:609
 #, c-format
 msgid "Failure: %s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:545
+#: ../src/utils/pactl.c:633
 #, c-format
 msgid "Failed to upload sample: %s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:562
+#: ../src/utils/pactl.c:650
 #, c-format
 msgid "Premature end of file\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:678
+#: ../src/utils/pactl.c:770
 #, c-format
 msgid ""
 "%s [options] stat\n"
@@ -1638,15 +1761,18 @@ msgid ""
 "%s [options] unload-module ID\n"
 "%s [options] suspend-sink [SINK] 1|0\n"
 "%s [options] suspend-source [SOURCE] 1|0\n"
+"%s [options] set-card-profile [CARD] [PROFILE] \n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
-"  -n, --client-name=NAME                How to call this client on the server\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:729
+#: ../src/utils/pactl.c:822
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -1654,57 +1780,66 @@ msgid ""
 "Linked with libpulse %s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:768
+#: ../src/utils/pactl.c:861
 #, c-format
 msgid "Please specify a sample file to load\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:790
+#: ../src/utils/pactl.c:883
 #, c-format
 msgid "Failed to open sound file.\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:802
+#: ../src/utils/pactl.c:895
 #, c-format
 msgid "You have to specify a sample name to play\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:814
+#: ../src/utils/pactl.c:907
 #, c-format
 msgid "You have to specify a sample name to remove\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:822
+#: ../src/utils/pactl.c:915
 #, c-format
 msgid "You have to specify a sink input index and a sink\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:831
+#: ../src/utils/pactl.c:924
 #, c-format
 msgid "You have to specify a source output index and a source\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:845
+#: ../src/utils/pactl.c:938
 #, c-format
 msgid "You have to specify a module name and arguments.\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:865
+#: ../src/utils/pactl.c:958
 #, c-format
 msgid "You have to specify a module index\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:875
+#: ../src/utils/pactl.c:968
+#, c-format
+msgid ""
+"You may not specify more than one sink. You have to specify a boolean "
+"value.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:981
 #, c-format
-msgid "You may not specify more than one sink. You have to specify at least one boolean value.\n"
+msgid ""
+"You may not specify more than one source. You have to specify a boolean "
+"value.\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:888
+#: ../src/utils/pactl.c:993
 #, c-format
-msgid "You may not specify more than one source. You have to specify at least one boolean value.\n"
+msgid "You have to specify a card name/index and a profile name\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:904
+#: ../src/utils/pactl.c:1008
 #, c-format
 msgid "No valid command specified.\n"
 msgstr ""
@@ -1716,7 +1851,8 @@ msgid ""
 "\n"
 " -d    Show current PulseAudio data attached to X11 display (default)\n"
 " -e    Export local PulseAudio data to X11 display\n"
-" -i    Import PulseAudio data from X11 display to local environment variables and cookie file.\n"
+" -i    Import PulseAudio data from X11 display to local environment "
+"variables and cookie file.\n"
 " -r    Remove PulseAudio data from X11 display\n"
 msgstr ""
 
@@ -1798,19 +1934,17 @@ msgstr ""
 msgid "Daemon not responding."
 msgstr ""
 
-#: ../src/utils/pacmd.c:112
+#: ../src/utils/pacmd.c:144
 #, c-format
 msgid "select(): %s"
 msgstr "select(): %s"
 
-#: ../src/utils/pacmd.c:124
-#: ../src/utils/pacmd.c:140
+#: ../src/utils/pacmd.c:154 ../src/utils/pacmd.c:171
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:153
-#: ../src/utils/pacmd.c:167
+#: ../src/utils/pacmd.c:187 ../src/utils/pacmd.c:201
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
@@ -1840,11 +1974,15 @@ msgid ""
 "\n"
 "  -v, --verbose                         Enable verbose operation\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
 "  -d, --device=DEVICE                   The name of the sink to connect to\n"
-"  -n, --client-name=NAME                How to call this client on the server\n"
-"      --stream-name=NAME                How to call this stream on the server\n"
-"      --volume=VOLUME                   Specify the initial (linear) volume in range 0...65536\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
+"      --stream-name=NAME                How to call this stream on the "
+"server\n"
+"      --volume=VOLUME                   Specify the initial (linear) volume "
+"in range 0...65536\n"
 "      --channel-map=CHANNELMAP          Set the channel map to the use\n"
 msgstr ""
 
@@ -1876,8 +2014,26 @@ msgstr ""
 msgid "Using sample spec '%s'\n"
 msgstr ""
 
-#: ../src/pulsecore/lock-autospawn.c:126
-#: ../src/pulsecore/lock-autospawn.c:207
+#: ../src/pulsecore/lock-autospawn.c:126 ../src/pulsecore/lock-autospawn.c:207
 msgid "Cannot access autospawn lock."
 msgstr ""
 
+#~ msgid ""
+#~ "' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n"
+#~ "For enabling real-time scheduling please acquire the appropriate "
+#~ "PolicyKit priviliges, or become a member of '"
+#~ msgstr ""
+#~ "' i PolicyKit ha denegat els permissos. S'està lliberant SUID. \n"
+#~ "Per habilitar la prioritat en temps real, s'ha d'adquirir els permissos "
+#~ "de PolicyKit, o pertanyer a '"
+
+#~ msgid ""
+#~ "', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this "
+#~ "user."
+#~ msgstr ""
+#~ "', o incrementar els límits de recursos RLIMIT_NICE/RLIMIT_RTPRIO per a "
+#~ "aquest usuari."
+
+#~ msgid "Default sink name (%s) does not exist in name register."
+#~ msgstr ""
+#~ "El nom per omissió del conducte (%s) no existeix en el registre de noms."
diff --git a/po/cs.po b/po/cs.po
index 344b0c0..ff12391 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-01-28 04:30+0100\n"
+"POT-Creation-Date: 2009-02-04 21:48+0100\n"
 "PO-Revision-Date: 2008-10-19 22:31+0200\n"
 "Last-Translator: Petr Kovar <pknbe at volny.cz>\n"
 "Language-Team: Czech <translation-team-cs at lists.sourceforge.net>\n"
@@ -711,7 +711,7 @@ msgstr "Rušení superuživatelských oprávnění."
 msgid "Limited capabilities successfully to CAP_SYS_NICE."
 msgstr "Schopnosti úspěšně omezeny na CAP_SYS_NICE."
 
-#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:742
+#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:804
 msgid "Mono"
 msgstr "Mono"
 
@@ -915,34 +915,34 @@ msgstr "Horní zadní levý"
 msgid "Top Rear Right"
 msgstr "Horní zadní pravý"
 
-#: ../src/pulse/channelmap.c:473 ../src/pulse/sample.c:152
-#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:189
-#: ../src/pulse/volume.c:209 ../src/pulse/volume.c:239
+#: ../src/pulse/channelmap.c:476 ../src/pulse/sample.c:167
+#: ../src/pulse/volume.c:170 ../src/pulse/volume.c:196
+#: ../src/pulse/volume.c:216 ../src/pulse/volume.c:246
 #, fuzzy
 msgid "(invalid)"
 msgstr "Neplatné"
 
-#: ../src/pulse/channelmap.c:746
+#: ../src/pulse/channelmap.c:808
 msgid "Stereo"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:751
+#: ../src/pulse/channelmap.c:813
 msgid "Surround 4.0"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:757
+#: ../src/pulse/channelmap.c:819
 msgid "Surround 4.1"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:763
+#: ../src/pulse/channelmap.c:825
 msgid "Surround 5.0"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:769
+#: ../src/pulse/channelmap.c:831
 msgid "Surround 5.1"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:776
+#: ../src/pulse/channelmap.c:838
 msgid "Surround 7.1"
 msgstr ""
 
@@ -1034,6 +1034,39 @@ msgstr "Neznámý chybový kód"
 msgid "No such extension"
 msgstr "Takové rozšíření neexistuje"
 
+#: ../src/pulse/error.c:65
+msgid "Obsolete functionality"
+msgstr ""
+
+#: ../src/pulse/error.c:66
+msgid "Missing implementation"
+msgstr ""
+
+#: ../src/pulse/sample.c:169
+#, c-format
+msgid "%s %uch %uHz"
+msgstr ""
+
+#: ../src/pulse/sample.c:181
+#, c-format
+msgid "%0.1f GiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:183
+#, c-format
+msgid "%0.1f MiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:185
+#, c-format
+msgid "%0.1f KiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:187
+#, c-format
+msgid "%u B"
+msgstr ""
+
 #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
 msgid "XOpenDisplay() failed"
 msgstr "XOpenDisplay() selhalo"
@@ -1960,17 +1993,17 @@ msgstr "Nezdařilo se zabít démona PulseAudio."
 msgid "Daemon not responding."
 msgstr "Démon neodpovídá."
 
-#: ../src/utils/pacmd.c:112
+#: ../src/utils/pacmd.c:144
 #, c-format
 msgid "select(): %s"
 msgstr "select(): %s"
 
-#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140
+#: ../src/utils/pacmd.c:154 ../src/utils/pacmd.c:171
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167
+#: ../src/utils/pacmd.c:187 ../src/utils/pacmd.c:201
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
diff --git a/po/de.po b/po/de.po
index 61d8f7b..1a7005a 100644
--- a/po/de.po
+++ b/po/de.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-01-28 04:30+0100\n"
+"POT-Creation-Date: 2009-02-04 21:48+0100\n"
 "PO-Revision-Date: 2008-10-22 00:58+0100\n"
 "Last-Translator: Fabian Affolter <fab at fedoraproject.org>\n"
 "Language-Team: German <fedora-trans-de at redhat.com>\n"
@@ -727,7 +727,7 @@ msgstr "Gebe Root-Privilegien auf."
 msgid "Limited capabilities successfully to CAP_SYS_NICE."
 msgstr "Fähigkeiten erfolgreich auf CAP_SYS_NICE reduziert."
 
-#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:742
+#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:804
 msgid "Mono"
 msgstr "Mono"
 
@@ -931,33 +931,33 @@ msgstr "Oben Hinten Links"
 msgid "Top Rear Right"
 msgstr "Oben Hinten Rechts"
 
-#: ../src/pulse/channelmap.c:473 ../src/pulse/sample.c:152
-#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:189
-#: ../src/pulse/volume.c:209 ../src/pulse/volume.c:239
+#: ../src/pulse/channelmap.c:476 ../src/pulse/sample.c:167
+#: ../src/pulse/volume.c:170 ../src/pulse/volume.c:196
+#: ../src/pulse/volume.c:216 ../src/pulse/volume.c:246
 msgid "(invalid)"
 msgstr "(ungültig)"
 
-#: ../src/pulse/channelmap.c:746
+#: ../src/pulse/channelmap.c:808
 msgid "Stereo"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:751
+#: ../src/pulse/channelmap.c:813
 msgid "Surround 4.0"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:757
+#: ../src/pulse/channelmap.c:819
 msgid "Surround 4.1"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:763
+#: ../src/pulse/channelmap.c:825
 msgid "Surround 5.0"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:769
+#: ../src/pulse/channelmap.c:831
 msgid "Surround 5.1"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:776
+#: ../src/pulse/channelmap.c:838
 msgid "Surround 7.1"
 msgstr ""
 
@@ -1049,6 +1049,39 @@ msgstr "Unbekannter Fehlercode"
 msgid "No such extension"
 msgstr "Erweiterung nicht vorhanden"
 
+#: ../src/pulse/error.c:65
+msgid "Obsolete functionality"
+msgstr ""
+
+#: ../src/pulse/error.c:66
+msgid "Missing implementation"
+msgstr ""
+
+#: ../src/pulse/sample.c:169
+#, c-format
+msgid "%s %uch %uHz"
+msgstr ""
+
+#: ../src/pulse/sample.c:181
+#, c-format
+msgid "%0.1f GiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:183
+#, c-format
+msgid "%0.1f MiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:185
+#, c-format
+msgid "%0.1f KiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:187
+#, c-format
+msgid "%u B"
+msgstr ""
+
 #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
 msgid "XOpenDisplay() failed"
 msgstr "XOpenDisplay() fehlgeschlagen"
@@ -2042,17 +2075,17 @@ msgstr "Terminieren des PulseAudio-Daemon fehlgeschlagen."
 msgid "Daemon not responding."
 msgstr "Daemon antwortet nicht."
 
-#: ../src/utils/pacmd.c:112
+#: ../src/utils/pacmd.c:144
 #, c-format
 msgid "select(): %s"
 msgstr "select(): %s"
 
-#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140
+#: ../src/utils/pacmd.c:154 ../src/utils/pacmd.c:171
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167
+#: ../src/utils/pacmd.c:187 ../src/utils/pacmd.c:201
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
diff --git a/po/el.po b/po/el.po
index 6fb4658..73e40ec 100644
--- a/po/el.po
+++ b/po/el.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: el\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-01-28 04:30+0100\n"
+"POT-Creation-Date: 2009-02-04 21:48+0100\n"
 "PO-Revision-Date: 2008-08-22 19:40+0300\n"
 "Last-Translator: Dimitris Glezos <dimitris at glezos.com>\n"
 "Language-Team: Greek <fedora-trans-el at redhat.com>\n"
@@ -645,7 +645,7 @@ msgstr ""
 msgid "Limited capabilities successfully to CAP_SYS_NICE."
 msgstr ""
 
-#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:742
+#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:804
 msgid "Mono"
 msgstr ""
 
@@ -849,33 +849,33 @@ msgstr ""
 msgid "Top Rear Right"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:473 ../src/pulse/sample.c:152
-#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:189
-#: ../src/pulse/volume.c:209 ../src/pulse/volume.c:239
+#: ../src/pulse/channelmap.c:476 ../src/pulse/sample.c:167
+#: ../src/pulse/volume.c:170 ../src/pulse/volume.c:196
+#: ../src/pulse/volume.c:216 ../src/pulse/volume.c:246
 msgid "(invalid)"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:746
+#: ../src/pulse/channelmap.c:808
 msgid "Stereo"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:751
+#: ../src/pulse/channelmap.c:813
 msgid "Surround 4.0"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:757
+#: ../src/pulse/channelmap.c:819
 msgid "Surround 4.1"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:763
+#: ../src/pulse/channelmap.c:825
 msgid "Surround 5.0"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:769
+#: ../src/pulse/channelmap.c:831
 msgid "Surround 5.1"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:776
+#: ../src/pulse/channelmap.c:838
 msgid "Surround 7.1"
 msgstr ""
 
@@ -967,6 +967,39 @@ msgstr ""
 msgid "No such extension"
 msgstr ""
 
+#: ../src/pulse/error.c:65
+msgid "Obsolete functionality"
+msgstr ""
+
+#: ../src/pulse/error.c:66
+msgid "Missing implementation"
+msgstr ""
+
+#: ../src/pulse/sample.c:169
+#, c-format
+msgid "%s %uch %uHz"
+msgstr ""
+
+#: ../src/pulse/sample.c:181
+#, c-format
+msgid "%0.1f GiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:183
+#, c-format
+msgid "%0.1f MiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:185
+#, c-format
+msgid "%0.1f KiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:187
+#, c-format
+msgid "%u B"
+msgstr ""
+
 #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
 msgid "XOpenDisplay() failed"
 msgstr ""
@@ -1793,17 +1826,17 @@ msgstr ""
 msgid "Daemon not responding."
 msgstr ""
 
-#: ../src/utils/pacmd.c:112
+#: ../src/utils/pacmd.c:144
 #, c-format
 msgid "select(): %s"
 msgstr ""
 
-#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140
+#: ../src/utils/pacmd.c:154 ../src/utils/pacmd.c:171
 #, c-format
 msgid "read(): %s"
 msgstr ""
 
-#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167
+#: ../src/utils/pacmd.c:187 ../src/utils/pacmd.c:201
 #, c-format
 msgid "write(): %s"
 msgstr ""
diff --git a/po/es.po b/po/es.po
index df5e0ca..feb8c9b 100644
--- a/po/es.po
+++ b/po/es.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PulseAudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-01-28 04:30+0100\n"
+"POT-Creation-Date: 2009-02-04 21:48+0100\n"
 "PO-Revision-Date: 2009-01-16 09:25-0300\n"
 "Last-Translator: daniel cabrera <h.daniel.cabrera at gmail.com>\n"
 "Language-Team: Spanish <fedora-trans-es at redhat.com>\n"
@@ -755,7 +755,7 @@ msgstr "Abandonando privilegios de root."
 msgid "Limited capabilities successfully to CAP_SYS_NICE."
 msgstr "Capacidades limitadas con éxito para CAP_SYS_NICE-"
 
-#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:742
+#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:804
 msgid "Mono"
 msgstr "Mono"
 
@@ -959,33 +959,33 @@ msgstr "Posterior izquierdo superior"
 msgid "Top Rear Right"
 msgstr "Posterior derecho superior"
 
-#: ../src/pulse/channelmap.c:473 ../src/pulse/sample.c:152
-#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:189
-#: ../src/pulse/volume.c:209 ../src/pulse/volume.c:239
+#: ../src/pulse/channelmap.c:476 ../src/pulse/sample.c:167
+#: ../src/pulse/volume.c:170 ../src/pulse/volume.c:196
+#: ../src/pulse/volume.c:216 ../src/pulse/volume.c:246
 msgid "(invalid)"
 msgstr "(inválido)"
 
-#: ../src/pulse/channelmap.c:746
+#: ../src/pulse/channelmap.c:808
 msgid "Stereo"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:751
+#: ../src/pulse/channelmap.c:813
 msgid "Surround 4.0"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:757
+#: ../src/pulse/channelmap.c:819
 msgid "Surround 4.1"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:763
+#: ../src/pulse/channelmap.c:825
 msgid "Surround 5.0"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:769
+#: ../src/pulse/channelmap.c:831
 msgid "Surround 5.1"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:776
+#: ../src/pulse/channelmap.c:838
 msgid "Surround 7.1"
 msgstr ""
 
@@ -1077,6 +1077,39 @@ msgstr "Código de error desconocido"
 msgid "No such extension"
 msgstr "No existe tal extensión"
 
+#: ../src/pulse/error.c:65
+msgid "Obsolete functionality"
+msgstr ""
+
+#: ../src/pulse/error.c:66
+msgid "Missing implementation"
+msgstr ""
+
+#: ../src/pulse/sample.c:169
+#, c-format
+msgid "%s %uch %uHz"
+msgstr ""
+
+#: ../src/pulse/sample.c:181
+#, c-format
+msgid "%0.1f GiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:183
+#, c-format
+msgid "%0.1f MiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:185
+#, c-format
+msgid "%0.1f KiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:187
+#, c-format
+msgid "%u B"
+msgstr ""
+
 #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
 msgid "XOpenDisplay() failed"
 msgstr "XOpenDisplay() falló"
@@ -2089,17 +2122,17 @@ msgstr "Error al intentar detener el demonio de PulseAudio."
 msgid "Daemon not responding."
 msgstr "El demonio no responde."
 
-#: ../src/utils/pacmd.c:112
+#: ../src/utils/pacmd.c:144
 #, c-format
 msgid "select(): %s"
 msgstr "select(): %s"
 
-#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140
+#: ../src/utils/pacmd.c:154 ../src/utils/pacmd.c:171
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167
+#: ../src/utils/pacmd.c:187 ../src/utils/pacmd.c:201
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
diff --git a/po/fi.po b/po/fi.po
index 37d9686..bb60eef 100644
--- a/po/fi.po
+++ b/po/fi.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: git trunk\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-01-28 04:30+0100\n"
+"POT-Creation-Date: 2009-02-04 21:48+0100\n"
 "PO-Revision-Date: 2008-12-01 18:40+0200\n"
 "Last-Translator: Timo Jyrinki <timo.jyrinki at iki.fi>\n"
 "Language-Team: Finnish <laatu at lokalisointi.org>\n"
@@ -652,7 +652,7 @@ msgstr "Pudotetaan pääkäyttäjän oikeudet."
 msgid "Limited capabilities successfully to CAP_SYS_NICE."
 msgstr ""
 
-#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:742
+#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:804
 msgid "Mono"
 msgstr "Mono"
 
@@ -856,33 +856,33 @@ msgstr "Vasen ylä taka"
 msgid "Top Rear Right"
 msgstr "Oikea ylä taka"
 
-#: ../src/pulse/channelmap.c:473 ../src/pulse/sample.c:152
-#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:189
-#: ../src/pulse/volume.c:209 ../src/pulse/volume.c:239
+#: ../src/pulse/channelmap.c:476 ../src/pulse/sample.c:167
+#: ../src/pulse/volume.c:170 ../src/pulse/volume.c:196
+#: ../src/pulse/volume.c:216 ../src/pulse/volume.c:246
 msgid "(invalid)"
 msgstr "(virheellinen)"
 
-#: ../src/pulse/channelmap.c:746
+#: ../src/pulse/channelmap.c:808
 msgid "Stereo"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:751
+#: ../src/pulse/channelmap.c:813
 msgid "Surround 4.0"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:757
+#: ../src/pulse/channelmap.c:819
 msgid "Surround 4.1"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:763
+#: ../src/pulse/channelmap.c:825
 msgid "Surround 5.0"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:769
+#: ../src/pulse/channelmap.c:831
 msgid "Surround 5.1"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:776
+#: ../src/pulse/channelmap.c:838
 msgid "Surround 7.1"
 msgstr ""
 
@@ -974,6 +974,39 @@ msgstr "Tuntematon virhekoodi"
 msgid "No such extension"
 msgstr "Ei kyseisenlaista laajennusta"
 
+#: ../src/pulse/error.c:65
+msgid "Obsolete functionality"
+msgstr ""
+
+#: ../src/pulse/error.c:66
+msgid "Missing implementation"
+msgstr ""
+
+#: ../src/pulse/sample.c:169
+#, c-format
+msgid "%s %uch %uHz"
+msgstr ""
+
+#: ../src/pulse/sample.c:181
+#, c-format
+msgid "%0.1f GiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:183
+#, c-format
+msgid "%0.1f MiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:185
+#, c-format
+msgid "%0.1f KiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:187
+#, c-format
+msgid "%u B"
+msgstr ""
+
 #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
 msgid "XOpenDisplay() failed"
 msgstr "XOpenDisplay() epäonnistui"
@@ -1883,17 +1916,17 @@ msgstr "PulseAudio-taustaprosessin lopettaminen epäonnistui."
 msgid "Daemon not responding."
 msgstr "Taustaprosessi ei vastaa."
 
-#: ../src/utils/pacmd.c:112
+#: ../src/utils/pacmd.c:144
 #, c-format
 msgid "select(): %s"
 msgstr ""
 
-#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140
+#: ../src/utils/pacmd.c:154 ../src/utils/pacmd.c:171
 #, c-format
 msgid "read(): %s"
 msgstr ""
 
-#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167
+#: ../src/utils/pacmd.c:187 ../src/utils/pacmd.c:201
 #, c-format
 msgid "write(): %s"
 msgstr ""
diff --git a/po/fr.po b/po/fr.po
index 9bf0ece..824e82d 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -10,7 +10,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio trunk\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-01-28 04:30+0100\n"
+"POT-Creation-Date: 2009-02-04 21:48+0100\n"
 "PO-Revision-Date: 2008-10-18 20:34+0200\n"
 "Last-Translator: Pablo Martin-Gomez <pablo.martin-gomez at laposte.net>\n"
 "Language-Team: Français <fedora-trans-fr at redhat.com>\n"
@@ -759,7 +759,7 @@ msgstr "Abandon des permissions root."
 msgid "Limited capabilities successfully to CAP_SYS_NICE."
 msgstr "Limitation des capacités à CAP_SYS_NICE réussie."
 
-#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:742
+#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:804
 msgid "Mono"
 msgstr "Mono"
 
@@ -963,33 +963,33 @@ msgstr "Arrière gauche haut"
 msgid "Top Rear Right"
 msgstr "Arrière droit haut"
 
-#: ../src/pulse/channelmap.c:473 ../src/pulse/sample.c:152
-#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:189
-#: ../src/pulse/volume.c:209 ../src/pulse/volume.c:239
+#: ../src/pulse/channelmap.c:476 ../src/pulse/sample.c:167
+#: ../src/pulse/volume.c:170 ../src/pulse/volume.c:196
+#: ../src/pulse/volume.c:216 ../src/pulse/volume.c:246
 msgid "(invalid)"
 msgstr "(invalide)"
 
-#: ../src/pulse/channelmap.c:746
+#: ../src/pulse/channelmap.c:808
 msgid "Stereo"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:751
+#: ../src/pulse/channelmap.c:813
 msgid "Surround 4.0"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:757
+#: ../src/pulse/channelmap.c:819
 msgid "Surround 4.1"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:763
+#: ../src/pulse/channelmap.c:825
 msgid "Surround 5.0"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:769
+#: ../src/pulse/channelmap.c:831
 msgid "Surround 5.1"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:776
+#: ../src/pulse/channelmap.c:838
 msgid "Surround 7.1"
 msgstr ""
 
@@ -1081,6 +1081,39 @@ msgstr "Code d'erreur inconnu"
 msgid "No such extension"
 msgstr "Aucune extension de ce type"
 
+#: ../src/pulse/error.c:65
+msgid "Obsolete functionality"
+msgstr ""
+
+#: ../src/pulse/error.c:66
+msgid "Missing implementation"
+msgstr ""
+
+#: ../src/pulse/sample.c:169
+#, c-format
+msgid "%s %uch %uHz"
+msgstr ""
+
+#: ../src/pulse/sample.c:181
+#, c-format
+msgid "%0.1f GiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:183
+#, c-format
+msgid "%0.1f MiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:185
+#, c-format
+msgid "%0.1f KiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:187
+#, c-format
+msgid "%u B"
+msgstr ""
+
 #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
 msgid "XOpenDisplay() failed"
 msgstr "Échec de XOpenDisplay()"
@@ -2112,17 +2145,17 @@ msgstr "Impossible de tuer le démon PulseAudio."
 msgid "Daemon not responding."
 msgstr "Le démon ne répond pas."
 
-#: ../src/utils/pacmd.c:112
+#: ../src/utils/pacmd.c:144
 #, c-format
 msgid "select(): %s"
 msgstr "select() : %s"
 
-#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140
+#: ../src/utils/pacmd.c:154 ../src/utils/pacmd.c:171
 #, c-format
 msgid "read(): %s"
 msgstr "read() : %s"
 
-#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167
+#: ../src/utils/pacmd.c:187 ../src/utils/pacmd.c:201
 #, c-format
 msgid "write(): %s"
 msgstr "write() : %s"
diff --git a/po/pl.po b/po/pl.po
index d381388..b6f6587 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -5,7 +5,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pl\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-01-28 04:30+0100\n"
+"POT-Creation-Date: 2009-02-04 21:48+0100\n"
 "PO-Revision-Date: 2009-01-09 22:17+0100\n"
 "Last-Translator: Piotr DrÄ…g <piotrdrag at gmail.com>\n"
 "Language-Team: Polish <pl at li.org>\n"
@@ -740,7 +740,7 @@ msgstr "Porzucanie uprawnień roota."
 msgid "Limited capabilities successfully to CAP_SYS_NICE."
 msgstr "Pomyślnie ograniczono możliwości do CAP_SYS_NICE."
 
-#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:742
+#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:804
 msgid "Mono"
 msgstr "Mono"
 
@@ -944,33 +944,33 @@ msgstr "Górny tylny lewy"
 msgid "Top Rear Right"
 msgstr "Górny tylny prawy"
 
-#: ../src/pulse/channelmap.c:473 ../src/pulse/sample.c:152
-#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:189
-#: ../src/pulse/volume.c:209 ../src/pulse/volume.c:239
+#: ../src/pulse/channelmap.c:476 ../src/pulse/sample.c:167
+#: ../src/pulse/volume.c:170 ../src/pulse/volume.c:196
+#: ../src/pulse/volume.c:216 ../src/pulse/volume.c:246
 msgid "(invalid)"
 msgstr "(nieprawidłowe)"
 
-#: ../src/pulse/channelmap.c:746
+#: ../src/pulse/channelmap.c:808
 msgid "Stereo"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:751
+#: ../src/pulse/channelmap.c:813
 msgid "Surround 4.0"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:757
+#: ../src/pulse/channelmap.c:819
 msgid "Surround 4.1"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:763
+#: ../src/pulse/channelmap.c:825
 msgid "Surround 5.0"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:769
+#: ../src/pulse/channelmap.c:831
 msgid "Surround 5.1"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:776
+#: ../src/pulse/channelmap.c:838
 msgid "Surround 7.1"
 msgstr ""
 
@@ -1062,6 +1062,39 @@ msgstr "Nieznany kod błędu"
 msgid "No such extension"
 msgstr "Nie ma takiego rozszerzenia"
 
+#: ../src/pulse/error.c:65
+msgid "Obsolete functionality"
+msgstr ""
+
+#: ../src/pulse/error.c:66
+msgid "Missing implementation"
+msgstr ""
+
+#: ../src/pulse/sample.c:169
+#, c-format
+msgid "%s %uch %uHz"
+msgstr ""
+
+#: ../src/pulse/sample.c:181
+#, c-format
+msgid "%0.1f GiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:183
+#, c-format
+msgid "%0.1f MiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:185
+#, c-format
+msgid "%0.1f KiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:187
+#, c-format
+msgid "%u B"
+msgstr ""
+
 #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
 msgid "XOpenDisplay() failed"
 msgstr "XOpenDisplay() nie powiodło się"
@@ -2066,17 +2099,17 @@ msgstr "Zniszczenie demona PulseAudio nie powiodło się."
 msgid "Daemon not responding."
 msgstr "Demon nie odpowiada."
 
-#: ../src/utils/pacmd.c:112
+#: ../src/utils/pacmd.c:144
 #, c-format
 msgid "select(): %s"
 msgstr "select(): %s"
 
-#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140
+#: ../src/utils/pacmd.c:154 ../src/utils/pacmd.c:171
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167
+#: ../src/utils/pacmd.c:187 ../src/utils/pacmd.c:201
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
diff --git a/po/pt_BR.po b/po/pt_BR.po
index 3101625..b285288 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-01-28 04:30+0100\n"
+"POT-Creation-Date: 2009-02-04 21:48+0100\n"
 "PO-Revision-Date: 2008-11-21 01:21-0300\n"
 "Last-Translator: Henrique (LonelySpooky) Junior <lspooky at fedoraproject.org>\n"
 "Language-Team: Brazilian-Portuguese <fedora-trans-pt_br at redhat.com>\n"
@@ -743,7 +743,7 @@ msgstr "Descartando os privilégios de root."
 msgid "Limited capabilities successfully to CAP_SYS_NICE."
 msgstr "As capacidades foram limitadas com sucesso para CAP_SYS_NICE."
 
-#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:742
+#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:804
 msgid "Mono"
 msgstr "Mono"
 
@@ -947,33 +947,33 @@ msgstr "Posterior Superior Esquerdo"
 msgid "Top Rear Right"
 msgstr "Posterior Superior Direito"
 
-#: ../src/pulse/channelmap.c:473 ../src/pulse/sample.c:152
-#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:189
-#: ../src/pulse/volume.c:209 ../src/pulse/volume.c:239
+#: ../src/pulse/channelmap.c:476 ../src/pulse/sample.c:167
+#: ../src/pulse/volume.c:170 ../src/pulse/volume.c:196
+#: ../src/pulse/volume.c:216 ../src/pulse/volume.c:246
 msgid "(invalid)"
 msgstr "(Inválido)"
 
-#: ../src/pulse/channelmap.c:746
+#: ../src/pulse/channelmap.c:808
 msgid "Stereo"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:751
+#: ../src/pulse/channelmap.c:813
 msgid "Surround 4.0"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:757
+#: ../src/pulse/channelmap.c:819
 msgid "Surround 4.1"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:763
+#: ../src/pulse/channelmap.c:825
 msgid "Surround 5.0"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:769
+#: ../src/pulse/channelmap.c:831
 msgid "Surround 5.1"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:776
+#: ../src/pulse/channelmap.c:838
 msgid "Surround 7.1"
 msgstr ""
 
@@ -1065,6 +1065,39 @@ msgstr "Código de erro desconhecido"
 msgid "No such extension"
 msgstr "Não existe tal extensão"
 
+#: ../src/pulse/error.c:65
+msgid "Obsolete functionality"
+msgstr ""
+
+#: ../src/pulse/error.c:66
+msgid "Missing implementation"
+msgstr ""
+
+#: ../src/pulse/sample.c:169
+#, c-format
+msgid "%s %uch %uHz"
+msgstr ""
+
+#: ../src/pulse/sample.c:181
+#, c-format
+msgid "%0.1f GiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:183
+#, c-format
+msgid "%0.1f MiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:185
+#, c-format
+msgid "%0.1f KiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:187
+#, c-format
+msgid "%u B"
+msgstr ""
+
 #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
 msgid "XOpenDisplay() failed"
 msgstr "XOpenDisplay() falhou"
@@ -2068,17 +2101,17 @@ msgstr "Falha em cancelar o daemon do PulseAudio."
 msgid "Daemon not responding."
 msgstr "Daemon não responde."
 
-#: ../src/utils/pacmd.c:112
+#: ../src/utils/pacmd.c:144
 #, c-format
 msgid "select(): %s"
 msgstr "select(): %s"
 
-#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140
+#: ../src/utils/pacmd.c:154 ../src/utils/pacmd.c:171
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167
+#: ../src/utils/pacmd.c:187 ../src/utils/pacmd.c:201
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
diff --git a/po/sv.po b/po/sv.po
index 59644c8..0493243 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-01-28 04:30+0100\n"
+"POT-Creation-Date: 2009-02-04 21:48+0100\n"
 "PO-Revision-Date: 2008-09-05 18:24+0100\n"
 "Last-Translator: Daniel Nylander <po at danielnylander.se>\n"
 "Language-Team: Swedish <tp-sv at listor.tp-sv.se>\n"
@@ -649,7 +649,7 @@ msgstr "Släpper root-behörighet."
 msgid "Limited capabilities successfully to CAP_SYS_NICE."
 msgstr ""
 
-#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:742
+#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:804
 msgid "Mono"
 msgstr "Mono"
 
@@ -853,34 +853,34 @@ msgstr ""
 msgid "Top Rear Right"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:473 ../src/pulse/sample.c:152
-#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:189
-#: ../src/pulse/volume.c:209 ../src/pulse/volume.c:239
+#: ../src/pulse/channelmap.c:476 ../src/pulse/sample.c:167
+#: ../src/pulse/volume.c:170 ../src/pulse/volume.c:196
+#: ../src/pulse/volume.c:216 ../src/pulse/volume.c:246
 #, fuzzy
 msgid "(invalid)"
 msgstr "Ogiltig"
 
-#: ../src/pulse/channelmap.c:746
+#: ../src/pulse/channelmap.c:808
 msgid "Stereo"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:751
+#: ../src/pulse/channelmap.c:813
 msgid "Surround 4.0"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:757
+#: ../src/pulse/channelmap.c:819
 msgid "Surround 4.1"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:763
+#: ../src/pulse/channelmap.c:825
 msgid "Surround 5.0"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:769
+#: ../src/pulse/channelmap.c:831
 msgid "Surround 5.1"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:776
+#: ../src/pulse/channelmap.c:838
 msgid "Surround 7.1"
 msgstr ""
 
@@ -972,6 +972,39 @@ msgstr "Okänd felkod"
 msgid "No such extension"
 msgstr ""
 
+#: ../src/pulse/error.c:65
+msgid "Obsolete functionality"
+msgstr ""
+
+#: ../src/pulse/error.c:66
+msgid "Missing implementation"
+msgstr ""
+
+#: ../src/pulse/sample.c:169
+#, c-format
+msgid "%s %uch %uHz"
+msgstr ""
+
+#: ../src/pulse/sample.c:181
+#, c-format
+msgid "%0.1f GiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:183
+#, c-format
+msgid "%0.1f MiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:185
+#, c-format
+msgid "%0.1f KiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:187
+#, c-format
+msgid "%u B"
+msgstr ""
+
 #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
 msgid "XOpenDisplay() failed"
 msgstr "XOpenDisplay() misslyckades"
@@ -1804,17 +1837,17 @@ msgstr ""
 msgid "Daemon not responding."
 msgstr ""
 
-#: ../src/utils/pacmd.c:112
+#: ../src/utils/pacmd.c:144
 #, c-format
 msgid "select(): %s"
 msgstr "select(): %s"
 
-#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140
+#: ../src/utils/pacmd.c:154 ../src/utils/pacmd.c:171
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167
+#: ../src/utils/pacmd.c:187 ../src/utils/pacmd.c:201
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
diff --git a/po/zh_CN.po b/po/zh_CN.po
index 1045b60..0ec230a 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -3,28 +3,34 @@
 # This file is distributed under the same license as the  package.
 # 闫丰刚 (sainry)<sainry at gmail.com> 2008
 # 闫丰刚 <sainry at gmail.com>, 2009. 
-# 
-# 
+#
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: PulseAudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-11-26 01:41+0000\n"
+"POT-Creation-Date: 2009-02-04 21:48+0100\n"
 "PO-Revision-Date: 2009-01-24 12:47+0800\n"
 "Last-Translator: 王泽国 <zak.zeguo.wang at gmail.com>\n"
 "Language-Team: Chinese/Simplified\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit"
+"Content-Transfer-Encoding: 8bit\n"
 
-#: ../src/daemon/ltdl-bind-now.c:177 ../src/daemon/ltdl-bind-now.c:197
-msgid "Failed to add bind-now-loader."
-msgstr "添加bind-now-loader失败。"
+#: ../src/daemon/ltdl-bind-now.c:124
+#, fuzzy
+msgid "Failed to find original lt_dlopen loader."
+msgstr "查找原始dlopen加载器失败。"
 
-#: ../src/daemon/ltdl-bind-now.c:184
-msgid "Failed to find original dlopen loader."
+#: ../src/daemon/ltdl-bind-now.c:129
+#, fuzzy
+msgid "Failed to allocate new dl loader."
 msgstr "查找原始dlopen加载器失败。"
 
+#: ../src/daemon/ltdl-bind-now.c:142
+msgid "Failed to add bind-now-loader."
+msgstr "添加bind-now-loader失败。"
+
 #: ../src/daemon/polkit.c:55
 #, c-format
 msgid "Cannot connect to system bus: %s"
@@ -146,267 +152,256 @@ msgstr "此平台不支持system-wide模式。"
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) 失败:%s"
 
-#: ../src/daemon/main.c:425
+#: ../src/daemon/main.c:429
 msgid "Failed to parse command line."
 msgstr "分析命令行失败。"
 
-#: ../src/daemon/main.c:441
+#: ../src/daemon/main.c:451
 #, c-format
 msgid "We're in the group '%s', allowing high-priority scheduling."
 msgstr "我们在'%s'组中,允许高优先级调度。"
 
-#: ../src/daemon/main.c:448
+#: ../src/daemon/main.c:458
 #, c-format
 msgid "We're in the group '%s', allowing real-time scheduling."
 msgstr "我们在'%s'组中,允许实时调度。"
 
-#: ../src/daemon/main.c:456
+#: ../src/daemon/main.c:466
 msgid "PolicyKit grants us acquire-high-priority privilege."
 msgstr "PolicyKit授予我们“获取高优先级”权限。"
 
-#: ../src/daemon/main.c:459
+#: ../src/daemon/main.c:469
 msgid "PolicyKit refuses acquire-high-priority privilege."
 msgstr "PolicyKit拒绝“获取高优先级”权限。"
 
-#: ../src/daemon/main.c:464
+#: ../src/daemon/main.c:474
 msgid "PolicyKit grants us acquire-real-time privilege."
 msgstr "PolicyKit授予我们“获取实时”权限。"
 
-#: ../src/daemon/main.c:467
+#: ../src/daemon/main.c:477
 msgid "PolicyKit refuses acquire-real-time privilege."
 msgstr "PolicyKit拒绝我们“获取实时”权限。"
 
-#: ../src/daemon/main.c:479
+#: ../src/daemon/main.c:506
+#, fuzzy
 msgid ""
-"Called SUID root and real-time/high-priority scheduling was requested in the "
-"configuration. However, we lack the necessary priviliges:\n"
+"Called SUID root and real-time and/or high-priority scheduling was requested "
+"in the configuration. However, we lack the necessary privileges:\n"
 "We are not in group '"
-msgstr "此配置需要调用SUID root和实时/高优先级调度。但是我们没有所需的权限:\n"
+msgstr ""
+"此配置需要调用SUID root和实时/高优先级调度。但是我们没有所需的权限:\n"
 "我们不属该组"
 
-#: ../src/daemon/main.c:480
-msgid ""
-"' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n"
-"For enabling real-time scheduling please acquire the appropriate PolicyKit "
-"priviliges, or become a member of '"
-msgstr "而且PolicyKit拒绝授予我们权限。再次取消SUID。\n"
-"要启用实时调度,请取得适应的PolicyKit权限,或者成为组成员'"
-
-#: ../src/daemon/main.c:481
-msgid ""
-"', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user."
-msgstr "',或者提高本用户的RLIMIT_NICE/RLIMIT_RTPRIO资源上限。"
-
-#: ../src/daemon/main.c:497
+#: ../src/daemon/main.c:530
 msgid ""
 "High-priority scheduling enabled in configuration but not allowed by policy."
 msgstr "配置中已启用高优先级调度,但策略未允许。"
 
-#: ../src/daemon/main.c:522
+#: ../src/daemon/main.c:559
 msgid "Successfully increased RLIMIT_RTPRIO"
 msgstr "提高RLIMIT_RTPRIO成功。"
 
-#: ../src/daemon/main.c:525
+#: ../src/daemon/main.c:562
 #, c-format
 msgid "RLIMIT_RTPRIO failed: %s"
 msgstr "RLIMIT_RTPRIO失败:%s"
 
-#: ../src/daemon/main.c:532
+#: ../src/daemon/main.c:569
 msgid "Giving up CAP_NICE"
 msgstr "正在放弃CAP_NICE"
 
-#: ../src/daemon/main.c:539
+#: ../src/daemon/main.c:576
 msgid ""
 "Real-time scheduling enabled in configuration but not allowed by policy."
 msgstr "配置中已启用实时调度,但策略未允许。"
 
-#: ../src/daemon/main.c:597
+#: ../src/daemon/main.c:637
 msgid "Daemon not running"
 msgstr "后台程序没有运行"
 
-#: ../src/daemon/main.c:599
+#: ../src/daemon/main.c:639
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "后台程序正在运行,PID %u"
 
-#: ../src/daemon/main.c:609
+#: ../src/daemon/main.c:649
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "杀死后台程序失败:%s"
 
-#: ../src/daemon/main.c:627
+#: ../src/daemon/main.c:667
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
 msgstr "不应以root身份运行本程序(除非指定 --system)。"
 
-#: ../src/daemon/main.c:629
-msgid "Root priviliges required."
+#: ../src/daemon/main.c:669
+#, fuzzy
+msgid "Root privileges required."
 msgstr "需要root权限。"
 
-#: ../src/daemon/main.c:634
+#: ../src/daemon/main.c:674
 msgid "--start not supported for system instances."
 msgstr "系统实例不支持 --start。"
 
-#: ../src/daemon/main.c:639
+#: ../src/daemon/main.c:679
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr "正在以系统模式运行,但是 --disallow-exit 未设定!"
 
-#: ../src/daemon/main.c:642
+#: ../src/daemon/main.c:682
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr "正在以系统模式运行,但是 --disallow-module-loading 未设定!"
 
-#: ../src/daemon/main.c:645
+#: ../src/daemon/main.c:685
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "正在以系统模式运行,强制禁用SHM模式!"
 
-#: ../src/daemon/main.c:650
+#: ../src/daemon/main.c:690
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr "正在以系统模式运行,强制禁用退出空闲时间!"
 
-#: ../src/daemon/main.c:677
+#: ../src/daemon/main.c:717
 msgid "Failed to acquire stdio."
 msgstr "获取stdio失败。"
 
-#: ../src/daemon/main.c:683
+#: ../src/daemon/main.c:723
 #, c-format
 msgid "pipe failed: %s"
 msgstr "管道失败:%s"
 
-#: ../src/daemon/main.c:688
+#: ../src/daemon/main.c:728
 #, c-format
 msgid "fork() failed: %s"
 msgstr "fork()失败:%s"
 
-#: ../src/daemon/main.c:702
+#: ../src/daemon/main.c:742
 #, c-format
 msgid "read() failed: %s"
 msgstr "read()失败:%s"
 
-#: ../src/daemon/main.c:708
+#: ../src/daemon/main.c:748
 msgid "Daemon startup failed."
 msgstr "后台程序启动失败。"
 
-#: ../src/daemon/main.c:710
+#: ../src/daemon/main.c:750
 msgid "Daemon startup successful."
 msgstr "后台程序启动成功。"
 
-#: ../src/daemon/main.c:780
+#: ../src/daemon/main.c:820
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "这是 PulseAudio %s"
 
-#: ../src/daemon/main.c:781
+#: ../src/daemon/main.c:821
 #, c-format
 msgid "Compilation host: %s"
 msgstr "编译主机:%s"
 
-#: ../src/daemon/main.c:782
+#: ../src/daemon/main.c:822
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "编译CFLAGS:%s"
 
-#: ../src/daemon/main.c:785
+#: ../src/daemon/main.c:825
 #, c-format
 msgid "Running on host: %s"
 msgstr "正在主机上运行:%s"
 
-#: ../src/daemon/main.c:788
+#: ../src/daemon/main.c:828
+#, c-format
+msgid "Found %u CPUs."
+msgstr ""
+
+#: ../src/daemon/main.c:830
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "页面大小为%lu字节"
 
-#: ../src/daemon/main.c:791
+#: ../src/daemon/main.c:833
 msgid "Compiled with Valgrind support: yes"
 msgstr "编译启用Valgrind支持:是"
 
-#: ../src/daemon/main.c:793
+#: ../src/daemon/main.c:835
 msgid "Compiled with Valgrind support: no"
 msgstr "编译启用Valgrind支持:否"
 
-#: ../src/daemon/main.c:796
+#: ../src/daemon/main.c:838
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "正在以valgrind模式运行:%s"
 
-#: ../src/daemon/main.c:799
+#: ../src/daemon/main.c:841
 msgid "Optimized build: yes"
 msgstr "优化生成:是"
 
-#: ../src/daemon/main.c:801
+#: ../src/daemon/main.c:843
 msgid "Optimized build: no"
 msgstr "优化生成:否"
 
-#: ../src/daemon/main.c:805
+#: ../src/daemon/main.c:847
 msgid "Failed to get machine ID"
 msgstr "获取machine ID失败"
 
-#: ../src/daemon/main.c:808
+#: ../src/daemon/main.c:850
 #, c-format
 msgid "Machine ID is %s."
 msgstr "machine ID是%s。"
 
-#: ../src/daemon/main.c:813
+#: ../src/daemon/main.c:855
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "正在使用运行时文件夹%s。"
 
-#: ../src/daemon/main.c:818
+#: ../src/daemon/main.c:860
 #, c-format
 msgid "Using state directory %s."
 msgstr "正在使用状态文件夹%s。"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:863
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "正在以系统模式运行:%s"
 
-#: ../src/daemon/main.c:836
+#: ../src/daemon/main.c:878
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create()失败。"
 
-#: ../src/daemon/main.c:848
+#: ../src/daemon/main.c:890
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "新鲜的高分辨率计时器开锅了!吃个饱!"
 
-#: ../src/daemon/main.c:850
+#: ../src/daemon/main.c:892
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
-msgstr ""
-"老兄,你的内核真臭!现在流行的是启用了高分辩率计分器的Linux!"
+msgstr "老兄,你的内核真臭!现在流行的是启用了高分辩率计分器的Linux!"
 
-#: ../src/daemon/main.c:860
+#: ../src/daemon/main.c:904
 msgid "pa_core_new() failed."
 msgstr "pa_core_new()失败。"
 
-#: ../src/daemon/main.c:921
+#: ../src/daemon/main.c:965
 msgid "Failed to initialize daemon."
 msgstr "后台程序初始化失败。"
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:970
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "后台程序启动未加载任何模块,拒绝工作。"
 
-#: ../src/daemon/main.c:931
-#, c-format
-msgid "Default sink name (%s) does not exist in name register."
-msgstr "名称登记表中不存在默认的音频出口名(%s)。"
-
-#: ../src/daemon/main.c:944
+#: ../src/daemon/main.c:983
 msgid "Daemon startup complete."
 msgstr "后台程序启动完成。"
 
-#: ../src/daemon/main.c:950
+#: ../src/daemon/main.c:989
 msgid "Daemon shutdown initiated."
 msgstr "开始关闭后台程序。"
 
-#: ../src/daemon/main.c:971
+#: ../src/daemon/main.c:1010
 msgid "Daemon terminated."
 msgstr "后台程序已终止。"
 
-#: ../src/daemon/cmdline.c:117
-#, c-format
+#: ../src/daemon/cmdline.c:121
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -421,7 +416,8 @@ msgid ""
 "      --start                           Start the daemon if it is not "
 "running\n"
 "  -k  --kill                            Kill a running daemon\n"
-"      --check                           Check for a running daemon\n"
+"      --check                           Check for a running daemon (only "
+"returns exit code)\n"
 "\n"
 "OPTIONS:\n"
 "      --system[=BOOL]                   Run as system-wide instance\n"
@@ -451,6 +447,10 @@ msgid ""
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
 "      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-meta[=BOOL]                 Include code location in log "
+"messages\n"
+"      --log-time[=BOOL]                 Include timestamps in log messages\n"
+"      --log-backtrace=FRAMES            Include a backtrace in log messages\n"
 "  -p, --dl-search-path=PATH             Set the search path for dynamic "
 "shared\n"
 "                                        objects (plugins)\n"
@@ -526,58 +526,70 @@ msgstr ""
 "\n"
 "  -n                                    不加载默认的脚本文件\n"
 
-#: ../src/daemon/cmdline.c:245
+#: ../src/daemon/cmdline.c:252
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize 期待布尔参数"
 
-#: ../src/daemon/cmdline.c:252
+#: ../src/daemon/cmdline.c:259
 msgid "--fail expects boolean argument"
 msgstr "--fail 期待布尔参数"
 
-#: ../src/daemon/cmdline.c:262
+#: ../src/daemon/cmdline.c:269
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
-msgstr "--log-level 期待日志级别参数(可以是数字0~4或者debug,info,notice,warn,error中的一个)"
+msgstr ""
+"--log-level 期待日志级别参数(可以是数字0~4或者debug,info,notice,warn,"
+"error中的一个)"
 
-#: ../src/daemon/cmdline.c:274
+#: ../src/daemon/cmdline.c:281
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority 期待布尔参数"
 
-#: ../src/daemon/cmdline.c:281
+#: ../src/daemon/cmdline.c:288
 msgid "--realtime expects boolean argument"
 msgstr "--realtime 期待布尔参数"
 
-#: ../src/daemon/cmdline.c:288
+#: ../src/daemon/cmdline.c:295
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading 期待布尔参数"
 
-#: ../src/daemon/cmdline.c:295
+#: ../src/daemon/cmdline.c:302
 msgid "--disallow-exit boolean argument"
 msgstr "--disallow-exit 布尔参数"
 
-#: ../src/daemon/cmdline.c:302
+#: ../src/daemon/cmdline.c:309
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file 期待布尔参数"
 
-#: ../src/daemon/cmdline.c:319
+#: ../src/daemon/cmdline.c:326
 msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
 msgstr "无效的日志目标:从syslog,stderr和auto中选取一个"
 
-#: ../src/daemon/cmdline.c:338
+#: ../src/daemon/cmdline.c:333
+#, fuzzy
+msgid "--log-time boolean argument"
+msgstr "--disallow-exit 布尔参数"
+
+#: ../src/daemon/cmdline.c:340
+#, fuzzy
+msgid "--log-meta boolean argument"
+msgstr "--disallow-exit 布尔参数"
+
+#: ../src/daemon/cmdline.c:359
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "无效的重采样方法'%s'。"
 
-#: ../src/daemon/cmdline.c:345
+#: ../src/daemon/cmdline.c:366
 msgid "--system expects boolean argument"
 msgstr "--system 期待布尔参数"
 
-#: ../src/daemon/cmdline.c:352
+#: ../src/daemon/cmdline.c:373
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit 期待布尔参数"
 
-#: ../src/daemon/cmdline.c:359
+#: ../src/daemon/cmdline.c:380
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm 期待布尔参数"
 
@@ -621,288 +633,314 @@ msgstr "加载一次:%s\n"
 msgid "Path: %s\n"
 msgstr "路径:%s\n"
 
-#: ../src/daemon/daemon-conf.c:205
+#: ../src/daemon/daemon-conf.c:212
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] 无效的日志目标'%s'。"
 
-#: ../src/daemon/daemon-conf.c:221
+#: ../src/daemon/daemon-conf.c:228
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] 无效的日志级别'%s'。"
 
-#: ../src/daemon/daemon-conf.c:237
+#: ../src/daemon/daemon-conf.c:244
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] 无效的重采样方法'%s'。"
 
-#: ../src/daemon/daemon-conf.c:260
+#: ../src/daemon/daemon-conf.c:267
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] 无效的rlimit '%s'。"
 
-#: ../src/daemon/daemon-conf.c:267
+#: ../src/daemon/daemon-conf.c:274
 #, c-format
 msgid "[%s:%u] rlimit not supported on this platform."
 msgstr "[%s:%u] 此平台不支持rlimit。"
 
-#: ../src/daemon/daemon-conf.c:283
+#: ../src/daemon/daemon-conf.c:290
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] 无效的样品格式'%s'。"
 
-#: ../src/daemon/daemon-conf.c:301
+#: ../src/daemon/daemon-conf.c:308
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] 无效的样品率'%s'。"
 
-#: ../src/daemon/daemon-conf.c:319
+#: ../src/daemon/daemon-conf.c:326
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] 无效的样品通道'%s'。"
 
-#: ../src/daemon/daemon-conf.c:337
+#: ../src/daemon/daemon-conf.c:344
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] 无效的分段数'%s'。"
 
-#: ../src/daemon/daemon-conf.c:355
+#: ../src/daemon/daemon-conf.c:362
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] 无效的分段大小'%s'。"
 
-#: ../src/daemon/daemon-conf.c:373
+#: ../src/daemon/daemon-conf.c:380
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] 无效的nice level '%s'。"
 
-#: ../src/daemon/daemon-conf.c:570
+#: ../src/daemon/daemon-conf.c:566
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "打开配置文件失败:%s"
 
-#: ../src/daemon/daemon-conf.c:644
+#: ../src/daemon/daemon-conf.c:640
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### 从配置文件读取:%s ###\n"
 
 #: ../src/daemon/caps.c:63
-msgid "Dropping root priviliges."
+#, fuzzy
+msgid "Dropping root privileges."
 msgstr "正在取消root权限。"
 
 #: ../src/daemon/caps.c:103
 msgid "Limited capabilities successfully to CAP_SYS_NICE."
 msgstr "性能成功限制到CAP_SYS_NICE。"
 
-#: ../src/pulse/channelmap.c:102
+#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:804
 msgid "Mono"
 msgstr "单声道"
 
-#: ../src/pulse/channelmap.c:104
+#: ../src/pulse/channelmap.c:105
 msgid "Front Center"
 msgstr "中前"
 
-#: ../src/pulse/channelmap.c:105
+#: ../src/pulse/channelmap.c:106
 msgid "Front Left"
 msgstr "左前"
 
-#: ../src/pulse/channelmap.c:106
+#: ../src/pulse/channelmap.c:107
 msgid "Front Right"
 msgstr "右前"
 
-#: ../src/pulse/channelmap.c:108
+#: ../src/pulse/channelmap.c:109
 msgid "Rear Center"
 msgstr "中后"
 
-#: ../src/pulse/channelmap.c:109
+#: ../src/pulse/channelmap.c:110
 msgid "Rear Left"
 msgstr "左后"
 
-#: ../src/pulse/channelmap.c:110
+#: ../src/pulse/channelmap.c:111
 msgid "Rear Right"
 msgstr "右后"
 
-#: ../src/pulse/channelmap.c:112
+#: ../src/pulse/channelmap.c:113
 msgid "Low Frequency Emmiter"
 msgstr "低频脉冲"
 
-#: ../src/pulse/channelmap.c:114
+#: ../src/pulse/channelmap.c:115
 msgid "Front Left-of-center"
 msgstr "前左中央"
 
-#: ../src/pulse/channelmap.c:115
+#: ../src/pulse/channelmap.c:116
 msgid "Front Right-of-center"
 msgstr "前右中央"
 
-#: ../src/pulse/channelmap.c:117
+#: ../src/pulse/channelmap.c:118
 msgid "Side Left"
 msgstr "左侧"
 
-#: ../src/pulse/channelmap.c:118
+#: ../src/pulse/channelmap.c:119
 msgid "Side Right"
 msgstr "右侧"
 
-#: ../src/pulse/channelmap.c:120
+#: ../src/pulse/channelmap.c:121
 msgid "Auxiliary 0"
 msgstr "辅助 0"
 
-#: ../src/pulse/channelmap.c:121
+#: ../src/pulse/channelmap.c:122
 msgid "Auxiliary 1"
 msgstr "辅助 1"
 
-#: ../src/pulse/channelmap.c:122
+#: ../src/pulse/channelmap.c:123
 msgid "Auxiliary 2"
 msgstr "辅助 2"
 
-#: ../src/pulse/channelmap.c:123
+#: ../src/pulse/channelmap.c:124
 msgid "Auxiliary 3"
 msgstr "辅助 3"
 
-#: ../src/pulse/channelmap.c:124
+#: ../src/pulse/channelmap.c:125
 msgid "Auxiliary 4"
 msgstr "辅助 4"
 
-#: ../src/pulse/channelmap.c:125
+#: ../src/pulse/channelmap.c:126
 msgid "Auxiliary 5"
 msgstr "辅助 5"
 
-#: ../src/pulse/channelmap.c:126
+#: ../src/pulse/channelmap.c:127
 msgid "Auxiliary 6"
 msgstr "辅助 6"
 
-#: ../src/pulse/channelmap.c:127
+#: ../src/pulse/channelmap.c:128
 msgid "Auxiliary 7"
 msgstr "辅助 7"
 
-#: ../src/pulse/channelmap.c:128
+#: ../src/pulse/channelmap.c:129
 msgid "Auxiliary 8"
 msgstr "辅助 7"
 
-#: ../src/pulse/channelmap.c:129
+#: ../src/pulse/channelmap.c:130
 msgid "Auxiliary 9"
 msgstr "辅助 9"
 
-#: ../src/pulse/channelmap.c:130
+#: ../src/pulse/channelmap.c:131
 msgid "Auxiliary 10"
 msgstr "辅助 10"
 
-#: ../src/pulse/channelmap.c:131
+#: ../src/pulse/channelmap.c:132
 msgid "Auxiliary 11"
 msgstr "辅助 11"
 
-#: ../src/pulse/channelmap.c:132
+#: ../src/pulse/channelmap.c:133
 msgid "Auxiliary 12"
 msgstr "辅助 12"
 
-#: ../src/pulse/channelmap.c:133
+#: ../src/pulse/channelmap.c:134
 msgid "Auxiliary 13"
 msgstr "辅助 13"
 
-#: ../src/pulse/channelmap.c:134
+#: ../src/pulse/channelmap.c:135
 msgid "Auxiliary 14"
 msgstr "辅助 14"
 
-#: ../src/pulse/channelmap.c:135
+#: ../src/pulse/channelmap.c:136
 msgid "Auxiliary 15"
 msgstr "辅助 15"
 
-#: ../src/pulse/channelmap.c:136
+#: ../src/pulse/channelmap.c:137
 msgid "Auxiliary 16"
 msgstr "辅助 16"
 
-#: ../src/pulse/channelmap.c:137
+#: ../src/pulse/channelmap.c:138
 msgid "Auxiliary 17"
 msgstr "辅助 17"
 
-#: ../src/pulse/channelmap.c:138
+#: ../src/pulse/channelmap.c:139
 msgid "Auxiliary 18"
 msgstr "辅助 18"
 
-#: ../src/pulse/channelmap.c:139
+#: ../src/pulse/channelmap.c:140
 msgid "Auxiliary 19"
 msgstr "辅助 19"
 
-#: ../src/pulse/channelmap.c:140
+#: ../src/pulse/channelmap.c:141
 msgid "Auxiliary 20"
 msgstr "辅助 20"
 
-#: ../src/pulse/channelmap.c:141
+#: ../src/pulse/channelmap.c:142
 msgid "Auxiliary 21"
 msgstr "辅助 21"
 
-#: ../src/pulse/channelmap.c:142
+#: ../src/pulse/channelmap.c:143
 msgid "Auxiliary 22"
 msgstr "辅助 22"
 
-#: ../src/pulse/channelmap.c:143
+#: ../src/pulse/channelmap.c:144
 msgid "Auxiliary 23"
 msgstr "辅助 23"
 
-#: ../src/pulse/channelmap.c:144
+#: ../src/pulse/channelmap.c:145
 msgid "Auxiliary 24"
 msgstr "辅助 24"
 
-#: ../src/pulse/channelmap.c:145
+#: ../src/pulse/channelmap.c:146
 msgid "Auxiliary 25"
 msgstr "辅助 25"
 
-#: ../src/pulse/channelmap.c:146
+#: ../src/pulse/channelmap.c:147
 msgid "Auxiliary 26"
 msgstr "辅助 26"
 
-#: ../src/pulse/channelmap.c:147
+#: ../src/pulse/channelmap.c:148
 msgid "Auxiliary 27"
 msgstr "辅助 27"
 
-#: ../src/pulse/channelmap.c:148
+#: ../src/pulse/channelmap.c:149
 msgid "Auxiliary 28"
 msgstr "辅助 28"
 
-#: ../src/pulse/channelmap.c:149
+#: ../src/pulse/channelmap.c:150
 msgid "Auxiliary 29"
 msgstr "辅助 29"
 
-#: ../src/pulse/channelmap.c:150
+#: ../src/pulse/channelmap.c:151
 msgid "Auxiliary 30"
 msgstr "辅助 30"
 
-#: ../src/pulse/channelmap.c:151
+#: ../src/pulse/channelmap.c:152
 msgid "Auxiliary 31"
 msgstr "辅助 31"
 
-#: ../src/pulse/channelmap.c:153
+#: ../src/pulse/channelmap.c:154
 msgid "Top Center"
 msgstr "上中"
 
-#: ../src/pulse/channelmap.c:155
+#: ../src/pulse/channelmap.c:156
 msgid "Top Front Center"
 msgstr "上中前"
 
-#: ../src/pulse/channelmap.c:156
+#: ../src/pulse/channelmap.c:157
 msgid "Top Front Left"
 msgstr "上左前"
 
-#: ../src/pulse/channelmap.c:157
+#: ../src/pulse/channelmap.c:158
 msgid "Top Front Right"
 msgstr "上右前"
 
-#: ../src/pulse/channelmap.c:159
+#: ../src/pulse/channelmap.c:160
 msgid "Top Rear Center"
 msgstr "上中后"
 
-#: ../src/pulse/channelmap.c:160
+#: ../src/pulse/channelmap.c:161
 msgid "Top Rear Left"
 msgstr "上左后"
 
-#: ../src/pulse/channelmap.c:161
+#: ../src/pulse/channelmap.c:162
 msgid "Top Rear Right"
 msgstr "上右后"
 
-#: ../src/pulse/channelmap.c:472 ../src/pulse/sample.c:144
-#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:194
+#: ../src/pulse/channelmap.c:476 ../src/pulse/sample.c:167
+#: ../src/pulse/volume.c:170 ../src/pulse/volume.c:196
+#: ../src/pulse/volume.c:216 ../src/pulse/volume.c:246
 msgid "(invalid)"
 msgstr "(无效)"
 
+#: ../src/pulse/channelmap.c:808
+msgid "Stereo"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:813
+msgid "Surround 4.0"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:819
+msgid "Surround 4.1"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:825
+msgid "Surround 5.0"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:831
+msgid "Surround 5.1"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:838
+msgid "Surround 7.1"
+msgstr ""
+
 #: ../src/pulse/error.c:43
 msgid "OK"
 msgstr "好"
@@ -991,6 +1029,39 @@ msgstr "未知错误码"
 msgid "No such extension"
 msgstr "没有该扩展"
 
+#: ../src/pulse/error.c:65
+msgid "Obsolete functionality"
+msgstr ""
+
+#: ../src/pulse/error.c:66
+msgid "Missing implementation"
+msgstr ""
+
+#: ../src/pulse/sample.c:169
+#, c-format
+msgid "%s %uch %uHz"
+msgstr ""
+
+#: ../src/pulse/sample.c:181
+#, c-format
+msgid "%0.1f GiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:183
+#, c-format
+msgid "%0.1f MiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:185
+#, c-format
+msgid "%0.1f KiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:187
+#, c-format
+msgid "%u B"
+msgstr ""
+
 #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
 msgid "XOpenDisplay() failed"
 msgstr "XOpenDisplay()失败"
@@ -1004,45 +1075,35 @@ msgstr "cookie数据分析失败"
 msgid "Failed to open configuration file '%s': %s"
 msgstr "打开配置文件'%s'失败:%s"
 
-#: ../src/pulse/context.c:516
+#: ../src/pulse/context.c:517
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "没有加载cookie。尝试不加载cookie进行连接。"
 
-#: ../src/pulse/context.c:642
+#: ../src/pulse/context.c:643
 #, c-format
 msgid "fork(): %s"
 msgstr "fork():%s"
 
-#: ../src/pulse/context.c:695
+#: ../src/pulse/context.c:696
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid():%s"
 
-#: ../src/pulse/context.c:1256
+#: ../src/pulse/context.c:1257
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "收到未知扩展'%s'的信息"
 
-#: ../src/utils/pacat.c:93
+#: ../src/utils/pacat.c:94
 #, c-format
 msgid "pa_stream_write() failed: %s\n"
 msgstr "pa_stream_write()失败:%s\n"
 
-#: ../src/utils/pacat.c:132
+#: ../src/utils/pacat.c:133
 #, c-format
 msgid "pa_stream_peek() failed: %s\n"
 msgstr "pa_stream_peek()失败:%s\n"
 
-#: ../src/utils/pacat.c:141
-#, c-format
-msgid "Buffer overrun, dropping incoming data\n"
-msgstr "缓冲超限,丢弃正在读入的数据\n"
-
-#: ../src/utils/pacat.c:143
-#, c-format
-msgid "pa_stream_drop() failed: %s\n"
-msgstr "pa_stream_drop()失败:%s\n"
-
 #: ../src/utils/pacat.c:169
 #, c-format
 msgid "Stream successfully created.\n"
@@ -1122,78 +1183,78 @@ msgstr "连接已建立。%s \n"
 msgid "pa_stream_new() failed: %s\n"
 msgstr "pa_stream_new()失败:%s\n"
 
-#: ../src/utils/pacat.c:287
+#: ../src/utils/pacat.c:288
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s\n"
 msgstr "pa_stream_connect_playback()失败:%s\n"
 
-#: ../src/utils/pacat.c:293
+#: ../src/utils/pacat.c:294
 #, c-format
 msgid "pa_stream_connect_record() failed: %s\n"
 msgstr "pa_stream_connect_playback()失败:%s\n"
 
-#: ../src/utils/pacat.c:307 ../src/utils/pasuspender.c:159
-#: ../src/utils/pactl.c:666 ../src/utils/paplay.c:183
+#: ../src/utils/pacat.c:308 ../src/utils/pasuspender.c:159
+#: ../src/utils/pactl.c:758 ../src/utils/paplay.c:183
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "连接失败:%s\n"
 
-#: ../src/utils/pacat.c:328 ../src/utils/paplay.c:75
+#: ../src/utils/pacat.c:329 ../src/utils/paplay.c:75
 #, c-format
 msgid "Failed to drain stream: %s\n"
 msgstr "排出流失败:%s\n"
 
-#: ../src/utils/pacat.c:333 ../src/utils/paplay.c:80
+#: ../src/utils/pacat.c:334 ../src/utils/paplay.c:80
 #, c-format
 msgid "Playback stream drained.\n"
 msgstr "流播放完毕。\n"
 
-#: ../src/utils/pacat.c:343 ../src/utils/paplay.c:92
+#: ../src/utils/pacat.c:344 ../src/utils/paplay.c:92
 #, c-format
 msgid "Draining connection to server.\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:370
 #, c-format
 msgid "Got EOF.\n"
 msgstr "收到EOF。\n"
 
-#: ../src/utils/pacat.c:375
+#: ../src/utils/pacat.c:376
 #, c-format
 msgid "pa_stream_drain(): %s\n"
 msgstr "pa_stream_drain():%s\n"
 
-#: ../src/utils/pacat.c:385
+#: ../src/utils/pacat.c:386
 #, c-format
 msgid "read() failed: %s\n"
 msgstr "read()失败:%s\n"
 
-#: ../src/utils/pacat.c:417
+#: ../src/utils/pacat.c:418
 #, c-format
 msgid "write() failed: %s\n"
 msgstr "write()失败:%s\n"
 
-#: ../src/utils/pacat.c:438
+#: ../src/utils/pacat.c:439
 #, c-format
 msgid "Got signal, exiting.\n"
 msgstr "收到信号,正在退出。\n"
 
-#: ../src/utils/pacat.c:452
+#: ../src/utils/pacat.c:453
 #, c-format
 msgid "Failed to get latency: %s\n"
 msgstr "获取传输延迟失败:%s\n"
 
-#: ../src/utils/pacat.c:457
+#: ../src/utils/pacat.c:458
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec.  \r"
 msgstr "时间:%0.3f秒;延迟:%0.0f 微秒。  \r"
 
-#: ../src/utils/pacat.c:477
+#: ../src/utils/pacat.c:478
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s\n"
 msgstr "pa_stream_update_timing_info()失败:%s\n"
 
-#: ../src/utils/pacat.c:490
+#: ../src/utils/pacat.c:491
 #, c-format
 msgid ""
 "%s [options]\n"
@@ -1244,7 +1305,8 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
-msgstr "%s [options]\n"
+msgstr ""
+"%s [options]\n"
 "\n"
 "  -h, --help                            显示此帮助\n"
 "      --version                         显示版本号\n"
@@ -1258,21 +1320,26 @@ msgstr "%s [options]\n"
 "  -d, --device=DEVICE                   要连接的sink/source名\n"
 "  -n, --client-name=NAME                指定客户端在服务器上的名称\n"
 "      --stream-name=NAME                指定流在服务器上的名称\n"
-"      --volume=VOLUME                   指定初始(线性)音量,取值在0...65536之间\n"
+"      --volume=VOLUME                   指定初始(线性)音量,取值在0...65536"
+"之间\n"
 "      --rate=SAMPLERATE                 采样频率(单位Hz,默认为44100)\n"
-"      --format=SAMPLEFORMAT             采样类型,从s16le,s16be,u8,float32le,\n"
-"                                        float32be,ulaw,alaw,s32le,s32be中取(默认为s16ne)\n"
-"      --channels=CHANNELS               通道数,1为单声道,2为立体声(默认为2)\n"
+"      --format=SAMPLEFORMAT             采样类型,从s16le,s16be,u8,"
+"float32le,\n"
+"                                        float32be,ulaw,alaw,s32le,s32be中"
+"取(默认为s16ne)\n"
+"      --channels=CHANNELS               通道数,1为单声道,2为立体声(默认为"
+"2)\n"
 "      --channel-map=CHANNELMAP          取代默认值的通道映射表\n"
 "      --fix-format                      从流连接的音频出口处取采样格式。\n"
 "      --fix-rate                        从流连接的音频出口处取采样率。\n"
-"      --fix-channels                    从流连接的音频出口处取通道数和通道映射表。\n"
+"      --fix-channels                    从流连接的音频出口处取通道数和通道映"
+"射表。\n"
 "      --no-remix                        Don't upmix or downmix channels.\n"
 "      --no-remap                        根据下标而非名称来映射通道。\n"
 "      --latency=BYTES                   请求指定字节数的延迟。\n"
 "      --process-time=BYTES              每次请求指定字节数的处理时间。\n"
 
-#: ../src/utils/pacat.c:591
+#: ../src/utils/pacat.c:592
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1283,88 +1350,88 @@ msgstr ""
 "Compiled with libpulse %s\n"
 "Linked with libpulse %s\n"
 
-#: ../src/utils/pacat.c:647
+#: ../src/utils/pacat.c:649
 #, c-format
 msgid "Invalid channel map '%s'\n"
 msgstr "无效的通道映射描述'%s'\n"
 
-#: ../src/utils/pacat.c:676
+#: ../src/utils/pacat.c:678
 #, c-format
 msgid "Invalid latency specification '%s'\n"
 msgstr "无效的延迟规格描述 %s'\n"
 
-#: ../src/utils/pacat.c:683
+#: ../src/utils/pacat.c:685
 #, c-format
 msgid "Invalid process time specification '%s'\n"
 msgstr "无效的处理时间描述 '%s'\n"
 
-#: ../src/utils/pacat.c:694
+#: ../src/utils/pacat.c:696
 #, c-format
 msgid "Invalid sample specification\n"
 msgstr "无效的采样描述\n"
 
-#: ../src/utils/pacat.c:699
+#: ../src/utils/pacat.c:701
 #, c-format
 msgid "Channel map doesn't match sample specification\n"
 msgstr "通道映射与采样描述不匹配\n"
 
-#: ../src/utils/pacat.c:706
+#: ../src/utils/pacat.c:708
 #, c-format
 msgid "Opening a %s stream with sample specification '%s'.\n"
 msgstr "以采样规格'%s'打开%s流。\n"
 
-#: ../src/utils/pacat.c:706
+#: ../src/utils/pacat.c:708
 msgid "recording"
 msgstr "正在录制"
 
-#: ../src/utils/pacat.c:706
+#: ../src/utils/pacat.c:708
 msgid "playback"
 msgstr "回放"
 
-#: ../src/utils/pacat.c:714
+#: ../src/utils/pacat.c:716
 #, c-format
 msgid "open(): %s\n"
 msgstr "open():%s\n"
 
-#: ../src/utils/pacat.c:719
+#: ../src/utils/pacat.c:721
 #, c-format
 msgid "dup2(): %s\n"
 msgstr "dup2():%s\n"
 
-#: ../src/utils/pacat.c:729
+#: ../src/utils/pacat.c:731
 #, c-format
 msgid "Too many arguments.\n"
 msgstr "参数过多。\n"
 
-#: ../src/utils/pacat.c:742 ../src/utils/pasuspender.c:280
-#: ../src/utils/pactl.c:909 ../src/utils/paplay.c:381
+#: ../src/utils/pacat.c:744 ../src/utils/pasuspender.c:280
+#: ../src/utils/pactl.c:1013 ../src/utils/paplay.c:381
 #, c-format
 msgid "pa_mainloop_new() failed.\n"
 msgstr "pa_mainloop_new()失败。\n"
 
-#: ../src/utils/pacat.c:763
+#: ../src/utils/pacat.c:765
 #, c-format
 msgid "io_new() failed.\n"
 msgstr "io_new()失败。\n"
 
-#: ../src/utils/pacat.c:769 ../src/utils/pasuspender.c:293
-#: ../src/utils/pactl.c:923 ../src/utils/paplay.c:396
+#: ../src/utils/pacat.c:771 ../src/utils/pasuspender.c:293
+#: ../src/utils/pactl.c:1027 ../src/utils/paplay.c:396
 #, c-format
 msgid "pa_context_new() failed.\n"
 msgstr "pa_context_new()失败。\n"
 
-#: ../src/utils/pacat.c:777
+#: ../src/utils/pacat.c:779
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_connect()失败:%s"
 
-#: ../src/utils/pacat.c:788
+#: ../src/utils/pacat.c:790
 #, c-format
 msgid "time_new() failed.\n"
 msgstr "time_new()失败。\n"
 
-#: ../src/utils/pacat.c:795 ../src/utils/pasuspender.c:301
-#: ../src/utils/pactl.c:931 ../src/utils/paplay.c:407
+#: ../src/utils/pacat.c:797 ../src/utils/pasuspender.c:301
+#: ../src/utils/pactl.c:1035 ../src/utils/paplay.c:407
 #, c-format
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run()失败。\n"
@@ -1394,7 +1461,7 @@ msgstr "恢复失败:%s\n"
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "警告:非本地声音服务器,不会挂起。\n"
 
-#: ../src/utils/pasuspender.c:176 ../src/utils/pactl.c:672
+#: ../src/utils/pasuspender.c:176 ../src/utils/pactl.c:764
 #: ../src/utils/paplay.c:191
 #, c-format
 msgid "Got SIGINT, exiting.\n"
@@ -1415,7 +1482,8 @@ msgid ""
 "  -s, --server=SERVER                   The name of the server to connect "
 "to\n"
 "\n"
-msgstr "%s [options] ... \n"
+msgstr ""
+"%s [options] ... \n"
 "\n"
 "  -h, --help                            显示此帮助\n"
 "      --version                         显示版本\n"
@@ -1433,32 +1501,32 @@ msgstr ""
 "Compiled with libpulse %s\n"
 "Linked with libpulse %s\n"
 
-#: ../src/utils/pactl.c:107
+#: ../src/utils/pactl.c:108
 #, c-format
 msgid "Failed to get statistics: %s\n"
 msgstr "获取统计数据失败:%s\n"
 
-#: ../src/utils/pactl.c:113
+#: ../src/utils/pactl.c:114
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "当前使用:%u块,总共%s字节。\n"
 
-#: ../src/utils/pactl.c:116
+#: ../src/utils/pactl.c:117
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr "整个生命周期所得分配:%u块,总共%s字节。\n"
 
-#: ../src/utils/pactl.c:119
+#: ../src/utils/pactl.c:120
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "采样缓存大小:%s\n"
 
-#: ../src/utils/pactl.c:128
+#: ../src/utils/pactl.c:129
 #, c-format
 msgid "Failed to get server information: %s\n"
 msgstr "获取服务器信息失败:%s\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:136
 #, c-format
 msgid ""
 "User name: %s\n"
@@ -1469,7 +1537,8 @@ msgid ""
 "Default Sink: %s\n"
 "Default Source: %s\n"
 "Cookie: %08x\n"
-msgstr "用户名:%s\n"
+msgstr ""
+"用户名:%s\n"
 "主机名:%s\n"
 "服务器名:%s\n"
 "服务器版本:%s\n"
@@ -1478,27 +1547,33 @@ msgstr "用户名:%s\n"
 "默认音频入口:%s\n"
 "Cookie:%08x\n"
 
-#: ../src/utils/pactl.c:160
+#: ../src/utils/pactl.c:175
 #, c-format
 msgid "Failed to get sink information: %s\n"
 msgstr "获取音频出口信息失败:%s\n"
 
-#: ../src/utils/pactl.c:176
-#, c-format
+#: ../src/utils/pactl.c:191
+#, fuzzy, c-format
 msgid ""
-"*** Sink #%u ***\n"
-"Name: %s\n"
-"Driver: %s\n"
-"Sample Specification: %s\n"
-"Channel Map: %s\n"
-"Owner Module: %u\n"
-"Volume: %s\n"
-"Monitor Source: %s\n"
-"Latency: %0.0f usec, configured %0.0f usec\n"
-"Flags: %s%s%s%s%s%s\n"
-"Properties:\n"
-"%s"
-msgstr "*** 音频出口 #%u ***\n"
+"Sink #%u\n"
+"\tState: %s\n"
+"\tName: %s\n"
+"\tDescription: %s\n"
+"\tDriver: %s\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tOwner Module: %u\n"
+"\tMute: %s\n"
+"\tVolume: %s%s%s\n"
+"\t        balance %0.2f\n"
+"\tBase Volume: %s%s%s\n"
+"\tMonitor Source: %s\n"
+"\tLatency: %0.0f usec, configured %0.0f usec\n"
+"\tFlags: %s%s%s%s%s%s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+"*** 音频出口 #%u ***\n"
 "名称:%s\n"
 "驱动:%s\n"
 "采样规格:%s\n"
@@ -1511,31 +1586,33 @@ msgstr "*** 音频出口 #%u ***\n"
 "属性:\n"
 "%s"
 
-#: ../src/utils/pactl.c:193 ../src/utils/pactl.c:371
-msgid "muted"
-msgstr "已静音"
-
-#: ../src/utils/pactl.c:212
+#: ../src/utils/pactl.c:255
 #, c-format
 msgid "Failed to get source information: %s\n"
 msgstr "获取音频入口信息失败:%s\n"
 
-#: ../src/utils/pactl.c:228
-#, c-format
+#: ../src/utils/pactl.c:271
+#, fuzzy, c-format
 msgid ""
-"*** Source #%u ***\n"
-"Name: %s\n"
-"Driver: %s\n"
-"Sample Specification: %s\n"
-"Channel Map: %s\n"
-"Owner Module: %u\n"
-"Volume: %s\n"
-"Monitor of Sink: %s\n"
-"Latency: %0.0f usec, configured %0.0f usec\n"
-"Flags: %s%s%s%s%s%s\n"
-"Properties:\n"
-"%s"
-msgstr "*** 音频入口 #%u ***\n"
+"Source #%u\n"
+"\tState: %s\n"
+"\tName: %s\n"
+"\tDescription: %s\n"
+"\tDriver: %s\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tOwner Module: %u\n"
+"\tMute: %s\n"
+"\tVolume: %s%s%s\n"
+"\t        balance %0.2f\n"
+"\tBase Volume: %s%s%s\n"
+"\tMonitor of Sink: %s\n"
+"\tLatency: %0.0f usec, configured %0.0f usec\n"
+"\tFlags: %s%s%s%s%s%s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+"*** 音频入口 #%u ***\n"
 "名称:%s\n"
 "驱动:%s\n"
 "采样规格:%s\n"
@@ -1548,73 +1625,112 @@ msgstr "*** 音频入口 #%u ***\n"
 "属性:\n"
 "%s"
 
-#: ../src/utils/pactl.c:246 ../src/utils/pactl.c:289 ../src/utils/pactl.c:322
-#: ../src/utils/pactl.c:366 ../src/utils/pactl.c:367 ../src/utils/pactl.c:374
-#: ../src/utils/pactl.c:418 ../src/utils/pactl.c:419 ../src/utils/pactl.c:425
-#: ../src/utils/pactl.c:468 ../src/utils/pactl.c:469 ../src/utils/pactl.c:473
+#: ../src/utils/pactl.c:303 ../src/utils/pactl.c:347 ../src/utils/pactl.c:382
+#: ../src/utils/pactl.c:419 ../src/utils/pactl.c:478 ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:489 ../src/utils/pactl.c:533 ../src/utils/pactl.c:534
+#: ../src/utils/pactl.c:540 ../src/utils/pactl.c:583 ../src/utils/pactl.c:584
+#: ../src/utils/pactl.c:591
 msgid "n/a"
 msgstr "n/a"
 
-#: ../src/utils/pactl.c:263
+#: ../src/utils/pactl.c:321
 #, c-format
 msgid "Failed to get module information: %s\n"
 msgstr "获取模块信息失败:%s\n"
 
-#: ../src/utils/pactl.c:281
-#, c-format
+#: ../src/utils/pactl.c:339
+#, fuzzy, c-format
 msgid ""
-"*** Module #%u ***\n"
-"Name: %s\n"
-"Argument: %s\n"
-"Usage counter: %s\n"
-"Auto unload: %s\n"
-msgstr "*** 模块 #%u ***\n"
+"Module #%u\n"
+"\tName: %s\n"
+"\tArgument: %s\n"
+"\tUsage counter: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+"*** 模块 #%u ***\n"
 "名称:%s\n"
 "参数:%s\n"
 "使用计数器:%s\n"
 "自动卸载:%s\n"
 
-#: ../src/utils/pactl.c:298
+#: ../src/utils/pactl.c:358
 #, c-format
 msgid "Failed to get client information: %s\n"
 msgstr "获取客户端信息失败:%s\n"
 
-#: ../src/utils/pactl.c:316
-#, c-format
+#: ../src/utils/pactl.c:376
+#, fuzzy, c-format
 msgid ""
-"*** Client #%u ***\n"
-"Driver: %s\n"
-"Owner Module: %s\n"
-"Properties:\n"
+"Client #%u\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+"*** 客户端 #%u ***\n"
+"驱动:%s\n"
+"所有者模块:%s\n"
+"属性:\n"
 "%s"
-msgstr "*** 客户端 #%u ***\n"
+
+#: ../src/utils/pactl.c:393
+#, fuzzy, c-format
+msgid "Failed to get card information: %s\n"
+msgstr "获取自动加载信息失败:%s\n"
+
+#: ../src/utils/pactl.c:411
+#, fuzzy, c-format
+msgid ""
+"Card #%u\n"
+"\tName: %s\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+"*** 客户端 #%u ***\n"
 "驱动:%s\n"
 "所有者模块:%s\n"
 "属性:\n"
 "%s"
 
-#: ../src/utils/pactl.c:333
+#: ../src/utils/pactl.c:425
+#, c-format
+msgid "\tProfiles:\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:431
+#, fuzzy, c-format
+msgid "\tActive Profile: %s\n"
+msgstr "管道失败:%s"
+
+#: ../src/utils/pactl.c:442
 #, c-format
 msgid "Failed to get sink input information: %s\n"
 msgstr "获取音频出口输入信息失败:%s\n"
 
-#: ../src/utils/pactl.c:352
-#, c-format
+#: ../src/utils/pactl.c:461
+#, fuzzy, c-format
 msgid ""
-"*** Sink Input #%u ***\n"
-"Driver: %s\n"
-"Owner Module: %s\n"
-"Client: %s\n"
-"Sink: %u\n"
-"Sample Specification: %s\n"
-"Channel Map: %s\n"
-"Volume: %s\n"
-"Buffer Latency: %0.0f usec\n"
-"Sink Latency: %0.0f usec\n"
-"Resample method: %s\n"
-"Properties:\n"
-"%s"
-msgstr "*** 音频出口输入 #%u ***\n"
+"Sink Input #%u\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tClient: %s\n"
+"\tSink: %u\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
+"\tBuffer Latency: %0.0f usec\n"
+"\tSink Latency: %0.0f usec\n"
+"\tResample method: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+"*** 音频出口输入 #%u ***\n"
 "驱动:%s\n"
 "所有者模块:%s\n"
 "客户端:%s\n"
@@ -1628,27 +1744,28 @@ msgstr "*** 音频出口输入 #%u ***\n"
 "属性:\n"
 "%s"
 
-#: ../src/utils/pactl.c:385
+#: ../src/utils/pactl.c:500
 #, c-format
 msgid "Failed to get source output information: %s\n"
 msgstr "获取音频入口输出信息失败:%s\n"
 
-#: ../src/utils/pactl.c:405
-#, c-format
+#: ../src/utils/pactl.c:520
+#, fuzzy, c-format
 msgid ""
-"*** Source Output #%u ***\n"
-"Driver: %s\n"
-"Owner Module: %s\n"
-"Client: %s\n"
-"Source: %u\n"
-"Sample Specification: %s\n"
-"Channel Map: %s\n"
-"Buffer Latency: %0.0f usec\n"
-"Source Latency: %0.0f usec\n"
-"Resample method: %s\n"
-"Properties:\n"
-"%s"
-msgstr "*** 音频入口输出 #%u ***\n"
+"Source Output #%u\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tClient: %s\n"
+"\tSource: %u\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tBuffer Latency: %0.0f usec\n"
+"\tSource Latency: %0.0f usec\n"
+"\tResample method: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+"*** 音频入口输出 #%u ***\n"
 "驱动:%s\n"
 "所有者模块:%s\n"
 "客户端:%s\n"
@@ -1661,26 +1778,29 @@ msgstr "*** 音频入口输出 #%u ***\n"
 "属性:\n"
 "%s"
 
-#: ../src/utils/pactl.c:436
+#: ../src/utils/pactl.c:551
 #, c-format
 msgid "Failed to get sample information: %s\n"
 msgstr "获取采样信息失败:%s\n"
 
-#: ../src/utils/pactl.c:455
-#, c-format
+#: ../src/utils/pactl.c:569
+#, fuzzy, c-format
 msgid ""
-"*** Sample #%u ***\n"
-"Name: %s\n"
-"Volume: %s\n"
-"Sample Specification: %s\n"
-"Channel Map: %s\n"
-"Duration: %0.1fs\n"
-"Size: %s\n"
-"Lazy: %s\n"
-"Filename: %s\n"
-"Properties:\n"
-"%s"
-msgstr "*** 采样 #%u ***\n"
+"Sample #%u\n"
+"\tName: %s\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
+"\tDuration: %0.1fs\n"
+"\tSize: %s\n"
+"\tLazy: %s\n"
+"\tFilename: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+"*** 采样 #%u ***\n"
 "名称:%s\n"
 "音量:%s\n"
 "采样规格:%s\n"
@@ -1692,50 +1812,23 @@ msgstr "*** 采样 #%u ***\n"
 "属性:\n"
 "%s"
 
-#: ../src/utils/pactl.c:481
-#, c-format
-msgid "Failed to get autoload information: %s\n"
-msgstr "获取自动加载信息失败:%s\n"
-
-#: ../src/utils/pactl.c:497
-#, c-format
-msgid ""
-"*** Autoload Entry #%u ***\n"
-"Name: %s\n"
-"Type: %s\n"
-"Module: %s\n"
-"Argument: %s\n"
-msgstr "*** 自动加载项 #%u ***\n"
-"名称:%s\n"
-"类型:%s\n"
-"模块:%s\n"
-"参数:%s\n"
-
-#: ../src/utils/pactl.c:504
-msgid "sink"
-msgstr "音频出口"
-
-#: ../src/utils/pactl.c:504
-msgid "source"
-msgstr "音频入口"
-
-#: ../src/utils/pactl.c:511 ../src/utils/pactl.c:521
+#: ../src/utils/pactl.c:599 ../src/utils/pactl.c:609
 #, c-format
 msgid "Failure: %s\n"
 msgstr "失败:%s\n"
 
-#: ../src/utils/pactl.c:545
+#: ../src/utils/pactl.c:633
 #, c-format
 msgid "Failed to upload sample: %s\n"
 msgstr "上传采样失败:%s\n"
 
-#: ../src/utils/pactl.c:562
+#: ../src/utils/pactl.c:650
 #, c-format
 msgid "Premature end of file\n"
 msgstr "文件过早结束\n"
 
-#: ../src/utils/pactl.c:678
-#, c-format
+#: ../src/utils/pactl.c:770
+#, fuzzy, c-format
 msgid ""
 "%s [options] stat\n"
 "%s [options] list\n"
@@ -1749,6 +1842,7 @@ msgid ""
 "%s [options] unload-module ID\n"
 "%s [options] suspend-sink [SINK] 1|0\n"
 "%s [options] suspend-source [SOURCE] 1|0\n"
+"%s [options] set-card-profile [CARD] [PROFILE] \n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -1757,7 +1851,8 @@ msgid ""
 "to\n"
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
-msgstr "%s [options] stat\n"
+msgstr ""
+"%s [options] stat\n"
 "%s [options] list\n"
 "%s [options] exit\n"
 "%s [options] upload-sample FILENAME [NAME]\n"
@@ -1776,7 +1871,7 @@ msgstr "%s [options] stat\n"
 "  -s, --server=SERVER                   要连接的服务器名\n"
 "  -n, --client-name=NAME                此客户端在服务器上的名称\n"
 
-#: ../src/utils/pactl.c:729
+#: ../src/utils/pactl.c:822
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -1787,61 +1882,66 @@ msgstr ""
 "Compiled with libpulse %s\n"
 "Linked with libpulse %s\n"
 
-#: ../src/utils/pactl.c:768
+#: ../src/utils/pactl.c:861
 #, c-format
 msgid "Please specify a sample file to load\n"
 msgstr "请指定要加载的采样文件\n"
 
-#: ../src/utils/pactl.c:790
+#: ../src/utils/pactl.c:883
 #, c-format
 msgid "Failed to open sound file.\n"
 msgstr "打开声音文件失败。\n"
 
-#: ../src/utils/pactl.c:802
+#: ../src/utils/pactl.c:895
 #, c-format
 msgid "You have to specify a sample name to play\n"
 msgstr "你必须指定要播放的采样名\n"
 
-#: ../src/utils/pactl.c:814
+#: ../src/utils/pactl.c:907
 #, c-format
 msgid "You have to specify a sample name to remove\n"
 msgstr "你必须指定要删除的采样名\n"
 
-#: ../src/utils/pactl.c:822
+#: ../src/utils/pactl.c:915
 #, c-format
 msgid "You have to specify a sink input index and a sink\n"
 msgstr "你必须指定音频出口索引和音频出口\n"
 
-#: ../src/utils/pactl.c:831
+#: ../src/utils/pactl.c:924
 #, c-format
 msgid "You have to specify a source output index and a source\n"
 msgstr "你必须指定音频入口输出索引和音频入口\n"
 
-#: ../src/utils/pactl.c:845
+#: ../src/utils/pactl.c:938
 #, c-format
 msgid "You have to specify a module name and arguments.\n"
 msgstr "必须指定模块名和参数。\n"
 
-#: ../src/utils/pactl.c:865
+#: ../src/utils/pactl.c:958
 #, c-format
 msgid "You have to specify a module index\n"
 msgstr "必须指定模块索引\n"
 
-#: ../src/utils/pactl.c:875
-#, c-format
+#: ../src/utils/pactl.c:968
+#, fuzzy, c-format
 msgid ""
-"You may not specify more than one sink. You have to specify at least one "
-"boolean value.\n"
+"You may not specify more than one sink. You have to specify a boolean "
+"value.\n"
 msgstr "不可指定多个音频出口。必须指定至少一个布尔值。\n"
 
-#: ../src/utils/pactl.c:888
-#, c-format
+#: ../src/utils/pactl.c:981
+#, fuzzy, c-format
 msgid ""
-"You may not specify more than one source. You have to specify at least one "
-"boolean value.\n"
+"You may not specify more than one source. You have to specify a boolean "
+"value.\n"
 msgstr "不可指定多个音频入口。必须指定至少一个布尔值。\n"
 
-#: ../src/utils/pactl.c:904
+#: ../src/utils/pactl.c:993
+#, fuzzy, c-format
+msgid "You have to specify a card name/index and a profile name\n"
+msgstr "你必须指定音频出口索引和音频出口\n"
+
+#: ../src/utils/pactl.c:1008
 #, c-format
 msgid "No valid command specified.\n"
 msgstr "未指定有效的命令。\n"
@@ -1942,17 +2042,17 @@ msgstr "杀死PulseAudio后台程序失败。"
 msgid "Daemon not responding."
 msgstr "后台程序未响应。"
 
-#: ../src/utils/pacmd.c:112
+#: ../src/utils/pacmd.c:144
 #, c-format
 msgid "select(): %s"
 msgstr "select():%s"
 
-#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140
+#: ../src/utils/pacmd.c:154 ../src/utils/pacmd.c:171
 #, c-format
 msgid "read(): %s"
 msgstr "read():%s"
 
-#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167
+#: ../src/utils/pacmd.c:187 ../src/utils/pacmd.c:201
 #, c-format
 msgid "write(): %s"
 msgstr "write():%s"
@@ -2004,7 +2104,8 @@ msgstr ""
 "  -d, --device=DEVICE                   要连接的音频出口名\n"
 "  -n, --client-name=NAME                此客户端在服务器上的名称\n"
 "      --stream-name=NAME                此流在服务器上的名称\n"
-"      --volume=VOLUME                   指定初始(线性)音量,取值在0...65536之间\n"
+"      --volume=VOLUME                   指定初始(线性)音量,取值在0...65536"
+"之间\n"
 "      --channel-map=CHANNELMAP          设定使用的通道映射表\n"
 
 #: ../src/utils/paplay.c:255
@@ -2042,3 +2143,46 @@ msgstr "正在使用采样规格'%s'\n"
 msgid "Cannot access autospawn lock."
 msgstr "不能访问autospawn锁。"
 
+#~ msgid ""
+#~ "' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n"
+#~ "For enabling real-time scheduling please acquire the appropriate "
+#~ "PolicyKit priviliges, or become a member of '"
+#~ msgstr ""
+#~ "而且PolicyKit拒绝授予我们权限。再次取消SUID。\n"
+#~ "要启用实时调度,请取得适应的PolicyKit权限,或者成为组成员'"
+
+#~ msgid ""
+#~ "', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this "
+#~ "user."
+#~ msgstr "',或者提高本用户的RLIMIT_NICE/RLIMIT_RTPRIO资源上限。"
+
+#~ msgid "Default sink name (%s) does not exist in name register."
+#~ msgstr "名称登记表中不存在默认的音频出口名(%s)。"
+
+#~ msgid "Buffer overrun, dropping incoming data\n"
+#~ msgstr "缓冲超限,丢弃正在读入的数据\n"
+
+#~ msgid "pa_stream_drop() failed: %s\n"
+#~ msgstr "pa_stream_drop()失败:%s\n"
+
+#~ msgid "muted"
+#~ msgstr "已静音"
+
+#~ msgid ""
+#~ "*** Autoload Entry #%u ***\n"
+#~ "Name: %s\n"
+#~ "Type: %s\n"
+#~ "Module: %s\n"
+#~ "Argument: %s\n"
+#~ msgstr ""
+#~ "*** 自动加载项 #%u ***\n"
+#~ "名称:%s\n"
+#~ "类型:%s\n"
+#~ "模块:%s\n"
+#~ "参数:%s\n"
+
+#~ msgid "sink"
+#~ msgstr "音频出口"
+
+#~ msgid "source"
+#~ msgstr "音频入口"

commit 12c29e18329ac7928f16d613c6fbd7b94472fae8
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 22:26:08 2009 +0100

    store the identification key in the module-stream-restore.id property

diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c
index b1630fe..2dd2045 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -62,6 +62,7 @@ PA_MODULE_USAGE(
         "restore_muted=<Save/restore muted states?>");
 
 #define SAVE_INTERVAL 10
+#define IDENTIFICATION_PROPERTY "module-stream-restore.id"
 
 static const char* const valid_modargs[] = {
     "restore_device",
@@ -129,20 +130,27 @@ static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct
 
 static char *get_name(pa_proplist *p, const char *prefix) {
     const char *r;
+    char *t;
 
     if (!p)
         return NULL;
 
+    if ((r = pa_proplist_gets(p, IDENTIFICATION_PROPERTY)))
+        return pa_xstrdup(r);
+
     if ((r = pa_proplist_gets(p, PA_PROP_MEDIA_ROLE)))
-        return pa_sprintf_malloc("%s-by-media-role:%s", prefix, r);
+        t = pa_sprintf_malloc("%s-by-media-role:%s", prefix, r);
     else if ((r = pa_proplist_gets(p, PA_PROP_APPLICATION_ID)))
-        return pa_sprintf_malloc("%s-by-application-id:%s", prefix, r);
+        t = pa_sprintf_malloc("%s-by-application-id:%s", prefix, r);
     else if ((r = pa_proplist_gets(p, PA_PROP_APPLICATION_NAME)))
-        return pa_sprintf_malloc("%s-by-application-name:%s", prefix, r);
+        t = pa_sprintf_malloc("%s-by-application-name:%s", prefix, r);
     else if ((r = pa_proplist_gets(p, PA_PROP_MEDIA_NAME)))
-        return pa_sprintf_malloc("%s-by-media-name:%s", prefix, r);
+        t = pa_sprintf_malloc("%s-by-media-name:%s", prefix, r);
+    else
+        t = pa_sprintf_malloc("%s-fallback:%s", prefix, r);
 
-    return pa_sprintf_malloc("%s-fallback:%s", prefix, r);
+    pa_proplist_sets(p, IDENTIFICATION_PROPERTY, t);
+    return t;
 }
 
 static struct entry* read_entry(struct userdata *u, const char *name) {

commit 3fc12330627488ab7632d501e3976769275cf709
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Feb 4 22:41:45 2009 +0100

    add a .mailmap file for git shortlog

diff --git a/.mailmap b/.mailmap
new file mode 100644
index 0000000..0b99ec6
--- /dev/null
+++ b/.mailmap
@@ -0,0 +1,7 @@
+Diego Elio Pettenò <flameeyes at gmail.com>
+Lennart Poettering <mzfuryy at 0pointer.net>
+Lennart Poettering <lennart at poettering.net>
+Russ Dill <Russ.Dill at asu.edu>
+Russ Dill <russ.dill at gmail.com>
+Sjoerd Simons <sjoerd at luon.net>
+Sjoerd Simons <sjoerd at debian.org>

commit de86c6e3ade17c3b29fd57afb47efb3a88a423d4
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Feb 5 01:22:05 2009 +0100

    add a 'volume factor' that is implicitly multiplied into the volume of a sink input without being visible to the outside

diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index df42cae..37d40eb 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -79,6 +79,18 @@ void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cv
         data->volume = *volume;
 }
 
+void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data *data, const pa_cvolume *volume_factor) {
+    pa_assert(data);
+    pa_assert(volume_factor);
+
+    if (data->volume_factor_is_set)
+        pa_sw_cvolume_multiply(&data->volume_factor, &data->volume_factor, volume_factor);
+    else {
+        data->volume_factor_is_set = TRUE;
+        data->volume_factor = *volume_factor;
+    }
+}
+
 void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mute) {
     pa_assert(data);
 
@@ -171,12 +183,17 @@ int pa_sink_input_new(
             pa_cvolume_reset(&data->volume, data->sample_spec.channels);
 
         data->save_volume = FALSE;
-
     }
 
     pa_return_val_if_fail(pa_cvolume_valid(&data->volume), -PA_ERR_INVALID);
     pa_return_val_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec), -PA_ERR_INVALID);
 
+    if (!data->volume_factor_is_set)
+        pa_cvolume_reset(&data->volume_factor, data->sample_spec.channels);
+
+    pa_return_val_if_fail(pa_cvolume_valid(&data->volume_factor), -PA_ERR_INVALID);
+    pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor, &data->sample_spec), -PA_ERR_INVALID);
+
     if (!data->muted_is_set)
         data->muted = FALSE;
 
@@ -259,6 +276,7 @@ int pa_sink_input_new(
     } else
         i->virtual_volume = data->volume;
 
+    i->volume_factor = data->volume_factor;
     pa_cvolume_init(&i->soft_volume);
     i->save_volume = data->save_volume;
     i->save_sink = data->save_sink;
@@ -500,7 +518,7 @@ void pa_sink_input_put(pa_sink_input *i) {
         pa_sink_update_flat_volume(i->sink, &new_volume);
         pa_sink_set_volume(i->sink, &new_volume, FALSE, FALSE);
     } else
-        i->soft_volume = i->virtual_volume;
+        pa_sw_cvolume_multiply(&i->soft_volume, &i->virtual_volume, &i->volume_factor);
 
     i->thread_info.soft_volume = i->soft_volume;
     i->thread_info.muted = i->muted;
@@ -874,8 +892,7 @@ void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_boo
 
         /* OK, we are in normal volume mode. The volume only affects
          * ourselves */
-
-        i->soft_volume = *volume;
+        pa_sw_cvolume_multiply(&i->soft_volume, volume, &i->volume_factor);
 
         /* Hooks have the ability to play games with i->soft_volume */
         pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SET_VOLUME], i);
@@ -1066,7 +1083,7 @@ int pa_sink_input_start_move(pa_sink_input *i) {
 
         /* Make the absolute volume relative */
         i->virtual_volume = i->soft_volume;
-        pa_cvolume_reset(&i->soft_volume, i->sample_spec.channels);
+        i->soft_volume = i->volume_factor;
 
         /* We might need to update the sink's volume if we are in flat
          * volume mode. */
diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h
index f6c5aa1..889ee84 100644
--- a/src/pulsecore/sink-input.h
+++ b/src/pulsecore/sink-input.h
@@ -91,7 +91,7 @@ struct pa_sink_input {
 
     pa_sink_input *sync_prev, *sync_next;
 
-    pa_cvolume virtual_volume, soft_volume;
+    pa_cvolume virtual_volume, soft_volume, volume_factor;
     pa_bool_t muted:1;
 
     /* if TRUE then the source we are connected to and/or the volume
@@ -233,13 +233,13 @@ typedef struct pa_sink_input_new_data {
     pa_sample_spec sample_spec;
     pa_channel_map channel_map;
 
-    pa_cvolume volume;
+    pa_cvolume volume, volume_factor;
     pa_bool_t muted:1;
 
     pa_bool_t sample_spec_is_set:1;
     pa_bool_t channel_map_is_set:1;
 
-    pa_bool_t volume_is_set:1;
+    pa_bool_t volume_is_set:1, volume_factor_is_set:1;
     pa_bool_t muted_is_set:1;
 
     pa_bool_t volume_is_absolute:1;
@@ -251,6 +251,7 @@ pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data
 void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data *data, const pa_sample_spec *spec);
 void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data *data, const pa_channel_map *map);
 void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume);
+void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data *data, const pa_cvolume *volume_factor);
 void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mute);
 void pa_sink_input_new_data_done(pa_sink_input_new_data *data);
 
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index 0c297ec..5772587 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -990,6 +990,7 @@ void pa_sink_update_flat_volume(pa_sink *s, pa_cvolume *new_volume) {
         remapped_new_volume = *new_volume;
         pa_cvolume_remap(&remapped_new_volume, &s->channel_map, &i->channel_map);
         pa_sw_cvolume_divide(&i->soft_volume, &i->virtual_volume, &remapped_new_volume);
+        pa_sw_cvolume_multiply(&i->soft_volume, &i->soft_volume, &i->volume_factor);
 
         /* Hooks have the ability to play games with i->soft_volume */
         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_INPUT_SET_VOLUME], i);

commit f6ffd2dd5a019e6ea5b2cbd1d19c3a4417043e59
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Feb 5 01:22:57 2009 +0100

    make module-position-event-sounds use volume factor

diff --git a/src/modules/module-position-event-sounds.c b/src/modules/module-position-event-sounds.c
index e17cbe8..6252eba 100644
--- a/src/modules/module-position-event-sounds.c
+++ b/src/modules/module-position-event-sounds.c
@@ -54,7 +54,6 @@ static const char* const valid_modargs[] = {
 };
 
 struct userdata {
-    pa_core *core;
     pa_hook_slot *sink_input_fixate_hook_slot;
 };
 
@@ -62,6 +61,7 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *core, pa_sink_i
     const char *hpos;
     double f;
     char t[PA_CVOLUME_SNPRINT_MAX];
+    pa_cvolume v;
 
     pa_assert(data);
 
@@ -80,16 +80,12 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *core, pa_sink_i
 
     pa_log_debug("Positioning event sound '%s' at %0.2f.", pa_strnull(pa_proplist_gets(data->proplist, PA_PROP_EVENT_ID)), f);
 
-    if (!data->volume_is_set) {
-        pa_cvolume_reset(&data->volume, data->sample_spec.channels);
-        data->volume_is_set = TRUE;
-        data->volume_is_absolute = FALSE;
-    }
+    pa_cvolume_reset(&v, data->sample_spec.channels);
+    pa_cvolume_set_balance(&v, &data->channel_map, f*2.0-1.0);
 
-    pa_cvolume_set_balance(&data->volume, &data->channel_map, f*2.0-1.0);
-    data->save_volume = FALSE;
+    pa_log_debug("Final volume factor %s.", pa_cvolume_snprint(t, sizeof(t), &v));
 
-    pa_log_debug("Final volume %s.", pa_cvolume_snprint(t, sizeof(t), &data->volume));
+    pa_sink_input_new_data_apply_volume_factor(data, &v);
 
     return PA_HOOK_OK;
 }
@@ -106,7 +102,6 @@ int pa__init(pa_module*m) {
     }
 
     m->userdata = u = pa_xnew(struct userdata, 1);
-    u->core = m->core;
     u->sink_input_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_fixate_hook_callback, u);
 
     pa_modargs_free(ma);

commit 63e234335fd3362328db34cfc59d27e9899db82b
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Feb 5 04:05:47 2009 +0100

    handle default volume initialization properly

diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 37d40eb..fa2a383 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -179,8 +179,11 @@ int pa_sink_input_new(
         if (data->sink->flags & PA_SINK_FLAT_VOLUME) {
             data->volume = *pa_sink_get_volume(data->sink, FALSE);
             pa_cvolume_remap(&data->volume, &data->sink->channel_map, &data->channel_map);
-        } else
+            data->volume_is_absolute = TRUE;
+        } else {
             pa_cvolume_reset(&data->volume, data->sample_spec.channels);
+            data->volume_is_absolute = FALSE;
+        }
 
         data->save_volume = FALSE;
     }

commit a67406db936d3db85b819a1126d858c9efe672c2
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Feb 5 04:06:50 2009 +0100

    add pa_client_update_proplist() call

diff --git a/src/pulsecore/client.c b/src/pulsecore/client.c
index 1800441..6f3e08e 100644
--- a/src/pulsecore/client.c
+++ b/src/pulsecore/client.c
@@ -126,8 +126,21 @@ void pa_client_kill(pa_client *c) {
 
 void pa_client_set_name(pa_client *c, const char *name) {
     pa_assert(c);
+    pa_assert(name);
 
     pa_log_info("Client %u changed name from \"%s\" to \"%s\"", c->index, pa_strnull(pa_proplist_gets(c->proplist, PA_PROP_APPLICATION_NAME)), name);
     pa_proplist_sets(c->proplist, PA_PROP_APPLICATION_NAME, name);
+
+    pa_hook_fire(&c->core->hooks[PA_CORE_HOOK_CLIENT_PROPLIST_CHANGED], c);
+    pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_CHANGE, c->index);
+}
+
+void pa_client_update_proplist(pa_client *c, pa_update_mode_t mode, pa_proplist *p) {
+    pa_assert(c);
+    pa_assert(p);
+
+    pa_proplist_update(c->proplist, mode, p);
+
+    pa_hook_fire(&c->core->hooks[PA_CORE_HOOK_CLIENT_PROPLIST_CHANGED], c);
     pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_CHANGE, c->index);
 }
diff --git a/src/pulsecore/client.h b/src/pulsecore/client.h
index 48e9bc7..8ac80dd 100644
--- a/src/pulsecore/client.h
+++ b/src/pulsecore/client.h
@@ -71,4 +71,6 @@ void pa_client_kill(pa_client *c);
 /* Rename the client */
 void pa_client_set_name(pa_client *c, const char *name);
 
+void pa_client_update_proplist(pa_client *c, pa_update_mode_t mode, pa_proplist *p);
+
 #endif

commit f42afc4883f4a6670e6fff7719beeca481831f9b
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Feb 5 04:07:27 2009 +0100

    make return value of pa_{sink_input|source_output}_update_proplist() void

diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index fa2a383..9c0bf76 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -940,18 +940,16 @@ pa_bool_t pa_sink_input_get_mute(pa_sink_input *i) {
 }
 
 /* Called from main thread */
-pa_bool_t pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_proplist *p) {
-
-  pa_sink_input_assert_ref(i);
-
-  pa_proplist_update(i->proplist, mode, p);
+void pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_proplist *p) {
+    pa_sink_input_assert_ref(i);
+    pa_assert(p);
 
-  if (PA_SINK_IS_LINKED(i->state)) {
-      pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i);
-      pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
-  }
+    pa_proplist_update(i->proplist, mode, p);
 
-  return TRUE;
+    if (PA_SINK_IS_LINKED(i->state)) {
+        pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i);
+        pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
+    }
 }
 
 /* Called from main context */
diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h
index 889ee84..20e2cfa 100644
--- a/src/pulsecore/sink-input.h
+++ b/src/pulsecore/sink-input.h
@@ -294,7 +294,7 @@ void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_boo
 const pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i);
 void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute, pa_bool_t save);
 pa_bool_t pa_sink_input_get_mute(pa_sink_input *i);
-pa_bool_t pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_proplist *p);
+void pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_proplist *p);
 
 pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i);
 
diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c
index 63d56d5..f2f2593 100644
--- a/src/pulsecore/source-output.c
+++ b/src/pulsecore/source-output.c
@@ -615,18 +615,16 @@ void pa_source_output_set_name(pa_source_output *o, const char *name) {
 }
 
 /* Called from main thread */
-pa_bool_t pa_source_output_update_proplist(pa_source_output *o, pa_update_mode_t mode, pa_proplist *p) {
-
-  pa_source_output_assert_ref(o);
-
-  pa_proplist_update(o->proplist, mode, p);
+void pa_source_output_update_proplist(pa_source_output *o, pa_update_mode_t mode, pa_proplist *p) {
+    pa_source_output_assert_ref(o);
+    pa_assert(p);
 
-  if (PA_SINK_IS_LINKED(o->state)) {
-    pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PROPLIST_CHANGED], o);
-    pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index);
-  }
+    pa_proplist_update(o->proplist, mode, p);
 
-  return TRUE;
+    if (PA_SINK_IS_LINKED(o->state)) {
+        pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PROPLIST_CHANGED], o);
+        pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index);
+    }
 }
 
 /* Called from main context */
diff --git a/src/pulsecore/source-output.h b/src/pulsecore/source-output.h
index 91f28f9..aba2510 100644
--- a/src/pulsecore/source-output.h
+++ b/src/pulsecore/source-output.h
@@ -229,7 +229,7 @@ void pa_source_output_kill(pa_source_output*o);
 
 pa_usec_t pa_source_output_get_latency(pa_source_output *o, pa_usec_t *source_latency);
 
-pa_bool_t pa_source_output_update_proplist(pa_source_output *o, pa_update_mode_t mode, pa_proplist *p);
+void pa_source_output_update_proplist(pa_source_output *o, pa_update_mode_t mode, pa_proplist *p);
 
 pa_resample_method_t pa_source_output_get_resample_method(pa_source_output *o);
 

commit 291589ecc1ce237b5e43d28cfd890305d815fc89
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Feb 5 04:09:09 2009 +0100

    allow overwriting of process properties with environment variables

diff --git a/src/pulsecore/proplist-util.c b/src/pulsecore/proplist-util.c
index 522c7af..c09c8af 100644
--- a/src/pulsecore/proplist-util.c
+++ b/src/pulsecore/proplist-util.c
@@ -65,11 +65,6 @@ void pa_init_proplist(pa_proplist *p) {
 
                 k = pa_xstrndup(*e+11, kl);
 
-                if (pa_proplist_contains(p, k)) {
-                    pa_xfree(k);
-                    continue;
-                }
-
                 pa_proplist_sets(p, k, *e+11+kl+1);
                 pa_xfree(k);
             }
@@ -80,7 +75,7 @@ void pa_init_proplist(pa_proplist *p) {
         pa_proplist *t;
 
         if ((t = pa_proplist_from_string(pp))) {
-            pa_proplist_update(p, PA_UPDATE_MERGE, t);
+            pa_proplist_update(p, PA_UPDATE_REPLACE, t);
             pa_proplist_free(t);
         }
     }

commit 524d78fc7af4b0d060dab5cb9f968710bf2f1835
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Feb 5 04:09:27 2009 +0100

    add missing hook

diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h
index 2b8f819..1407b1b 100644
--- a/src/pulsecore/core.h
+++ b/src/pulsecore/core.h
@@ -85,6 +85,7 @@ typedef enum pa_core_hook {
     PA_CORE_HOOK_CLIENT_NEW,
     PA_CORE_HOOK_CLIENT_PUT,
     PA_CORE_HOOK_CLIENT_UNLINK,
+    PA_CORE_HOOK_CLIENT_PROPLIST_CHANGED,
     PA_CORE_HOOK_CARD_NEW,
     PA_CORE_HOOK_CARD_PUT,
     PA_CORE_HOOK_CARD_UNLINK,

commit ee5abc3d64a1270b641f0cdbf1fdbb2ccd5e1c05
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Feb 5 04:10:08 2009 +0100

    make native protocol use pa_{sink_input|source_output|card}_update_proplist()

diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 39c834d..65b2bb9 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -2295,11 +2295,9 @@ static void command_set_client_name(pa_pdispatch *pd, uint32_t command, uint32_t
             return;
         }
 
-    pa_proplist_update(c->client->proplist, PA_UPDATE_REPLACE, p);
+    pa_client_update_proplist(c->client, PA_UPDATE_REPLACE, p);
     pa_proplist_free(p);
 
-    pa_subscription_post(c->protocol->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_CHANGE, c->client->index);
-
     reply = reply_new(tag);
 
     if (c->version >= 13)
@@ -3551,8 +3549,7 @@ static void command_update_proplist(pa_pdispatch *pd, uint32_t command, uint32_t
         CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY);
         CHECK_VALIDITY(c->pstream, playback_stream_isinstance(s), tag, PA_ERR_NOENTITY);
 
-        pa_proplist_update(s->sink_input->proplist, mode, p);
-        pa_subscription_post(c->protocol->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, s->sink_input->index);
+        pa_sink_input_update_proplist(s->sink_input, mode, p);
 
     } else if (command == PA_COMMAND_UPDATE_RECORD_STREAM_PROPLIST) {
         record_stream *s;
@@ -3560,13 +3557,11 @@ static void command_update_proplist(pa_pdispatch *pd, uint32_t command, uint32_t
         s = pa_idxset_get_by_index(c->record_streams, idx);
         CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY);
 
-        pa_proplist_update(s->source_output->proplist, mode, p);
-        pa_subscription_post(c->protocol->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, s->source_output->index);
+        pa_source_output_update_proplist(s->source_output, mode, p);
     } else {
         pa_assert(command == PA_COMMAND_UPDATE_CLIENT_PROPLIST);
 
-        pa_proplist_update(c->client->proplist, mode, p);
-        pa_subscription_post(c->protocol->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_CHANGE, c->client->index);
+        pa_client_update_proplist(c->client, mode, p);
     }
 
     pa_pstream_send_simple_ack(c->pstream, tag);

commit d6201cfc3ac2c16a4a0fc942be31ce753b9770bd
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Feb 5 04:11:26 2009 +0100

    parse ini-style sections properly

diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c
index 279fb7b..7d3b89f 100644
--- a/src/daemon/daemon-conf.c
+++ b/src/daemon/daemon-conf.c
@@ -200,7 +200,7 @@ int pa_daemon_conf_set_resample_method(pa_daemon_conf *c, const char *string) {
     return 0;
 }
 
-static int parse_log_target(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+static int parse_log_target(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
     pa_daemon_conf *c = data;
 
     pa_assert(filename);
@@ -216,7 +216,7 @@ static int parse_log_target(const char *filename, unsigned line, const char *lva
     return 0;
 }
 
-static int parse_log_level(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+static int parse_log_level(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
     pa_daemon_conf *c = data;
 
     pa_assert(filename);
@@ -232,7 +232,7 @@ static int parse_log_level(const char *filename, unsigned line, const char *lval
     return 0;
 }
 
-static int parse_resample_method(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+static int parse_resample_method(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
     pa_daemon_conf *c = data;
 
     pa_assert(filename);
@@ -248,7 +248,7 @@ static int parse_resample_method(const char *filename, unsigned line, const char
     return 0;
 }
 
-static int parse_rlimit(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+static int parse_rlimit(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
 #ifdef HAVE_SYS_RESOURCE_H
     struct pa_rlimit *r = data;
 
@@ -277,7 +277,7 @@ static int parse_rlimit(const char *filename, unsigned line, const char *lvalue,
     return 0;
 }
 
-static int parse_sample_format(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+static int parse_sample_format(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
     pa_daemon_conf *c = data;
     pa_sample_format_t f;
 
@@ -295,7 +295,7 @@ static int parse_sample_format(const char *filename, unsigned line, const char *
     return 0;
 }
 
-static int parse_sample_rate(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+static int parse_sample_rate(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
     pa_daemon_conf *c = data;
     uint32_t r;
 
@@ -313,7 +313,7 @@ static int parse_sample_rate(const char *filename, unsigned line, const char *lv
     return 0;
 }
 
-static int parse_sample_channels(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+static int parse_sample_channels(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
     pa_daemon_conf *c = data;
     int32_t n;
 
@@ -331,7 +331,7 @@ static int parse_sample_channels(const char *filename, unsigned line, const char
     return 0;
 }
 
-static int parse_fragments(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+static int parse_fragments(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
     pa_daemon_conf *c = data;
     int32_t n;
 
@@ -349,7 +349,7 @@ static int parse_fragments(const char *filename, unsigned line, const char *lval
     return 0;
 }
 
-static int parse_fragment_size_msec(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+static int parse_fragment_size_msec(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
     pa_daemon_conf *c = data;
     int32_t n;
 
@@ -367,7 +367,7 @@ static int parse_fragment_size_msec(const char *filename, unsigned line, const c
     return 0;
 }
 
-static int parse_nice_level(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+static int parse_nice_level(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
     pa_daemon_conf *c = data;
     int32_t level;
 
@@ -385,7 +385,7 @@ static int parse_nice_level(const char *filename, unsigned line, const char *lva
     return 0;
 }
 
-static int parse_rtprio(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+static int parse_rtprio(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
     pa_daemon_conf *c = data;
     int32_t rtprio;
 
@@ -409,77 +409,77 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
     unsigned i = 0;
 
     pa_config_item table[] = {
-        { "daemonize",                  pa_config_parse_bool,     NULL },
-        { "fail",                       pa_config_parse_bool,     NULL },
-        { "high-priority",              pa_config_parse_bool,     NULL },
-        { "realtime-scheduling",        pa_config_parse_bool,     NULL },
-        { "disallow-module-loading",    pa_config_parse_bool,     NULL },
-        { "disallow-exit",              pa_config_parse_bool,     NULL },
-        { "use-pid-file",               pa_config_parse_bool,     NULL },
-        { "system-instance",            pa_config_parse_bool,     NULL },
-        { "no-cpu-limit",               pa_config_parse_bool,     NULL },
-        { "disable-shm",                pa_config_parse_bool,     NULL },
-        { "flat-volumes",               pa_config_parse_bool,     NULL },
-        { "exit-idle-time",             pa_config_parse_int,      NULL },
-        { "scache-idle-time",           pa_config_parse_int,      NULL },
-        { "realtime-priority",          parse_rtprio,             NULL },
-        { "dl-search-path",             pa_config_parse_string,   NULL },
-        { "default-script-file",        pa_config_parse_string,   NULL },
-        { "log-target",                 parse_log_target,         NULL },
-        { "log-level",                  parse_log_level,          NULL },
-        { "verbose",                    parse_log_level,          NULL },
-        { "resample-method",            parse_resample_method,    NULL },
-        { "default-sample-format",      parse_sample_format,      NULL },
-        { "default-sample-rate",        parse_sample_rate,        NULL },
-        { "default-sample-channels",    parse_sample_channels,    NULL },
-        { "default-fragments",          parse_fragments,          NULL },
-        { "default-fragment-size-msec", parse_fragment_size_msec, NULL },
-        { "nice-level",                 parse_nice_level,         NULL },
-        { "disable-remixing",           pa_config_parse_bool,     NULL },
-        { "disable-lfe-remixing",       pa_config_parse_bool,     NULL },
-        { "load-default-script-file",   pa_config_parse_bool,     NULL },
-        { "shm-size-bytes",             pa_config_parse_size,     NULL },
-        { "log-meta",                   pa_config_parse_bool,     NULL },
-        { "log-time",                   pa_config_parse_bool,     NULL },
-        { "log-backtrace",              pa_config_parse_unsigned, NULL },
+        { "daemonize",                  pa_config_parse_bool,     NULL, NULL },
+        { "fail",                       pa_config_parse_bool,     NULL, NULL },
+        { "high-priority",              pa_config_parse_bool,     NULL, NULL },
+        { "realtime-scheduling",        pa_config_parse_bool,     NULL, NULL },
+        { "disallow-module-loading",    pa_config_parse_bool,     NULL, NULL },
+        { "disallow-exit",              pa_config_parse_bool,     NULL, NULL },
+        { "use-pid-file",               pa_config_parse_bool,     NULL, NULL },
+        { "system-instance",            pa_config_parse_bool,     NULL, NULL },
+        { "no-cpu-limit",               pa_config_parse_bool,     NULL, NULL },
+        { "disable-shm",                pa_config_parse_bool,     NULL, NULL },
+        { "flat-volumes",               pa_config_parse_bool,     NULL, NULL },
+        { "exit-idle-time",             pa_config_parse_int,      NULL, NULL },
+        { "scache-idle-time",           pa_config_parse_int,      NULL, NULL },
+        { "realtime-priority",          parse_rtprio,             NULL, NULL },
+        { "dl-search-path",             pa_config_parse_string,   NULL, NULL },
+        { "default-script-file",        pa_config_parse_string,   NULL, NULL },
+        { "log-target",                 parse_log_target,         NULL, NULL },
+        { "log-level",                  parse_log_level,          NULL, NULL },
+        { "verbose",                    parse_log_level,          NULL, NULL },
+        { "resample-method",            parse_resample_method,    NULL, NULL },
+        { "default-sample-format",      parse_sample_format,      NULL, NULL },
+        { "default-sample-rate",        parse_sample_rate,        NULL, NULL },
+        { "default-sample-channels",    parse_sample_channels,    NULL, NULL },
+        { "default-fragments",          parse_fragments,          NULL, NULL },
+        { "default-fragment-size-msec", parse_fragment_size_msec, NULL, NULL },
+        { "nice-level",                 parse_nice_level,         NULL, NULL },
+        { "disable-remixing",           pa_config_parse_bool,     NULL, NULL },
+        { "disable-lfe-remixing",       pa_config_parse_bool,     NULL, NULL },
+        { "load-default-script-file",   pa_config_parse_bool,     NULL, NULL },
+        { "shm-size-bytes",             pa_config_parse_size,     NULL, NULL },
+        { "log-meta",                   pa_config_parse_bool,     NULL, NULL },
+        { "log-time",                   pa_config_parse_bool,     NULL, NULL },
+        { "log-backtrace",              pa_config_parse_unsigned, NULL, NULL },
 #ifdef HAVE_SYS_RESOURCE_H
-        { "rlimit-fsize",               parse_rlimit,             NULL },
-        { "rlimit-data",                parse_rlimit,             NULL },
-        { "rlimit-stack",               parse_rlimit,             NULL },
-        { "rlimit-core",                parse_rlimit,             NULL },
-        { "rlimit-rss",                 parse_rlimit,             NULL },
+        { "rlimit-fsize",               parse_rlimit,             NULL, NULL },
+        { "rlimit-data",                parse_rlimit,             NULL, NULL },
+        { "rlimit-stack",               parse_rlimit,             NULL, NULL },
+        { "rlimit-core",                parse_rlimit,             NULL, NULL },
+        { "rlimit-rss",                 parse_rlimit,             NULL, NULL },
 #ifdef RLIMIT_NOFILE
-        { "rlimit-nofile",              parse_rlimit,             NULL },
+        { "rlimit-nofile",              parse_rlimit,             NULL, NULL },
 #endif
 #ifdef RLIMIT_AS
-        { "rlimit-as",                  parse_rlimit,             NULL },
+        { "rlimit-as",                  parse_rlimit,             NULL, NULL },
 #endif
 #ifdef RLIMIT_NPROC
-        { "rlimit-nproc",               parse_rlimit,             NULL },
+        { "rlimit-nproc",               parse_rlimit,             NULL, NULL },
 #endif
 #ifdef RLIMIT_MEMLOCK
-        { "rlimit-memlock",             parse_rlimit,             NULL },
+        { "rlimit-memlock",             parse_rlimit,             NULL, NULL },
 #endif
 #ifdef RLIMIT_LOCKS
-        { "rlimit-locks",               parse_rlimit,             NULL },
+        { "rlimit-locks",               parse_rlimit,             NULL, NULL },
 #endif
 #ifdef RLIMIT_SIGPENDING
-        { "rlimit-sigpending",          parse_rlimit,             NULL },
+        { "rlimit-sigpending",          parse_rlimit,             NULL, NULL },
 #endif
 #ifdef RLIMIT_MSGQUEUE
-        { "rlimit-msgqueue",            parse_rlimit,             NULL },
+        { "rlimit-msgqueue",            parse_rlimit,             NULL, NULL },
 #endif
 #ifdef RLIMIT_NICE
-        { "rlimit-nice",                parse_rlimit,             NULL },
+        { "rlimit-nice",                parse_rlimit,             NULL, NULL },
 #endif
 #ifdef RLIMIT_RTPRIO
-        { "rlimit-rtprio",              parse_rlimit,             NULL },
+        { "rlimit-rtprio",              parse_rlimit,             NULL, NULL },
 #endif
 #ifdef RLIMIT_RTTIME
-        { "rlimit-rttime",              parse_rlimit,             NULL },
+        { "rlimit-rttime",              parse_rlimit,             NULL, NULL },
 #endif
 #endif
-        { NULL,                         NULL,                     NULL },
+        { NULL,                         NULL,                     NULL, NULL },
     };
 
     table[i++].data = &c->daemonize;
diff --git a/src/pulse/client-conf.c b/src/pulse/client-conf.c
index 58d6464..71f8443 100644
--- a/src/pulse/client-conf.c
+++ b/src/pulse/client-conf.c
@@ -92,16 +92,16 @@ int pa_client_conf_load(pa_client_conf *c, const char *filename) {
 
     /* Prepare the configuration parse table */
     pa_config_item table[] = {
-        { "daemon-binary",          pa_config_parse_string,  NULL },
-        { "extra-arguments",        pa_config_parse_string,  NULL },
-        { "default-sink",           pa_config_parse_string,  NULL },
-        { "default-source",         pa_config_parse_string,  NULL },
-        { "default-server",         pa_config_parse_string,  NULL },
-        { "autospawn",              pa_config_parse_bool,    NULL },
-        { "cookie-file",            pa_config_parse_string,  NULL },
-        { "disable-shm",            pa_config_parse_bool,    NULL },
-        { "shm-size-bytes",         pa_config_parse_size,    NULL },
-        { NULL,                     NULL,                    NULL },
+        { "daemon-binary",          pa_config_parse_string,  NULL, NULL },
+        { "extra-arguments",        pa_config_parse_string,  NULL, NULL },
+        { "default-sink",           pa_config_parse_string,  NULL, NULL },
+        { "default-source",         pa_config_parse_string,  NULL, NULL },
+        { "default-server",         pa_config_parse_string,  NULL, NULL },
+        { "autospawn",              pa_config_parse_bool,    NULL, NULL },
+        { "cookie-file",            pa_config_parse_string,  NULL, NULL },
+        { "disable-shm",            pa_config_parse_bool,    NULL, NULL },
+        { "shm-size-bytes",         pa_config_parse_size,    NULL, NULL },
+        { NULL,                     NULL,                    NULL, NULL },
     };
 
     table[0].data = &c->daemon_binary;
diff --git a/src/pulsecore/conf-parser.c b/src/pulsecore/conf-parser.c
index ef6d6bb..b7ec2b3 100644
--- a/src/pulsecore/conf-parser.c
+++ b/src/pulsecore/conf-parser.c
@@ -40,17 +40,19 @@
 #define COMMENTS "#;\n"
 
 /* Run the user supplied parser for an assignment */
-static int next_assignment(const char *filename, unsigned line, const pa_config_item *t, const char *lvalue, const char *rvalue, void *userdata) {
+static int next_assignment(const char *filename, unsigned line, const char *section, const pa_config_item *t, const char *lvalue, const char *rvalue, void *userdata) {
     pa_assert(filename);
     pa_assert(t);
     pa_assert(lvalue);
     pa_assert(rvalue);
 
     for (; t->parse; t++)
-        if (!strcmp(lvalue, t->lvalue))
-            return t->parse(filename, line, lvalue, rvalue, t->data, userdata);
+        if (!t->lvalue ||
+            (pa_streq(lvalue, t->lvalue) &&
+             ((!section && !t->section) || pa_streq(section, t->section))))
+            return t->parse(filename, line, section, lvalue, rvalue, t->data, userdata);
 
-    pa_log("[%s:%u] Unknown lvalue '%s'.", filename, line, lvalue);
+    pa_log("[%s:%u] Unknown lvalue '%s' in section '%s'.", filename, line, lvalue, pa_strnull(section));
 
     return -1;
 }
@@ -83,8 +85,10 @@ static char *strip(char *s) {
 }
 
 /* Parse a variable assignment line */
-static int parse_line(const char *filename, unsigned line, const pa_config_item *t, char *l, void *userdata) {
-    char *e, *c, *b = l+strspn(l, WHITESPACE);
+static int parse_line(const char *filename, unsigned line, char **section, const pa_config_item *t, char *l, void *userdata) {
+    char *e, *c, *b;
+
+    b = l+strspn(l, WHITESPACE);
 
     if ((c = strpbrk(b, COMMENTS)))
         *c = 0;
@@ -92,6 +96,22 @@ static int parse_line(const char *filename, unsigned line, const pa_config_item
     if (!*b)
         return 0;
 
+    if (*b == '[') {
+        size_t k;
+
+        k = strlen(b);
+        pa_assert(k > 0);
+
+        if (b[k-1] != ']') {
+            pa_log("[%s:%u] Invalid section header.", filename, line);
+            return -1;
+        }
+
+        pa_xfree(*section);
+        *section = pa_xstrndup(b+1, k-2);
+        return 0;
+    }
+
     if (!(e = strchr(b, '='))) {
         pa_log("[%s:%u] Missing '='.", filename, line);
         return -1;
@@ -100,7 +120,7 @@ static int parse_line(const char *filename, unsigned line, const pa_config_item
     *e = 0;
     e++;
 
-    return next_assignment(filename, line, t, strip(b), strip(e), userdata);
+    return next_assignment(filename, line, *section, t, strip(b), strip(e), userdata);
 }
 
 /* Go through the file and parse each line */
@@ -108,6 +128,7 @@ int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void
     int r = -1;
     unsigned line = 0;
     int do_close = !f;
+    char *section = NULL;
 
     pa_assert(filename);
     pa_assert(t);
@@ -118,29 +139,29 @@ int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void
             goto finish;
         }
 
-        pa_log_warn("Failed to open configuration file '%s': %s",
-            filename, pa_cstrerror(errno));
+        pa_log_warn("Failed to open configuration file '%s': %s", filename, pa_cstrerror(errno));
         goto finish;
     }
 
     while (!feof(f)) {
         char l[256];
+
         if (!fgets(l, sizeof(l), f)) {
             if (feof(f))
                 break;
 
-            pa_log_warn("Failed to read configuration file '%s': %s",
-                filename, pa_cstrerror(errno));
+            pa_log_warn("Failed to read configuration file '%s': %s", filename, pa_cstrerror(errno));
             goto finish;
         }
 
-        if (parse_line(filename, ++line, t,  l, userdata) < 0)
+        if (parse_line(filename, ++line, &section, t, l, userdata) < 0)
             goto finish;
     }
 
     r = 0;
 
 finish:
+    pa_xfree(section);
 
     if (do_close && f)
         fclose(f);
@@ -148,7 +169,7 @@ finish:
     return r;
 }
 
-int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+int pa_config_parse_int(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
     int *i = data;
     int32_t k;
 
@@ -166,7 +187,7 @@ int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue,
     return 0;
 }
 
-int pa_config_parse_unsigned(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+int pa_config_parse_unsigned(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
     unsigned *u = data;
     uint32_t k;
 
@@ -184,7 +205,7 @@ int pa_config_parse_unsigned(const char *filename, unsigned line, const char *lv
     return 0;
 }
 
-int pa_config_parse_size(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+int pa_config_parse_size(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
     size_t *i = data;
     uint32_t k;
 
@@ -202,7 +223,7 @@ int pa_config_parse_size(const char *filename, unsigned line, const char *lvalue
     return 0;
 }
 
-int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+int pa_config_parse_bool(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
     int k;
     pa_bool_t *b = data;
 
@@ -221,7 +242,7 @@ int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue
     return 0;
 }
 
-int pa_config_parse_string(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+int pa_config_parse_string(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
     char **s = data;
 
     pa_assert(filename);
diff --git a/src/pulsecore/conf-parser.h b/src/pulsecore/conf-parser.h
index 48a0fd2..f8f059f 100644
--- a/src/pulsecore/conf-parser.h
+++ b/src/pulsecore/conf-parser.h
@@ -27,11 +27,14 @@
 /* An abstract parser for simple, line based, shallow configuration
  * files consisting of variable assignments only. */
 
+typedef int (*pa_config_parser_cb_t)(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata);
+
 /* Wraps info for parsing a specific configuration variable */
 typedef struct pa_config_item {
     const char *lvalue; /* name of the variable */
-    int (*parse)(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata); /* Function that is called to parse the variable's value */
+    pa_config_parser_cb_t parse; /* Function that is called to parse the variable's value */
     void *data; /* Where to store the variable's data */
+    const char *section;
 } pa_config_item;
 
 /* The configuration file parsing routine. Expects a table of
@@ -40,10 +43,10 @@ typedef struct pa_config_item {
 int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void *userdata);
 
 /* Generic parsers for integers, size_t, booleans and strings */
-int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata);
-int pa_config_parse_unsigned(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata);
-int pa_config_parse_size(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata);
-int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata);
-int pa_config_parse_string(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata);
+int pa_config_parse_int(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata);
+int pa_config_parse_unsigned(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata);
+int pa_config_parse_size(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata);
+int pa_config_parse_bool(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata);
+int pa_config_parse_string(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata);
 
 #endif

commit 9f39a44488644e8d54e9c8a4096abf2d39040c1f
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Feb 5 04:14:30 2009 +0100

    add new module-augment-properties module for augmenting properties from .desktop files

diff --git a/src/Makefile.am b/src/Makefile.am
index 1910a82..ca8240f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -895,7 +895,8 @@ modlibexec_LTLIBRARIES += \
 		module-esound-sink.la \
 		module-tunnel-sink.la \
 		module-tunnel-source.la \
-		module-position-event-sounds.la
+		module-position-event-sounds.la \
+		module-augment-properties.la
 
 
 # See comment at librtp.la above
@@ -1084,6 +1085,7 @@ SYMDEF_FILES = \
 		modules/module-raop-discover-symdef.h \
 		modules/gconf/module-gconf-symdef.h \
 		modules/module-position-event-sounds-symdef.h \
+		modules/module-augment-properties-symdef.h \
 		modules/module-console-kit-symdef.h
 
 EXTRA_DIST += $(SYMDEF_FILES)
@@ -1336,7 +1338,14 @@ module_volume_restore_la_CFLAGS = $(AM_CFLAGS)
 module_position_event_sounds_la_SOURCES = modules/module-position-event-sounds.c
 module_position_event_sounds_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_position_event_sounds_la_LIBADD = $(AM_LIBADD) libpulsecore- at PA_MAJORMINORMICRO@.la libpulsecommon- at PA_MAJORMINORMICRO@.la libpulse.la
-module_position_event_sounds_CFLAGS = $(AM_CFLAGS)
+module_position_event_sounds_la_CFLAGS = $(AM_CFLAGS)
+
+# Augment properties from XDG .desktop files
+module_augment_properties_la_SOURCES = modules/module-augment-properties.c
+module_augment_properties_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_augment_properties_la_LIBADD = $(AM_LIBADD) libpulsecore- at PA_MAJORMINORMICRO@.la libpulsecommon- at PA_MAJORMINORMICRO@.la libpulse.la
+#module_augment_properties_la_CFLAGS = $(AM_CFLAGS) -DDESKTOPFILEDIR=\"$(datadir)/applications\"
+module_augment_properties_la_CFLAGS = $(AM_CFLAGS) -DDESKTOPFILEDIR=\"/usr/share/applications\"
 
 # Device volume/muted restore module
 module_device_restore_la_SOURCES = modules/module-device-restore.c
diff --git a/src/daemon/default.pa.in b/src/daemon/default.pa.in
index 91a1c61..2606190 100755
--- a/src/daemon/default.pa.in
+++ b/src/daemon/default.pa.in
@@ -34,6 +34,10 @@ load-module module-device-restore
 load-module module-stream-restore
 load-module module-card-restore
 
+### Automatically augment property information from .desktop files
+### stored in /usr/share/application
+load-module module-augment-properties
+
 ### Load audio drivers statically (it's probably better to not load
 ### these drivers manually, but instead use module-hal-detect --
 ### see below -- for doing this automatically)
diff --git a/src/modules/module-augment-properties.c b/src/modules/module-augment-properties.c
new file mode 100644
index 0000000..a2475db
--- /dev/null
+++ b/src/modules/module-augment-properties.c
@@ -0,0 +1,286 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Lennart Poettering
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/stat.h>
+
+#include <pulse/xmalloc.h>
+#include <pulse/volume.h>
+#include <pulse/channelmap.h>
+
+#include <pulsecore/core-error.h>
+#include <pulsecore/module.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/log.h>
+#include <pulsecore/client.h>
+#include <pulsecore/conf-parser.h>
+
+#include "module-augment-properties-symdef.h"
+
+PA_MODULE_AUTHOR("Lennart Poettering");
+PA_MODULE_DESCRIPTION("Augment the property sets of streams with additional static information");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(TRUE);
+
+#define STAT_INTERVAL 30
+#define MAX_CACHE_SIZE 50
+
+static const char* const valid_modargs[] = {
+    NULL
+};
+
+struct rule {
+    time_t timestamp;
+    pa_bool_t good;
+    time_t mtime;
+    char *process_name;
+    char *application_name;
+    char *icon_name;
+    pa_proplist *proplist;
+};
+
+struct userdata {
+    pa_hashmap *cache;
+    pa_hook_slot *client_new_slot, *client_proplist_changed_slot;
+};
+
+static void rule_free(struct rule *r) {
+    pa_assert(r);
+
+    pa_xfree(r->process_name);
+    pa_xfree(r->application_name);
+    pa_xfree(r->icon_name);
+    if (r->proplist)
+        pa_proplist_free(r->proplist);
+    pa_xfree(r);
+}
+
+static int parse_properties(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+    struct rule *r = userdata;
+    pa_proplist *n;
+
+    if (!(n = pa_proplist_from_string(rvalue)))
+        return -1;
+
+    if (r->proplist) {
+        pa_proplist_update(r->proplist, PA_UPDATE_MERGE, n);
+        pa_proplist_free(n);
+    } else
+        r->proplist = n;
+
+    return 0;
+}
+
+static int check_type(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+    return pa_streq(rvalue, "Application") ? 0 : -1;
+}
+
+static int catch_all(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+    return 0;
+}
+
+static void update_rule(struct rule *r) {
+    char *fn;
+    struct stat st;
+    static pa_config_item table[] = {
+        { "Name", pa_config_parse_string,              NULL, "Desktop Entry" },
+        { "Icon", pa_config_parse_string,              NULL, "Desktop Entry" },
+        { "Type", check_type,                          NULL, "Desktop Entry" },
+        { "X-PulseAudio-Properties", parse_properties, NULL, "Desktop Entry" },
+        { NULL,  catch_all, NULL, NULL },
+        { NULL, NULL, NULL, NULL },
+    };
+
+    pa_assert(r);
+    fn = pa_sprintf_malloc(DESKTOPFILEDIR PA_PATH_SEP "%s.desktop", r->process_name);
+
+    if (stat(fn, &st) < 0) {
+        r->good = FALSE;
+        pa_xfree(fn);
+        return;
+    }
+
+    if (r->good && st.st_mtime == r->mtime) {
+        pa_xfree(fn);
+        return;
+    }
+
+    r->good = TRUE;
+    r->mtime = st.st_mtime;
+    pa_xfree(r->application_name);
+    pa_xfree(r->icon_name);
+    r->application_name = r->icon_name = NULL;
+    if (r->proplist)
+        pa_proplist_clear(r->proplist);
+
+    table[0].data = &r->application_name;
+    table[1].data = &r->icon_name;
+
+    if (pa_config_parse(fn, NULL, table, r) < 0)
+        pa_log_warn("Failed to parse .desktop file %s.", fn);
+
+    pa_xfree(fn);
+}
+
+static void apply_rule(struct rule *r, pa_proplist *p) {
+    pa_assert(r);
+    pa_assert(p);
+
+    if (!r->good)
+        return;
+
+    if (r->icon_name)
+        if (!pa_proplist_contains(p, PA_PROP_APPLICATION_ICON_NAME))
+            pa_proplist_sets(p, PA_PROP_APPLICATION_ICON_NAME, r->icon_name);
+
+    if (r->application_name) {
+        const char *t;
+
+        t = pa_proplist_gets(p, PA_PROP_APPLICATION_NAME);
+
+        if (!t || pa_streq(t, r->process_name))
+            pa_proplist_sets(p, PA_PROP_APPLICATION_NAME, r->application_name);
+    }
+
+    if (r->proplist)
+        pa_proplist_update(p, PA_UPDATE_MERGE, r->proplist);
+}
+
+static void make_room(pa_hashmap *cache) {
+    pa_assert(cache);
+
+    while (pa_hashmap_size(cache) >= MAX_CACHE_SIZE) {
+        struct rule *r;
+
+        pa_assert_se(r = pa_hashmap_steal_first(cache));
+        rule_free(r);
+    }
+}
+
+static pa_hook_result_t process(struct userdata *u, pa_proplist *p) {
+    struct rule *r;
+    time_t now;
+    const char *pn;
+
+    pa_assert(u);
+    pa_assert(p);
+
+    if (!(pn = pa_proplist_gets(p, PA_PROP_APPLICATION_PROCESS_BINARY)))
+        return PA_HOOK_OK;
+
+    if (*pn == '.' || strchr(pn, '/'))
+        return PA_HOOK_OK;
+
+    time(&now);
+
+    if ((r = pa_hashmap_get(u->cache, pn))) {
+        if (now-r->timestamp > STAT_INTERVAL) {
+            r->timestamp = now;
+            update_rule(r);
+        }
+    } else {
+        make_room(u->cache);
+
+        r = pa_xnew0(struct rule, 1);
+        r->process_name = pa_xstrdup(pn);
+        r->timestamp = now;
+        pa_hashmap_put(u->cache, r->process_name, r);
+        update_rule(r);
+    }
+
+    apply_rule(r, p);
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t client_new_cb(pa_core *core, pa_client_new_data *data, struct userdata *u) {
+    pa_core_assert_ref(core);
+    pa_assert(data);
+    pa_assert(u);
+
+    return process(u, data->proplist);
+}
+
+static pa_hook_result_t client_proplist_changed_cb(pa_core *core, pa_client *client, struct userdata *u) {
+    pa_core_assert_ref(core);
+    pa_assert(client);
+    pa_assert(u);
+
+    return process(u, client->proplist);
+}
+
+int pa__init(pa_module*m) {
+    pa_modargs *ma = NULL;
+    struct userdata *u;
+
+    pa_assert(m);
+
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log("Failed to parse module arguments");
+        goto fail;
+    }
+
+    m->userdata = u = pa_xnew(struct userdata, 1);
+
+    u->cache = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    u->client_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_CLIENT_NEW], PA_HOOK_EARLY, (pa_hook_cb_t) client_new_cb, u);
+    u->client_proplist_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_CLIENT_PROPLIST_CHANGED], PA_HOOK_EARLY, (pa_hook_cb_t) client_proplist_changed_cb, u);
+
+    pa_modargs_free(ma);
+
+    return 0;
+
+fail:
+    pa__done(m);
+
+    if (ma)
+        pa_modargs_free(ma);
+
+    return  -1;
+}
+
+void pa__done(pa_module*m) {
+    struct userdata* u;
+
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    if (u->client_new_slot)
+        pa_hook_slot_free(u->client_new_slot);
+    if (u->client_proplist_changed_slot)
+        pa_hook_slot_free(u->client_proplist_changed_slot);
+
+    if (u->cache) {
+        struct rule *r;
+
+        while ((r = pa_hashmap_steal_first(u->cache)))
+            rule_free(r);
+
+        pa_hashmap_free(u->cache, NULL, NULL);
+    }
+
+    pa_xfree(u);
+}
diff --git a/src/modules/module-match.c b/src/modules/module-match.c
index cbf6268..1793611 100644
--- a/src/modules/module-match.c
+++ b/src/modules/module-match.c
@@ -233,7 +233,6 @@ int pa__init(pa_module*m) {
         goto fail;
     }
 
-
     u = pa_xnew(struct userdata, 1);
     u->rules = NULL;
     u->subscription = NULL;

commit 04c3c6716b20ca8362ceea3d2e7fa23954f9a441
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Feb 6 00:25:47 2009 +0100

    A few MacOS X portability fixes
    
    Based on patches contributed by "Tron".
    
    See bug #478.

diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index b7ebdeb..ad6c6ca 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -88,6 +88,10 @@
 #include <samplerate.h>
 #endif
 
+#ifdef __APPLE__
+#include <xlocale.h>
+#endif
+
 #include <pulse/xmalloc.h>
 #include <pulse/util.h>
 #include <pulse/utf8.h>
diff --git a/src/pulsecore/proplist-util.c b/src/pulsecore/proplist-util.c
index c09c8af..8a447cf 100644
--- a/src/pulsecore/proplist-util.c
+++ b/src/pulsecore/proplist-util.c
@@ -27,6 +27,13 @@
 #include <locale.h>
 #include <dlfcn.h>
 
+#ifdef __APPLE__
+#include <crt_externs.h>
+#define environ (*_NSGetEnviron())
+#elif !HAVE_DECL_ENVIRON
+extern char **environ;
+#endif
+
 #include <pulse/proplist.h>
 #include <pulse/utf8.h>
 #include <pulse/xmalloc.h>
@@ -37,9 +44,6 @@
 #include "proplist-util.h"
 
 void pa_init_proplist(pa_proplist *p) {
-#if !HAVE_DECL_ENVIRON
-    extern char **environ;
-#endif
     char **e;
     const char *pp;
 

commit 6bb2c49057338fc88fd3846b34911878aec65b12
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Feb 6 02:01:17 2009 +0100

    add #defines for all enums that lacked it

diff --git a/src/pulse/channelmap.h b/src/pulse/channelmap.h
index f9124b2..a6d37d8 100644
--- a/src/pulse/channelmap.h
+++ b/src/pulse/channelmap.h
@@ -141,6 +141,66 @@ typedef enum pa_channel_position {
     PA_CHANNEL_POSITION_MAX
 } pa_channel_position_t;
 
+/** \cond fulldocs */
+#define PA_CHANNEL_POSITION_INVALID PA_CHANNEL_POSITION_INVALID
+#define PA_CHANNEL_POSITION_MONO PA_CHANNEL_POSITION_MONO
+#define PA_CHANNEL_POSITION_LEFT PA_CHANNEL_POSITION_LEFT
+#define PA_CHANNEL_POSITION_RIGHT PA_CHANNEL_POSITION_RIGHT
+#define PA_CHANNEL_POSITION_CENTER PA_CHANNEL_POSITION_CENTER
+#define PA_CHANNEL_POSITION_FRONT_LEFT PA_CHANNEL_POSITION_FRONT_LEFT
+#define PA_CHANNEL_POSITION_FRONT_RIGHT PA_CHANNEL_POSITION_FRONT_RIGHT
+#define PA_CHANNEL_POSITION_FRONT_CENTER PA_CHANNEL_POSITION_FRONT_CENTER
+#define PA_CHANNEL_POSITION_REAR_CENTER PA_CHANNEL_POSITION_REAR_CENTER
+#define PA_CHANNEL_POSITION_REAR_LEFT PA_CHANNEL_POSITION_REAR_LEFT
+#define PA_CHANNEL_POSITION_REAR_RIGHT PA_CHANNEL_POSITION_REAR_RIGHT
+#define PA_CHANNEL_POSITION_LFE PA_CHANNEL_POSITION_LFE
+#define PA_CHANNEL_POSITION_SUBWOOFER PA_CHANNEL_POSITION_SUBWOOFER
+#define PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
+#define PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
+#define PA_CHANNEL_POSITION_SIDE_LEFT PA_CHANNEL_POSITION_SIDE_LEFT
+#define PA_CHANNEL_POSITION_SIDE_RIGHT PA_CHANNEL_POSITION_SIDE_RIGHT
+#define PA_CHANNEL_POSITION_AUX0 PA_CHANNEL_POSITION_AUX0
+#define PA_CHANNEL_POSITION_AUX1 PA_CHANNEL_POSITION_AUX1
+#define PA_CHANNEL_POSITION_AUX2 PA_CHANNEL_POSITION_AUX2
+#define PA_CHANNEL_POSITION_AUX3 PA_CHANNEL_POSITION_AUX3
+#define PA_CHANNEL_POSITION_AUX4 PA_CHANNEL_POSITION_AUX4
+#define PA_CHANNEL_POSITION_AUX5 PA_CHANNEL_POSITION_AUX5
+#define PA_CHANNEL_POSITION_AUX6 PA_CHANNEL_POSITION_AUX6
+#define PA_CHANNEL_POSITION_AUX7 PA_CHANNEL_POSITION_AUX7
+#define PA_CHANNEL_POSITION_AUX8 PA_CHANNEL_POSITION_AUX8
+#define PA_CHANNEL_POSITION_AUX9 PA_CHANNEL_POSITION_AUX9
+#define PA_CHANNEL_POSITION_AUX10 PA_CHANNEL_POSITION_AUX10
+#define PA_CHANNEL_POSITION_AUX11 PA_CHANNEL_POSITION_AUX11
+#define PA_CHANNEL_POSITION_AUX12 PA_CHANNEL_POSITION_AUX12
+#define PA_CHANNEL_POSITION_AUX13 PA_CHANNEL_POSITION_AUX13
+#define PA_CHANNEL_POSITION_AUX14 PA_CHANNEL_POSITION_AUX14
+#define PA_CHANNEL_POSITION_AUX15 PA_CHANNEL_POSITION_AUX15
+#define PA_CHANNEL_POSITION_AUX16 PA_CHANNEL_POSITION_AUX16
+#define PA_CHANNEL_POSITION_AUX17 PA_CHANNEL_POSITION_AUX17
+#define PA_CHANNEL_POSITION_AUX18 PA_CHANNEL_POSITION_AUX18
+#define PA_CHANNEL_POSITION_AUX19 PA_CHANNEL_POSITION_AUX19
+#define PA_CHANNEL_POSITION_AUX20 PA_CHANNEL_POSITION_AUX20
+#define PA_CHANNEL_POSITION_AUX21 PA_CHANNEL_POSITION_AUX21
+#define PA_CHANNEL_POSITION_AUX22 PA_CHANNEL_POSITION_AUX22
+#define PA_CHANNEL_POSITION_AUX23 PA_CHANNEL_POSITION_AUX23
+#define PA_CHANNEL_POSITION_AUX24 PA_CHANNEL_POSITION_AUX24
+#define PA_CHANNEL_POSITION_AUX25 PA_CHANNEL_POSITION_AUX25
+#define PA_CHANNEL_POSITION_AUX26 PA_CHANNEL_POSITION_AUX26
+#define PA_CHANNEL_POSITION_AUX27 PA_CHANNEL_POSITION_AUX27
+#define PA_CHANNEL_POSITION_AUX28 PA_CHANNEL_POSITION_AUX28
+#define PA_CHANNEL_POSITION_AUX29 PA_CHANNEL_POSITION_AUX29
+#define PA_CHANNEL_POSITION_AUX30 PA_CHANNEL_POSITION_AUX30
+#define PA_CHANNEL_POSITION_AUX31 PA_CHANNEL_POSITION_AUX31
+#define PA_CHANNEL_POSITION_TOP_CENTER PA_CHANNEL_POSITION_TOP_CENTER
+#define PA_CHANNEL_POSITION_TOP_FRONT_LEFT PA_CHANNEL_POSITION_TOP_FRONT_LEFT
+#define PA_CHANNEL_POSITION_TOP_FRONT_RIGHT PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
+#define PA_CHANNEL_POSITION_TOP_FRONT_CENTER PA_CHANNEL_POSITION_TOP_FRONT_CENTER
+#define PA_CHANNEL_POSITION_TOP_REAR_LEFT PA_CHANNEL_POSITION_TOP_REAR_LEFT
+#define PA_CHANNEL_POSITION_TOP_REAR_RIGHT PA_CHANNEL_POSITION_TOP_REAR_RIGHT
+#define PA_CHANNEL_POSITION_TOP_REAR_CENTER PA_CHANNEL_POSITION_TOP_REAR_CENTER
+#define PA_CHANNEL_POSITION_MAX PA_CHANNEL_POSITION_MAX
+/** \endcond */
+
 /** A list of channel mapping definitions for pa_channel_map_init_auto() */
 typedef enum pa_channel_map_def {
     PA_CHANNEL_MAP_AIFF,
@@ -165,6 +225,16 @@ typedef enum pa_channel_map_def {
     /**< The default channel map */
 } pa_channel_map_def_t;
 
+/** \cond fulldocs */
+#define PA_CHANNEL_MAP_AIFF PA_CHANNEL_MAP_AIFF
+#define PA_CHANNEL_MAP_ALSA PA_CHANNEL_MAP_ALSA
+#define PA_CHANNEL_MAP_AUX PA_CHANNEL_MAP_AUX
+#define PA_CHANNEL_MAP_WAVEEX PA_CHANNEL_MAP_WAVEEX
+#define PA_CHANNEL_MAP_OSS PA_CHANNEL_MAP_OSS
+#define PA_CHANNEL_MAP_DEF_MAX PA_CHANNEL_MAP_DEF_MAX
+#define PA_CHANNEL_MAP_DEFAULT PA_CHANNEL_MAP_DEFAULT
+/** \endcond */
+
 /** A channel map which can be used to attach labels to specific
  * channels of a stream. These values are relevant for conversion and
  * mixing of streams */
diff --git a/src/pulse/def.h b/src/pulse/def.h
index 6149888..d4fa821 100644
--- a/src/pulse/def.h
+++ b/src/pulse/def.h
@@ -57,6 +57,12 @@ static inline int PA_CONTEXT_IS_GOOD(pa_context_state_t x) {
 }
 
 /** \cond fulldocs */
+#define PA_CONTEXT_UNCONNECTED PA_CONTEXT_UNCONNECTED
+#define PA_CONTEXT_CONNECTING PA_CONTEXT_CONNECTING
+#define PA_CONTEXT_AUTHORIZING PA_CONTEXT_AUTHORIZING
+#define PA_CONTEXT_SETTING_NAME PA_CONTEXT_SETTING_NAME
+#define PA_CONTEXT_READY PA_CONTEXT_READY
+#define PA_CONTEXT_FAILED PA_CONTEXT_FAILED
 #define PA_CONTEXT_IS_GOOD PA_CONTEXT_IS_GOOD
 /** \endcond */
 
@@ -77,6 +83,11 @@ static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x) {
 }
 
 /** \cond fulldocs */
+#define PA_STREAM_UNCONNECTED PA_STREAM_UNCONNECTED
+#define PA_STREAM_CREATING PA_STREAM_CREATING
+#define PA_STREAM_READY PA_STREAM_READY
+#define PA_STREAM_FAILED PA_STREAM_FAILED
+#define PA_STREAM_TERMINATED PA_STREAM_TERMINATED
 #define PA_STREAM_IS_GOOD PA_STREAM_IS_GOOD
 /** \endcond */
 
@@ -87,6 +98,12 @@ typedef enum pa_operation_state {
     PA_OPERATION_CANCELED      /**< The operation has been canceled */
 } pa_operation_state_t;
 
+/** \cond fulldocs */
+#define PA_OPERATION_RUNNING PA_OPERATION_RUNNING
+#define PA_OPERATION_DONE PA_OPERATION_DONE
+#define PA_OPERATION_CANCELED PA_OPERATION_CANCELED
+/** \endcond */
+
 /** An invalid index */
 #define PA_INVALID_INDEX ((uint32_t) -1)
 
@@ -109,6 +126,13 @@ typedef enum pa_stream_direction {
     PA_STREAM_UPLOAD         /**< Sample upload stream */
 } pa_stream_direction_t;
 
+/** \cond fulldocs */
+#define PA_STREAM_NODIRECTION PA_STREAM_NODIRECTION
+#define PA_STREAM_PLAYBACK PA_STREAM_PLAYBACK
+#define PA_STREAM_RECORD PA_STREAM_RECORD
+#define PA_STREAM_UPLOAD PA_STREAM_UPLOAD
+/** \endcond */
+
 /** Some special flags for stream connections. */
 typedef enum pa_stream_flags {
 
@@ -491,6 +515,36 @@ typedef enum pa_subscription_event_type {
 /** Return one if an event type t matches an event mask bitfield */
 #define pa_subscription_match_flags(m, t) (!!((m) & (1 << ((t) & PA_SUBSCRIPTION_EVENT_FACILITY_MASK))))
 
+/** \cond fulldocs */
+#define PA_SUBSCRIPTION_MASK_NULL PA_SUBSCRIPTION_MASK_NULL
+#define PA_SUBSCRIPTION_MASK_SINK PA_SUBSCRIPTION_MASK_SINK
+#define PA_SUBSCRIPTION_MASK_SOURCE PA_SUBSCRIPTION_MASK_SOURCE
+#define PA_SUBSCRIPTION_MASK_SINK_INPUT PA_SUBSCRIPTION_MASK_SINK_INPUT
+#define PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT
+#define PA_SUBSCRIPTION_MASK_MODULE PA_SUBSCRIPTION_MASK_MODULE
+#define PA_SUBSCRIPTION_MASK_CLIENT PA_SUBSCRIPTION_MASK_CLIENT
+#define PA_SUBSCRIPTION_MASK_SAMPLE_CACHE PA_SUBSCRIPTION_MASK_SAMPLE_CACHE
+#define PA_SUBSCRIPTION_MASK_SERVER PA_SUBSCRIPTION_MASK_SERVER
+#define PA_SUBSCRIPTION_MASK_AUTOLOAD PA_SUBSCRIPTION_MASK_AUTOLOAD
+#define PA_SUBSCRIPTION_MASK_CARD PA_SUBSCRIPTION_MASK_CARD
+#define PA_SUBSCRIPTION_MASK_ALL PA_SUBSCRIPTION_MASK_ALL
+#define PA_SUBSCRIPTION_EVENT_SINK PA_SUBSCRIPTION_EVENT_SINK
+#define PA_SUBSCRIPTION_EVENT_SOURCE PA_SUBSCRIPTION_EVENT_SOURCE
+#define PA_SUBSCRIPTION_EVENT_SINK_INPUT PA_SUBSCRIPTION_EVENT_SINK_INPUT
+#define PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT
+#define PA_SUBSCRIPTION_EVENT_MODULE PA_SUBSCRIPTION_EVENT_MODULE
+#define PA_SUBSCRIPTION_EVENT_CLIENT PA_SUBSCRIPTION_EVENT_CLIENT
+#define PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE
+#define PA_SUBSCRIPTION_EVENT_SERVER PA_SUBSCRIPTION_EVENT_SERVER
+#define PA_SUBSCRIPTION_EVENT_AUTOLOAD PA_SUBSCRIPTION_EVENT_AUTOLOAD
+#define PA_SUBSCRIPTION_EVENT_CARD PA_SUBSCRIPTION_EVENT_CARD
+#define PA_SUBSCRIPTION_EVENT_FACILITY_MASK PA_SUBSCRIPTION_EVENT_FACILITY_MASK
+#define PA_SUBSCRIPTION_EVENT_NEW PA_SUBSCRIPTION_EVENT_NEW
+#define PA_SUBSCRIPTION_EVENT_CHANGE PA_SUBSCRIPTION_EVENT_CHANGE
+#define PA_SUBSCRIPTION_EVENT_REMOVE PA_SUBSCRIPTION_EVENT_REMOVE
+#define PA_SUBSCRIPTION_EVENT_TYPE_MASK PA_SUBSCRIPTION_EVENT_TYPE_MASK
+/** \endcond */
+
 /** A structure for all kinds of timing information of a stream. See
  * pa_stream_update_timing_info() and pa_stream_get_timing_info(). The
  * total output latency a sample that is written with
@@ -617,6 +671,13 @@ typedef enum pa_seek_mode {
     /**< Seek relatively to the current end of the buffer queue. */
 } pa_seek_mode_t;
 
+/** \cond fulldocs */
+#define PA_SEEK_RELATIVE PA_SEEK_RELATIVE
+#define PA_SEEK_ABSOLUTE PA_SEEK_ABSOLUTE
+#define PA_SEEK_RELATIVE_ON_READ PA_SEEK_RELATIVE_ON_READ
+#define PA_SEEK_RELATIVE_END PA_SEEK_RELATIVE_END
+/** \endcond */
+
 /** Special sink flags. */
 typedef enum pa_sink_flags {
     PA_SINK_HW_VOLUME_CTRL = 0x0001U,
@@ -694,6 +755,8 @@ static inline int PA_SINK_IS_OPENED(pa_sink_state_t x) {
 #define PA_SINK_RUNNING PA_SINK_RUNNING
 #define PA_SINK_IDLE PA_SINK_IDLE
 #define PA_SINK_SUSPENDED PA_SINK_SUSPENDED
+#define PA_SINK_INIT PA_SINK_INIT
+#define PA_SINK_UNLINKED PA_SINK_UNLINKED
 #define PA_SINK_IS_OPENED PA_SINK_IS_OPENED
 /** \endcond */
 
@@ -769,6 +832,8 @@ static inline int PA_SOURCE_IS_OPENED(pa_source_state_t x) {
 #define PA_SOURCE_RUNNING PA_SOURCE_RUNNING
 #define PA_SOURCE_IDLE PA_SOURCE_IDLE
 #define PA_SOURCE_SUSPENDED PA_SOURCE_SUSPENDED
+#define PA_SOURCE_INIT PA_SOURCE_INIT
+#define PA_SOURCE_UNLINKED PA_SOURCE_UNLINKED
 #define PA_SOURCE_IS_OPENED PA_SOURCE_IS_OPENED
 /** \endcond */
 
diff --git a/src/pulse/proplist.h b/src/pulse/proplist.h
index d611406..9e78aec 100644
--- a/src/pulse/proplist.h
+++ b/src/pulse/proplist.h
@@ -194,6 +194,12 @@ typedef enum pa_update_mode {
      *  list. */
 } pa_update_mode_t;
 
+/** \cond fulldocs */
+#define PA_UPDATE_SET PA_UPDATE_SET
+#define PA_UPDATE_MERGE PA_UPDATE_MERGE
+#define PA_UPDATE_REPLACE PA_UPDATE_REPLACE
+/** \endcond */
+
 /** Merge property list "other" into "p", adhering the merge mode as
  * specified in "mode". \since 0.9.11 */
 void pa_proplist_update(pa_proplist *p, pa_update_mode_t mode, pa_proplist *other);

commit 64926ff6b3c13d75731f19d36bc056dda1c49deb
Author: Erich Boleyn <erich at uruk.org>
Date:   Fri Feb 6 02:11:07 2009 +0100

    RTP segfault/uninitialized resampler
    
    Erich Boleyn <erich at uruk.org> wrote:
    
    > Using RTP for multi-room music streaming, updated to Pulse 0.9.14 from
    > 0.9.9, RTP reception new crashes with a segfault on all machines at
    > the first "Updating sample rate" log message.
    >
    > Source of the segfault appears to be null pointer for
    > "impl_update_rates" function in resampler routine, perhaps
    > uninitialized resamplers in general?
    
    A fresh look after work made the resampler initialization code pop out.
    
    The problem is in the sink connection being made from
    "module-rtp-recv.c", the "PA_SINK_INPUT_VARIABLE_RATE" flag should be
    passed into "pa_sink_input_new", but is not there.  Made the change and
    tested it, fixes the problem.  Checked and head-of- tree off of the
    pulseaudio.org source browsing link does not have this fix either.
    
    One-liner patch attached.

diff --git a/src/modules/rtp/module-rtp-recv.c b/src/modules/rtp/module-rtp-recv.c
index baf3532..c118b5c 100644
--- a/src/modules/rtp/module-rtp-recv.c
+++ b/src/modules/rtp/module-rtp-recv.c
@@ -453,7 +453,7 @@ static struct session *session_new(struct userdata *u, const pa_sdp_info *sdp_in
     data.module = u->module;
     pa_sink_input_new_data_set_sample_spec(&data, &sdp_info->sample_spec);
 
-    pa_sink_input_new(&s->sink_input, u->module->core, &data, 0);
+    pa_sink_input_new(&s->sink_input, u->module->core, &data, PA_SINK_INPUT_VARIABLE_RATE);
     pa_sink_input_new_data_done(&data);
 
     if (!s->sink_input) {

commit 4bd9737725b85d90a7cf12b82528c2de70a7fbfe
Merge: 64926ff... 108e08c...
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Feb 6 02:15:13 2009 +0100

    Merge branch 'master-tx'
    
    Conflicts:
    	po/pl.po


-- 
hooks/post-receive
PulseAudio Sound Server



More information about the pulseaudio-commits mailing list