[pulseaudio-commits] [SCM] PulseAudio Sound Server branch, master, updated. v0.9.13-30-g2dfc265

Lennart Poettering gitmailer-noreply at 0pointer.de
Tue Oct 7 15:15:29 PDT 2008


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 branch has been updated
      from  5925d44013e2d559d1755176af0e26f69fc46458 (commit)

- Log -----------------------------------------------------------------
2dfc265... Merge branch 'flatvol'
37b8c45... query the sink volume outside of the loop because it might be quite expensive
34f6a51... use pa_sink_set_volume() for changing the volume
b048ae9... check the maximum volume of all sink inputs instead of the average volume to avoid digital amplification in favour of attenuation
404cf74... some minor reformatting
8bc58cc... ignore sinks that do not carry decibel information
776c8de... remove $Id$
b6ccea3... add a comment that pa_sink_input_set_volume and module-flat-volume.c are related
9f4033d... if a stream comes with now sensible properties attached, use common fallback db entry.
68cc299... after calling PA_CORE_HOOK_SINK_SET_VOLUME hook, check again whether the volume changed
46f73fb... additional validity checks
e053fa0... if the channel map was modified due to PA_SINK_INPUT_FIX_CHANNELS, remap the specified volume properly
e1dbc75... use pa_channel_map_init_extend() instead of pa_channel_map_init_auto() as channel map for sink inputs/source outputs in case no map is specified
ae83483... modernize a few checks
72024cd... when the volume is changed make sure we send out a subscription event
624f220... instead of resetting virtual_volume unconditionally on initialization, do so only when no volume was set before
1e513c3... Initialize exit_idle_time to -1 instead of 0  when in system mode.
80a79b1... flat-volume thingy
4541274... volume hooks
-----------------------------------------------------------------------

Summary of changes:
 src/Makefile.am                     |   10 ++-
 src/modules/module-flat-volume.c    |  224 +++++++++++++++++++++++++++++++++++
 src/modules/module-stream-restore.c |    2 +-
 src/pulsecore/core.h                |    2 +
 src/pulsecore/protocol-native.c     |    2 +-
 src/pulsecore/sink-input.c          |   52 ++++++--
 src/pulsecore/sink-input.h          |   11 ++
 src/pulsecore/sink.c                |   18 +++-
 src/pulsecore/sink.h                |    5 +
 src/pulsecore/source-output.c       |    6 +-
 10 files changed, 311 insertions(+), 21 deletions(-)
 create mode 100644 src/modules/module-flat-volume.c

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

commit 45412740b8db48722234412dc0f58284d033866e
Author: Marc-Andre Lureau <marcandre.lureau at gmail.com>
Date:   Tue Oct 7 01:37:38 2008 +0300

    volume hooks
    
    Signed-off-by: Lennart Poettering <lennart at poettering.net>

diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h
index 3955908..f796fb9 100644
--- a/src/pulsecore/core.h
+++ b/src/pulsecore/core.h
@@ -49,6 +49,7 @@ typedef enum pa_core_hook {
     PA_CORE_HOOK_SINK_UNLINK_POST,
     PA_CORE_HOOK_SINK_STATE_CHANGED,
     PA_CORE_HOOK_SINK_PROPLIST_CHANGED,
+    PA_CORE_HOOK_SINK_SET_VOLUME,
     PA_CORE_HOOK_SOURCE_NEW,
     PA_CORE_HOOK_SOURCE_FIXATE,
     PA_CORE_HOOK_SOURCE_PUT,
@@ -65,6 +66,7 @@ typedef enum pa_core_hook {
     PA_CORE_HOOK_SINK_INPUT_MOVE_POST,
     PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED,
     PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED,
+    PA_CORE_HOOK_SINK_INPUT_SET_VOLUME,
     PA_CORE_HOOK_SOURCE_OUTPUT_NEW,
     PA_CORE_HOOK_SOURCE_OUTPUT_FIXATE,
     PA_CORE_HOOK_SOURCE_OUTPUT_PUT,
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 778aab5..46dcb14 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -2722,7 +2722,7 @@ static void sink_input_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t,
     pa_tagstruct_putu32(t, s->sink->index);
     pa_tagstruct_put_sample_spec(t, &fixed_ss);
     pa_tagstruct_put_channel_map(t, &s->channel_map);
-    pa_tagstruct_put_cvolume(t, &s->volume);
+    pa_tagstruct_put_cvolume(t, pa_sink_input_get_volume(s));
     pa_tagstruct_put_usec(t, pa_sink_input_get_latency(s, &sink_latency));
     pa_tagstruct_put_usec(t, sink_latency);
     pa_tagstruct_puts(t, pa_resample_method_to_string(pa_sink_input_get_resample_method(s)));
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 4f70347..9a3c49c 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -75,7 +75,7 @@ void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cv
     pa_assert(data);
 
     if ((data->volume_is_set = !!volume))
-        data->volume = *volume;
+        data->volume = data->virtual_volume = *volume;
 }
 
 void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mute) {
@@ -156,6 +156,8 @@ pa_sink_input* pa_sink_input_new(
     pa_return_null_if_fail(pa_cvolume_valid(&data->volume));
     pa_return_null_if_fail(data->volume.channels == data->sample_spec.channels);
 
+    data->virtual_volume = data->volume;
+
     if (!data->muted_is_set)
         data->muted = FALSE;
 
@@ -227,7 +229,9 @@ pa_sink_input* pa_sink_input_new(
     i->sample_spec = data->sample_spec;
     i->channel_map = data->channel_map;
 
+    i->virtual_volume = data->virtual_volume;
     i->volume = data->volume;
+
     i->muted = data->muted;
 
     if (data->sync_base) {
@@ -784,17 +788,30 @@ pa_usec_t pa_sink_input_get_requested_latency(pa_sink_input *i) {
 
 /* Called from main context */
 void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume) {
+    pa_sink_input_set_volume_data data;
+
     pa_sink_input_assert_ref(i);
     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
     pa_assert(volume);
 
-    if (pa_cvolume_equal(&i->volume, volume))
+    data.sink_input = i;
+    data.virtual_volume = *volume;
+    data.volume = *volume;
+
+    if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SET_VOLUME], &data) < 0) {
         return;
+    }
 
-    i->volume = *volume;
+    if (!pa_cvolume_equal(&i->volume, &data.volume)) {
+        i->volume = data.volume;
+	pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME, &data.volume, 0, NULL) == 0);
+        return;
+    }
 
