]> code.delx.au - pulseaudio/commitdiff
core: always allow volume setting with single-channel pa_cvolume
authorLennart Poettering <lennart@poettering.net>
Mon, 31 Aug 2009 19:40:59 +0000 (21:40 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 31 Aug 2009 19:40:59 +0000 (21:40 +0200)
src/pulsecore/protocol-native.c
src/pulsecore/sink-input.c
src/pulsecore/sink.c
src/pulsecore/source.c

index 179e62e276dcfb5749561a90b01f85745ace9054..d961dba2dd5c758a29a974832774bc4cd3d23fb1 100644 (file)
@@ -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,
index d3e7a45cb6c39a7307df18cbcf850862c48c9e6a..adda2affb7196c1af692f4b967d5ee036f484daf 100644 (file)
@@ -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)) {
index 48c50b0bd15b3855210e5fac0f6826e1e8f515ba..f5a6fc50994e6c7d941cd80bf5bbdf7b8bb4d72d 100644 (file)
@@ -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 */
index 1c77e0b9c6aff50b679bedd0268284d05cd2bed9..415c54bc35efe2be9e2798d7246eb7d10eb912b2 100644 (file)
@@ -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) {