summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pulsecore/protocol-native.c6
-rw-r--r--src/pulsecore/sink-input.c14
-rw-r--r--src/pulsecore/sink.c10
-rw-r--r--src/pulsecore/source.c13
4 files changed, 33 insertions, 10 deletions
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 179e62e2..d961dba2 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -3390,17 +3390,17 @@ static void command_set_volume(
client_name = pa_strnull(pa_proplist_gets(c->client->proplist, PA_PROP_APPLICATION_PROCESS_BINARY));
if (sink) {
- CHECK_VALIDITY(c->pstream, pa_cvolume_compatible(&volume, &sink->sample_spec), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, volume.channels == 1 || pa_cvolume_compatible(&volume, &sink->sample_spec), tag, PA_ERR_INVALID);
pa_log_debug("Client %s changes volume of sink %s.", client_name, sink->name);
pa_sink_set_volume(sink, &volume, TRUE, TRUE);
} else if (source) {
- CHECK_VALIDITY(c->pstream, pa_cvolume_compatible(&volume, &source->sample_spec), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, volume.channels == 1 || pa_cvolume_compatible(&volume, &source->sample_spec), tag, PA_ERR_INVALID);
pa_log_debug("Client %s changes volume of source %s.", client_name, source->name);
pa_source_set_volume(source, &volume, TRUE);
} else if (si) {
- CHECK_VALIDITY(c->pstream, pa_cvolume_compatible(&volume, &si->sample_spec), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, volume.channels == 1 || pa_cvolume_compatible(&volume, &si->sample_spec), tag, PA_ERR_INVALID);
pa_log_debug("Client %s changes volume of sink input %s.",
client_name,
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index d3e7a45c..adda2aff 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -941,12 +941,22 @@ void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_boo
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));
+ pa_assert(volume->channels == 1 || pa_cvolume_compatible(volume, &i->sample_spec));
if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !absolute) {
v = i->sink->reference_volume;
pa_cvolume_remap(&v, &i->sink->channel_map, &i->channel_map);
- volume = pa_sw_cvolume_multiply(&v, &v, volume);
+
+ if (pa_cvolume_compatible(volume, &i->sample_spec))
+ volume = pa_sw_cvolume_multiply(&v, &v, volume);
+ else
+ volume = pa_sw_cvolume_multiply_scalar(&v, &v, pa_cvolume_max(volume));
+ } else {
+
+ if (!pa_cvolume_compatible(volume, &i->sample_spec)) {
+ v = i->volume;
+ volume = pa_cvolume_scale(&v, pa_cvolume_max(volume));
+ }
}
if (pa_cvolume_equal(volume, &i->volume)) {
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index 48c50b0b..f5a6fc50 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -1408,8 +1408,11 @@ void pa_sink_set_volume(
pa_assert_ctl_context();
pa_assert(PA_SINK_IS_LINKED(s->state));
pa_assert(!volume || pa_cvolume_valid(volume));
- pa_assert(!volume || pa_cvolume_compatible(volume, &s->sample_spec));
pa_assert(volume || (s->flags & PA_SINK_FLAT_VOLUME));
+ pa_assert(!volume || volume->channels == 1 || pa_cvolume_compatible(volume, &s->sample_spec));
+
+ /* As a special exception we accept mono volumes on all sinks --
+ * even on those with more complex channel maps */
/* If volume is NULL we synchronize the sink's real and reference
* volumes with the stream volumes. If it is not NULL we update
@@ -1419,7 +1422,10 @@ void pa_sink_set_volume(
if (volume) {
- s->reference_volume = *volume;
+ if (pa_cvolume_compatible(volume, &s->sample_spec))
+ s->reference_volume = *volume;
+ else
+ pa_cvolume_scale(&s->reference_volume, pa_cvolume_max(volume));
if (s->flags & PA_SINK_FLAT_VOLUME) {
/* OK, propagate this volume change back to the inputs */
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
index 1c77e0b9..415c54bc 100644
--- a/src/pulsecore/source.c
+++ b/src/pulsecore/source.c
@@ -760,15 +760,22 @@ void pa_source_set_volume(
pa_bool_t save) {
pa_bool_t real_changed;
+ pa_cvolume old_volume;
pa_source_assert_ref(s);
pa_assert_ctl_context();
pa_assert(PA_SOURCE_IS_LINKED(s->state));
pa_assert(pa_cvolume_valid(volume));
- pa_assert(pa_cvolume_compatible(volume, &s->sample_spec));
+ pa_assert(volume->channels == 1 || pa_cvolume_compatible(volume, &s->sample_spec));
- real_changed = !pa_cvolume_equal(volume, &s->volume);
- s->volume = *volume;
+ old_volume = s->volume;
+
+ if (pa_cvolume_compatible(volume, &s->sample_spec))
+ s->volume = *volume;
+ else
+ pa_cvolume_scale(&s->volume, pa_cvolume_max(volume));
+
+ real_changed = !pa_cvolume_equal(&old_volume, &s->volume);
s->save_volume = (!real_changed && s->save_volume) || save;
if (s->set_volume) {