-    pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME, &i->volume, 0, NULL) == 0);
-    pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
+    if (!pa_cvolume_equal(&i->virtual_volume, &data.virtual_volume)) {
+        i->virtual_volume = data.virtual_volume;
+        pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
+    }
 }
 
 /* Called from main context */
@@ -802,7 +819,7 @@ const pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i) {
     pa_sink_input_assert_ref(i);
     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
 
-    return &i->volume;
+    return &i->virtual_volume;
 }
 
 /* Called from main context */
diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h
index 7663f22..ed95fe4 100644
--- a/src/pulsecore/sink-input.h
+++ b/src/pulsecore/sink-input.h
@@ -89,6 +89,8 @@ struct pa_sink_input {
 
     pa_sink_input *sync_prev, *sync_next;
 
+    pa_cvolume virtual_volume;
+
     pa_cvolume volume;
     pa_bool_t muted;
 
@@ -218,6 +220,9 @@ typedef struct pa_sink_input_new_data {
 
     pa_sample_spec sample_spec;
     pa_channel_map channel_map;
+
+    pa_cvolume virtual_volume;
+
     pa_cvolume volume;
     pa_bool_t muted:1;
 
@@ -239,6 +244,12 @@ typedef struct pa_sink_input_move_hook_data {
     pa_sink *destination;
 } pa_sink_input_move_hook_data;
 
+typedef struct pa_sink_set_input_volume_data {
+  pa_sink_input *sink_input;
+  pa_cvolume virtual_volume;
+  pa_cvolume volume;
+} pa_sink_input_set_volume_data;
+
 /* To be called by the implementing module only */
 
 pa_sink_input* pa_sink_input_new(
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index e04fc08..d20a49d 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -843,13 +843,21 @@ pa_usec_t pa_sink_get_latency(pa_sink *s) {
 /* Called from main thread */
 void pa_sink_set_volume(pa_sink *s, const pa_cvolume *volume) {
     pa_bool_t changed;
+    pa_sink_set_volume_data data;
 
     pa_sink_assert_ref(s);
     pa_assert(PA_SINK_IS_LINKED(s->state));
     pa_assert(volume);
 
-    changed = !pa_cvolume_equal(volume, &s->volume);
-    s->volume = *volume;
+    data.sink = s;
+    data.volume = *volume;
+
+    changed = !pa_cvolume_equal(&data.volume, &s->volume);
+
+    if (changed && pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_SET_VOLUME], &data) < 0)
+        return;
+
+    s->volume = data.volume;
 
     if (s->set_volume && s->set_volume(s) < 0)
         s->set_volume = NULL;
diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h
index 672bdd3..74671b4 100644
--- a/src/pulsecore/sink.h
+++ b/src/pulsecore/sink.h
@@ -206,6 +206,11 @@ void pa_sink_new_data_set_volume(pa_sink_new_data *data, const pa_cvolume *volum
 void pa_sink_new_data_set_muted(pa_sink_new_data *data, pa_bool_t mute);
 void pa_sink_new_data_done(pa_sink_new_data *data);
 
+typedef struct pa_sink_set_volume_data {
+  pa_sink *sink;
+  pa_cvolume volume;
+} pa_sink_set_volume_data;
+
 /* To be called exclusively by the sink driver, from main context */
 
 pa_sink* pa_sink_new(

commit 80a79b15df82084430b85cd4573df9ea152b3b62
Author: Marc-Andre Lureau <marcandre.lureau at gmail.com>
Date:   Tue Oct 7 01:37:39 2008 +0300

    flat-volume thingy
    
    Signed-off-by: Lennart Poettering <lennart at poettering.net>

diff --git a/src/Makefile.am b/src/Makefile.am
index f277198..7487839 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1032,6 +1032,7 @@ libavahi_wrap_la_LIBADD = $(AM_LIBADD) $(AVAHI_CFLAGS) libpulsecore.la
 ###################################
 
 modlibexec_LTLIBRARIES += \
+		module-flat-volume.la \
 		module-cli.la \
 		module-cli-protocol-tcp.la \
 		module-simple-protocol-tcp.la \
@@ -1235,7 +1236,8 @@ SYMDEF_FILES = \
 		modules/bluetooth/module-bluetooth-device-symdef.h \
 		modules/gconf/module-gconf-symdef.h \
 		modules/module-position-event-sounds-symdef.h \
-		modules/module-console-kit-symdef.h
+		modules/module-console-kit-symdef.h \
+		modules/module-flat-volume-symdef.h
 
 EXTRA_DIST += $(SYMDEF_FILES)
 BUILT_SOURCES += $(SYMDEF_FILES)
@@ -1247,6 +1249,12 @@ $(SYMDEF_FILES): modules/module-defs.h.m4
 	$(MKDIR_P) modules/bluetooth
 	$(M4) -Dfname="$@" $< > $@
 
+# Flat volume
+
+module_flat_volume_la_SOURCES = modules/module-flat-volume.c
+module_flat_volume_la_LDFLAGS = -module -avoid-version
+module_flat_volume_la_LIBADD = $(AM_LIBADD) libpulsecore.la
+
 # Simple protocol
 
 module_simple_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c
diff --git a/src/modules/module-flat-volume.c b/src/modules/module-flat-volume.c
new file mode 100644
index 0000000..1a75e97
--- /dev/null
+++ b/src/modules/module-flat-volume.c
@@ -0,0 +1,220 @@
+/* $Id$ */
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+  Copyright 2004-2006, 2008 Lennart Poettering
+
+  Contact: Marc-Andre Lureau <marc-andre.lureau at nokia.com>
+
+  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 <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <regex.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/core-error.h>
+#include <pulsecore/module.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/log.h>
+#include <pulsecore/sink-input.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/macro.h>
+
+#include "module-flat-volume-symdef.h"
+
+PA_MODULE_AUTHOR("Marc-Andre Lureau");
+PA_MODULE_DESCRIPTION("Flat volume");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(TRUE);
+PA_MODULE_USAGE("");
+
+struct userdata {
+    pa_subscription *subscription;
+    pa_hook_slot *sink_input_set_volume_hook_slot;
+    pa_hook_slot *sink_input_fixate_hook_slot;
+};
+
+static void process_input_volume_change(pa_cvolume *dest_volume, const pa_cvolume *dest_virtual_volume, pa_channel_map *dest_channel_map,
+					pa_sink_input *this, pa_sink *sink) {
+    pa_sink_input *i;
+    uint32_t idx;
+    pa_cvolume max_volume, sink_volume;
+
+    pa_assert(dest_volume);
+    pa_assert(dest_virtual_volume);
+    pa_assert(dest_channel_map);
+    pa_assert(sink);
+
+    pa_log_debug("Sink input volume changed");
+
+    max_volume = *dest_virtual_volume;
+    pa_cvolume_remap(&max_volume, dest_channel_map, &sink->channel_map);
+
+    for (i = PA_SINK_INPUT(pa_idxset_first(sink->inputs, &idx)); i; i = PA_SINK_INPUT(pa_idxset_next(sink->inputs, &idx))) {
+        /* skip this sink-input if we are processing a volume change request */
+        if (this && this == i)
+            continue;
+
+        if (pa_cvolume_avg(&i->virtual_volume) > pa_cvolume_avg(&max_volume)) {
+            max_volume = i->virtual_volume;
+            pa_cvolume_remap(&max_volume, &i->channel_map, &sink->channel_map);
+        }
+    }
+
+    /* Set the master volume, and normalize inputs */
+    if (!pa_cvolume_equal(&max_volume, &sink->volume)) {
+        /* copied from pa_sink_set_volume(): need to call from here to avoid sink hooks */
+        /* alternatively, could create an extra function pa_sink_set_volume_full()? */
+        sink->volume = max_volume;
+        if (sink->set_volume && sink->set_volume(sink) < 0)
+            sink->set_volume = NULL;
+
+        if (!sink->set_volume)
+            pa_sink_set_soft_volume(sink, &max_volume);
+
+        pa_subscription_post(sink->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, sink->index);
+
+        pa_log_debug("sink = %.2f (changed)", (double)pa_cvolume_avg(&sink->volume)/PA_VOLUME_NORM);
+
+        /* Now, normalize each of the internal volume (client sink-input volume / sink master volume) */
+        for (i = PA_SINK_INPUT(pa_idxset_first(sink->inputs, &idx)); i; i = PA_SINK_INPUT(pa_idxset_next(sink->inputs, &idx))) {
+            /* skip this sink-input if we are processing a volume change request */
+            if (this && this == i)
+                continue;
+
+            sink_volume = max_volume;
+            pa_cvolume_remap(&sink_volume, &sink->channel_map, &i->channel_map);
+            pa_sw_cvolume_divide(&i->volume, &i->virtual_volume, &sink_volume);
+	    pa_log_debug("sink input { id = %d, flat = %.2f, true = %.2f }",
+			 i->index,
+			 (double)pa_cvolume_avg(&i->virtual_volume)/PA_VOLUME_NORM,
+			 (double)pa_cvolume_avg(&i->volume)/PA_VOLUME_NORM);
+	    pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME, pa_xnewdup(struct pa_cvolume, &i->volume, 1), 0, NULL, pa_xfree);
+        }
+    } else
+        pa_log_debug("sink = %.2f", (double)pa_cvolume_avg(&sink->volume)/PA_VOLUME_NORM);
+
+    /* and this one */
+    {
+        sink_volume = max_volume;
+        pa_cvolume_remap(&sink_volume, &sink->channel_map, dest_channel_map);
+        pa_sw_cvolume_divide(dest_volume, dest_virtual_volume, &sink_volume);
+        pa_log_debug("caller sink input: { id = %d, flat = %.2f, true = %.2f }",
+                     this ? (int)this->index : -1,
+                     (double)pa_cvolume_avg(dest_virtual_volume)/PA_VOLUME_NORM,
+                     (double)pa_cvolume_avg(dest_volume)/PA_VOLUME_NORM);
+    }
+}
+
+static pa_hook_result_t sink_input_set_volume_hook_callback(pa_core *c, pa_sink_input_set_volume_data *this, struct userdata *u) {
+    pa_assert(this);
+    pa_assert(this->sink_input);
+
+    process_input_volume_change(&this->volume, &this->virtual_volume, &this->sink_input->channel_map,
+				this->sink_input, this->sink_input->sink);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *core, pa_sink_input_new_data *this, struct userdata *u) {
+    pa_assert(this);
+    pa_assert(this->sink);
+
+    process_input_volume_change(&this->volume, &this->virtual_volume, &this->channel_map,
+                                NULL, this->sink);
+
+    return PA_HOOK_OK;
+}
+
+static void subscribe_callback(pa_core *core, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
+    struct userdata *u = userdata;
+    pa_sink *sink;
+    pa_sink_input *i;
+    uint32_t iidx;
+    pa_cvolume this_volume;
+
+    pa_assert(core);
+    pa_assert(u);
+
+    if (t != (PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_NEW) &&
+        t != (PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE))
+        return;
+
+    if (!(sink = pa_idxset_get_by_index(core->sinks, idx)))
+        return;
+
+    pa_log_debug("Sink volume changed");
+    pa_log_debug("sink = %.2f", (double)pa_cvolume_avg(pa_sink_get_volume(sink, FALSE)) / PA_VOLUME_NORM);
+
+    for (i = PA_SINK_INPUT(pa_idxset_first(sink->inputs, &iidx)); i; i = PA_SINK_INPUT(pa_idxset_next(sink->inputs, &iidx))) {
+        this_volume = *pa_sink_get_volume(sink, FALSE);
+        pa_cvolume_remap(&this_volume, &sink->channel_map, &i->channel_map);
+        pa_sw_cvolume_multiply(&i->virtual_volume, &i->volume, &this_volume);
+        pa_log_debug("sink input = { id = %d, flat = %.2f, true = %.2f }",
+                     i->index,
+                     (double)pa_cvolume_avg(&i->virtual_volume)/PA_VOLUME_NORM,
+                     (double)pa_cvolume_avg(&i->volume)/PA_VOLUME_NORM);
+        pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
+    }
+}
+
+int pa__init(pa_module*m) {
+    struct userdata *u;
+
+    pa_assert(m);
+
+    u = pa_xnew(struct userdata, 1);
+    m->userdata = u;
+
+    u->sink_input_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_fixate_hook_callback, u);
+    u->sink_input_set_volume_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_SET_VOLUME], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_set_volume_hook_callback, u);
+
+    u->subscription = pa_subscription_new(m->core, PA_SUBSCRIPTION_MASK_SINK, subscribe_callback, u);
+
+    return 0;
+}
+
+void pa__done(pa_module*m) {
+    struct userdata* u;
+
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    if (u->subscription)
+      pa_subscription_free(u->subscription);
+
+    if (u->sink_input_set_volume_hook_slot)
+        pa_hook_slot_free(u->sink_input_set_volume_hook_slot);
+    if (u->sink_input_fixate_hook_slot)
+        pa_hook_slot_free(u->sink_input_fixate_hook_slot);
+
+    pa_xfree(u);
+}

commit 1e513c342059fdce3d2694bae4c649b3af88e4a0
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Oct 7 02:00:07 2008 +0200

    Initialize exit_idle_time to -1 instead of 0  when in system mode.
    
    Spotted by Rafał Mużyło.

diff --git a/src/daemon/main.c b/src/daemon/main.c
index fad635f..bc8bc63 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -646,9 +646,9 @@ int main(int argc, char *argv[]) {
         conf->disable_shm = TRUE;
     }
 
-    if (conf->system_instance && conf->exit_idle_time > 0) {
+    if (conf->system_instance && conf->exit_idle_time >= 0) {
         pa_log_notice(_("Running in system mode, forcibly disabling exit idle time!"));
-        conf->exit_idle_time = 0;
+        conf->exit_idle_time = -1;
     }
 
     if (conf->cmd == PA_CMD_START) {

commit 624f220aa6b9e985ac3a14a4ef08e79bf8356723
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Oct 7 22:42:13 2008 +0200

    instead of resetting virtual_volume unconditionally on initialization, do so only when no volume was set before

diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 9a3c49c..bd4d769 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -150,13 +150,16 @@ pa_sink_input* pa_sink_input_new(
     pa_return_null_if_fail(pa_channel_map_valid(&data->channel_map));
     pa_return_null_if_fail(data->channel_map.channels == data->sample_spec.channels);
 
-    if (!data->volume_is_set)
+    if (!data->volume_is_set) {
         pa_cvolume_reset(&data->volume, data->sample_spec.channels);
+        pa_cvolume_reset(&data->virtual_volume, data->sample_spec.channels);
+    }
 
     pa_return_null_if_fail(pa_cvolume_valid(&data->volume));
     pa_return_null_if_fail(data->volume.channels == data->sample_spec.channels);
 
-    data->virtual_volume = data->volume;
+    pa_return_null_if_fail(pa_cvolume_valid(&data->virtual_volume));
+    pa_return_null_if_fail(pa_cvolume_compatible(&data->virtual_volume.channels, &data->sample_spec));
 
     if (!data->muted_is_set)
         data->muted = FALSE;

commit 72024cda54e8951cdf937b2dccdaa2cc2eb0231f
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Oct 7 22:43:00 2008 +0200

    when the volume is changed make sure we send out a subscription event

diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index bd4d769..e132580 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -801,14 +801,12 @@ void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume) {
     data.virtual_volume = *volume;
     data.volume = *volume;
 
-    if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SET_VOLUME], &data) < 0) {
+    if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SET_VOLUME], &data) < 0)
         return;
-    }
 
     if (!pa_cvolume_equal(&i->volume, &data.volume)) {
         i->volume = data.volume;
-	pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME, &data.volume, 0, NULL) == 0);
-        return;
+        pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME, &data.volume, 0, NULL) == 0);
     }
 
     if (!pa_cvolume_equal(&i->virtual_volume, &data.virtual_volume)) {

commit ae83483cf01b3e690bbee430fab8b7f9ee1efda8
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Oct 7 22:44:43 2008 +0200

    modernize a few checks

diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index e132580..6dfbdbb 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -119,6 +119,7 @@ pa_sink_input* pa_sink_input_new(
     pa_sink_input *i;
     pa_resampler *resampler = NULL;
     char st[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
+    pa_channel_map original_cm;
 
     pa_assert(core);
     pa_assert(data);
@@ -141,14 +142,14 @@ pa_sink_input* pa_sink_input_new(
     pa_return_null_if_fail(pa_sample_spec_valid(&data->sample_spec));
 
     if (!data->channel_map_is_set) {
-        if (data->sink->channel_map.channels == data->sample_spec.channels)
+        if (pa_channel_map_compatible(&data->sink->channel_map, &data->sample_spec))
             data->channel_map = data->sink->channel_map;
         else
             pa_return_null_if_fail(pa_channel_map_init_auto(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT));
     }
 
     pa_return_null_if_fail(pa_channel_map_valid(&data->channel_map));
-    pa_return_null_if_fail(data->channel_map.channels == data->sample_spec.channels);
+    pa_return_null_if_fail(pa_channel_map_compatible(&data->channel_map, &data->sample_spec));
 
     if (!data->volume_is_set) {
         pa_cvolume_reset(&data->volume, data->sample_spec.channels);
@@ -156,7 +157,7 @@ pa_sink_input* pa_sink_input_new(
     }
 
     pa_return_null_if_fail(pa_cvolume_valid(&data->volume));
-    pa_return_null_if_fail(data->volume.channels == data->sample_spec.channels);
+    pa_return_null_if_fail(pa_cvolume_compatible(&data->volume.channels, &data->sample_spec));
 
     pa_return_null_if_fail(pa_cvolume_valid(&data->virtual_volume));
     pa_return_null_if_fail(pa_cvolume_compatible(&data->virtual_volume.channels, &data->sample_spec));
@@ -796,6 +797,8 @@ void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume) {
     pa_sink_input_assert_ref(i);
     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
     pa_assert(volume);
+    pa_assert(pa_cvolume_valid(volume));
+    pa_assert(pa_cvolume_compatible(volume, &i->sample_spec));
 
     data.sink_input = i;
     data.virtual_volume = *volume;
diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c
index d76f6e4..6af7824 100644
--- a/src/pulsecore/source-output.c
+++ b/src/pulsecore/source-output.c
@@ -124,14 +124,14 @@ pa_source_output* pa_source_output_new(
     pa_return_null_if_fail(pa_sample_spec_valid(&data->sample_spec));
 
     if (!data->channel_map_is_set) {
-        if (data->source->channel_map.channels == data->sample_spec.channels)
+        if (pa_channel_map_compatible(&data->source->channel_map, &data->sample_spec))
             data->channel_map = data->source->channel_map;
         else
             pa_return_null_if_fail(pa_channel_map_init_auto(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT));
     }
 
     pa_return_null_if_fail(pa_channel_map_valid(&data->channel_map));
-    pa_return_null_if_fail(data->channel_map.channels == data->sample_spec.channels);
+    pa_return_null_if_fail(pa_channel_map_compatible(&data->channel_map, &data->sample_spec));
 
     if (flags & PA_SOURCE_OUTPUT_FIX_FORMAT)
         data->sample_spec.format = data->source->sample_spec.format;

commit e1dbc75eb80aefed7e111d857d2f822702d3a730
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Oct 7 22:45:37 2008 +0200

    use pa_channel_map_init_extend() instead of pa_channel_map_init_auto() as channel map for sink inputs/source outputs in case no map is specified

diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 6dfbdbb..6ef1e93 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -145,7 +145,7 @@ pa_sink_input* pa_sink_input_new(
         if (pa_channel_map_compatible(&data->sink->channel_map, &data->sample_spec))
             data->channel_map = data->sink->channel_map;
         else
-            pa_return_null_if_fail(pa_channel_map_init_auto(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT));
+            pa_channel_map_init_extend(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);
     }
 
     pa_return_null_if_fail(pa_channel_map_valid(&data->channel_map));
diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c
index 6af7824..7adc757 100644
--- a/src/pulsecore/source-output.c
+++ b/src/pulsecore/source-output.c
@@ -127,7 +127,7 @@ pa_source_output* pa_source_output_new(
         if (pa_channel_map_compatible(&data->source->channel_map, &data->sample_spec))
             data->channel_map = data->source->channel_map;
         else
-            pa_return_null_if_fail(pa_channel_map_init_auto(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT));
+            pa_channel_map_init_extend(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);
     }
 
     pa_return_null_if_fail(pa_channel_map_valid(&data->channel_map));

commit e053fa03f7c7ec161be14af28cab307d4271993b
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Oct 7 22:46:18 2008 +0200

    if the channel map was modified due to PA_SINK_INPUT_FIX_CHANNELS, remap the specified volume properly

diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 6ef1e93..c65f18a 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -171,6 +171,8 @@ pa_sink_input* pa_sink_input_new(
     if (flags & PA_SINK_INPUT_FIX_RATE)
         data->sample_spec.rate = data->sink->sample_spec.rate;
 
+    original_cm = data->channel_map;
+
     if (flags & PA_SINK_INPUT_FIX_CHANNELS) {
         data->sample_spec.channels = data->sink->sample_spec.channels;
         data->channel_map = data->sink->channel_map;
@@ -180,8 +182,7 @@ pa_sink_input* 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 */
-    if (data->volume.channels != data->sample_spec.channels)
-        pa_cvolume_set(&data->volume, data->sample_spec.channels, pa_cvolume_avg(&data->volume));
+    pa_cvolume_remap(&data->volume, &original_cm, &data->channel_map);
 
     if (data->resample_method == PA_RESAMPLER_INVALID)
         data->resample_method = core->resample_method;

commit 46f73fb9531772e89ef7706578ba3ed2bde6c563
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Oct 7 22:47:01 2008 +0200

    additional validity checks

diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index d20a49d..7e92049 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -848,6 +848,8 @@ void pa_sink_set_volume(pa_sink *s, const pa_cvolume *volume) {
     pa_sink_assert_ref(s);
     pa_assert(PA_SINK_IS_LINKED(s->state));
     pa_assert(volume);
+    pa_assert(pa_cvolume_valid(volume));
+    pa_assert(pa_cvolume_compatible(volume, &s->sample_spec));
 
     data.sink = s;
     data.volume = *volume;

commit 68cc2996cc1e0bfe53d35eafdd26ce4572a10ce9
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Oct 7 22:47:32 2008 +0200

    after calling PA_CORE_HOOK_SINK_SET_VOLUME hook, check again whether the volume changed

diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index 7e92049..d8d1f79 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -856,8 +856,12 @@ void pa_sink_set_volume(pa_sink *s, const pa_cvolume *volume) {
 
     changed = !pa_cvolume_equal(&data.volume, &s->volume);
 
-    if (changed && pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_SET_VOLUME], &data) < 0)
-        return;
+    if (changed) {
+        if (pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_SET_VOLUME], &data) < 0)
+            return;
+
+        changed = !pa_cvolume_equal(&data.volume, &s->volume);
+    }
 
     s->volume = data.volume;
 

commit 9f4033d1c40d6a4b81f88c45844c1da5ab0815f5
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Oct 8 00:08:51 2008 +0200

    if a stream comes with now sensible properties attached, use common
    fallback db entry.

diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c
index fe79291..e1381a5 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -134,7 +134,7 @@ static char *get_name(pa_proplist *p, const char *prefix) {
     else if ((r = pa_proplist_gets(p, PA_PROP_MEDIA_NAME)))
         return pa_sprintf_malloc("%s-by-media-name:%s", prefix, r);
 
-    return NULL;
+    return pa_sprintf_malloc("%s-fallback:%s", prefix);
 }
 
 static struct entry* read_entry(struct userdata *u, char *name) {

commit b6ccea3064fd1081ec4d0f8103a4b37de2605485
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Oct 8 00:10:01 2008 +0200

    add a comment that pa_sink_input_set_volume and module-flat-volume.c are related

diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index c65f18a..8505c63 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -805,6 +805,10 @@ void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume) {
     data.virtual_volume = *volume;
     data.volume = *volume;
 
+    /* If you change something here, consider looking into
+     * module-flat-volume.c as well since it uses very similar
+     * code. */
+
     if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SET_VOLUME], &data) < 0)
         return;
 

commit 776c8dec3c0df2114d5012a2089642a6677a0317
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Oct 8 00:10:56 2008 +0200

    remove $Id$

diff --git a/src/modules/module-flat-volume.c b/src/modules/module-flat-volume.c
index 1a75e97..5e33928 100644
--- a/src/modules/module-flat-volume.c
+++ b/src/modules/module-flat-volume.c
@@ -1,5 +1,3 @@
-/* $Id$ */
-
 /***
   This file is part of PulseAudio.
 

commit 8bc58cc7579bf238cd0a5ffd48d44ebc08eaf5a7
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Oct 8 00:12:15 2008 +0200

    ignore sinks that do not carry decibel information

diff --git a/src/modules/module-flat-volume.c b/src/modules/module-flat-volume.c
index 5e33928..3bb0c87 100644
--- a/src/modules/module-flat-volume.c
+++ b/src/modules/module-flat-volume.c
@@ -69,6 +69,9 @@ static void process_input_volume_change(pa_cvolume *dest_volume, const pa_cvolum
     pa_assert(dest_channel_map);
     pa_assert(sink);
 
+    if (!(sink->flags & PA_SINK_DECIBEL_VOLUME))
+        return;
+
     pa_log_debug("Sink input volume changed");
 
     max_volume = *dest_virtual_volume;
@@ -167,6 +170,9 @@ static void subscribe_callback(pa_core *core, pa_subscription_event_type_t t, ui
     if (!(sink = pa_idxset_get_by_index(core->sinks, idx)))
         return;
 
+    if (!(sink->flags & PA_SINK_DECIBEL_VOLUME))
+        return;
+
     pa_log_debug("Sink volume changed");
     pa_log_debug("sink = %.2f", (double)pa_cvolume_avg(pa_sink_get_volume(sink, FALSE)) / PA_VOLUME_NORM);
 

commit 404cf74332b4bee55015bfdc6ca3772c99d03f6c
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Oct 8 00:12:59 2008 +0200

    some minor reformatting

diff --git a/src/modules/module-flat-volume.c b/src/modules/module-flat-volume.c
index 3bb0c87..cd830c0 100644
--- a/src/modules/module-flat-volume.c
+++ b/src/modules/module-flat-volume.c
@@ -58,8 +58,13 @@ struct userdata {
     pa_hook_slot *sink_input_fixate_hook_slot;
 };
 
-static void process_input_volume_change(pa_cvolume *dest_volume, const pa_cvolume *dest_virtual_volume, pa_channel_map *dest_channel_map,
-					pa_sink_input *this, pa_sink *sink) {
+static void process_input_volume_change(
+        pa_cvolume *dest_volume,
+        const pa_cvolume *dest_virtual_volume,
+        pa_channel_map *dest_channel_map,
+        pa_sink_input *this,
+        pa_sink *sink) {
+
     pa_sink_input *i;
     uint32_t idx;
     pa_cvolume max_volume, sink_volume;
@@ -112,25 +117,24 @@ static void process_input_volume_change(pa_cvolume *dest_volume, const pa_cvolum
             sink_volume = max_volume;
             pa_cvolume_remap(&sink_volume, &sink->channel_map, &i->channel_map);
             pa_sw_cvolume_divide(&i->volume, &i->virtual_volume, &sink_volume);
-	    pa_log_debug("sink input { id = %d, flat = %.2f, true = %.2f }",
-			 i->index,
-			 (double)pa_cvolume_avg(&i->virtual_volume)/PA_VOLUME_NORM,
-			 (double)pa_cvolume_avg(&i->volume)/PA_VOLUME_NORM);
-	    pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME, pa_xnewdup(struct pa_cvolume, &i->volume, 1), 0, NULL, pa_xfree);
+            pa_log_debug("sink input { id = %d, flat = %.2f, true = %.2f }",
+                         i->index,
+                         (double)pa_cvolume_avg(&i->virtual_volume)/PA_VOLUME_NORM,
+                         (double)pa_cvolume_avg(&i->volume)/PA_VOLUME_NORM);
+            pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME, pa_xnewdup(struct pa_cvolume, &i->volume, 1), 0, NULL, pa_xfree);
         }
     } else
         pa_log_debug("sink = %.2f", (double)pa_cvolume_avg(&sink->volume)/PA_VOLUME_NORM);
 
     /* and this one */
-    {
-        sink_volume = max_volume;
-        pa_cvolume_remap(&sink_volume, &sink->channel_map, dest_channel_map);
-        pa_sw_cvolume_divide(dest_volume, dest_virtual_volume, &sink_volume);
-        pa_log_debug("caller sink input: { id = %d, flat = %.2f, true = %.2f }",
-                     this ? (int)this->index : -1,
-                     (double)pa_cvolume_avg(dest_virtual_volume)/PA_VOLUME_NORM,
-                     (double)pa_cvolume_avg(dest_volume)/PA_VOLUME_NORM);
-    }
+
+    sink_volume = max_volume;
+    pa_cvolume_remap(&sink_volume, &sink->channel_map, dest_channel_map);
+    pa_sw_cvolume_divide(dest_volume, dest_virtual_volume, &sink_volume);
+    pa_log_debug("caller sink input: { id = %d, flat = %.2f, true = %.2f }",
+                 this ? (int)this->index : -1,
+                 (double)pa_cvolume_avg(dest_virtual_volume)/PA_VOLUME_NORM,
+                 (double)pa_cvolume_avg(dest_volume)/PA_VOLUME_NORM);
 }
 
 static pa_hook_result_t sink_input_set_volume_hook_callback(pa_core *c, pa_sink_input_set_volume_data *this, struct userdata *u) {
@@ -138,7 +142,7 @@ static pa_hook_result_t sink_input_set_volume_hook_callback(pa_core *c, pa_sink_
     pa_assert(this->sink_input);
 
     process_input_volume_change(&this->volume, &this->virtual_volume, &this->sink_input->channel_map,
-				this->sink_input, this->sink_input->sink);
+                                this->sink_input, this->sink_input->sink);
 
     return PA_HOOK_OK;
 }

commit b048ae9f789cdbc7540b343fb1890a86d91a505f
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Oct 8 00:13:53 2008 +0200

    check the maximum volume of all sink inputs instead of the average volume to avoid digital amplification in favour of attenuation

diff --git a/src/modules/module-flat-volume.c b/src/modules/module-flat-volume.c
index cd830c0..02e3ed1 100644
--- a/src/modules/module-flat-volume.c
+++ b/src/modules/module-flat-volume.c
@@ -87,7 +87,7 @@ static void process_input_volume_change(
         if (this && this == i)
             continue;
 
-        if (pa_cvolume_avg(&i->virtual_volume) > pa_cvolume_avg(&max_volume)) {
+        if (pa_cvolume_max(&i->virtual_volume) > pa_cvolume_max(&max_volume)) {
             max_volume = i->virtual_volume;
             pa_cvolume_remap(&max_volume, &i->channel_map, &sink->channel_map);
         }

commit 34f6a516b2e5fd0ca4143eed9831759fcbc89cb0
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Oct 8 00:14:25 2008 +0200

    use pa_sink_set_volume() for changing the volume

diff --git a/src/modules/module-flat-volume.c b/src/modules/module-flat-volume.c
index 02e3ed1..25b5707 100644
--- a/src/modules/module-flat-volume.c
+++ b/src/modules/module-flat-volume.c
@@ -95,16 +95,8 @@ static void process_input_volume_change(
 
     /* Set the master volume, and normalize inputs */
     if (!pa_cvolume_equal(&max_volume, &sink->volume)) {
-        /* copied from pa_sink_set_volume(): need to call from here to avoid sink hooks */
-        /* alternatively, could create an extra function pa_sink_set_volume_full()? */
-        sink->volume = max_volume;
-        if (sink->set_volume && sink->set_volume(sink) < 0)
-            sink->set_volume = NULL;
 
-        if (!sink->set_volume)
-            pa_sink_set_soft_volume(sink, &max_volume);
-
-        pa_subscription_post(sink->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, sink->index);
+        pa_sink_set_volume(sink, &max_volume);
 
         pa_log_debug("sink = %.2f (changed)", (double)pa_cvolume_avg(&sink->volume)/PA_VOLUME_NORM);
 

commit 37b8c45e2b4d996b328a4fc74f491498abbc9348
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Oct 8 00:14:54 2008 +0200

    query the sink volume outside of the loop because it might be quite expensive

diff --git a/src/modules/module-flat-volume.c b/src/modules/module-flat-volume.c
index 25b5707..9bc8055 100644
--- a/src/modules/module-flat-volume.c
+++ b/src/modules/module-flat-volume.c
@@ -154,7 +154,7 @@ static void subscribe_callback(pa_core *core, pa_subscription_event_type_t t, ui
     pa_sink *sink;
     pa_sink_input *i;
     uint32_t iidx;
-    pa_cvolume this_volume;
+    pa_cvolume sink_volume;
 
     pa_assert(core);
     pa_assert(u);
@@ -172,10 +172,14 @@ static void subscribe_callback(pa_core *core, pa_subscription_event_type_t t, ui
     pa_log_debug("Sink volume changed");
     pa_log_debug("sink = %.2f", (double)pa_cvolume_avg(pa_sink_get_volume(sink, FALSE)) / PA_VOLUME_NORM);
 
+    sink_volume = *pa_sink_get_volume(sink, FALSE);
+
     for (i = PA_SINK_INPUT(pa_idxset_first(sink->inputs, &iidx)); i; i = PA_SINK_INPUT(pa_idxset_next(sink->inputs, &iidx))) {
-        this_volume = *pa_sink_get_volume(sink, FALSE);
-        pa_cvolume_remap(&this_volume, &sink->channel_map, &i->channel_map);
-        pa_sw_cvolume_multiply(&i->virtual_volume, &i->volume, &this_volume);
+        pa_cvolume si_volume;
+
+        si_volume = sink_volume;
+        pa_cvolume_remap(&si_volume, &sink->channel_map, &i->channel_map);
+        pa_sw_cvolume_multiply(&i->virtual_volume, &i->volume, &si_volume);
         pa_log_debug("sink input = { id = %d, flat = %.2f, true = %.2f }",
                      i->index,
                      (double)pa_cvolume_avg(&i->virtual_volume)/PA_VOLUME_NORM,

commit 2dfc2654832e5124f263bc7ee2718ff6913e6d46
Merge: 5925d44... 37b8c45...
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Oct 8 00:15:18 2008 +0200

    Merge branch 'flatvol'


-- 
hooks/post-receive
PulseAudio Sound Server



More information about the pulseaudio-commits mailing list