[pulseaudio-commits] 4 commits - man/pactl.1.xml.in src/utils

Peter Meerwald pmeerw at kemper.freedesktop.org
Tue Apr 15 15:10:05 PDT 2014


 man/pactl.1.xml.in |   20 +++++---
 src/utils/pactl.c  |  126 +++++++++++++++++++++++++++++++----------------------
 2 files changed, 87 insertions(+), 59 deletions(-)

New commits:
commit 36f775482f2e54e7de0b00ead980c6617e88bad3
Author: Peter Meerwald <pmeerw at pmeerw.net>
Date:   Sat Mar 29 18:03:05 2014 +0100

    pactl: Clean up checking for VOL_RELATIVE flag
    
    VOL_RELATIVE if a bit flag (1 << 4), hence we can simply do
        if (vol_flags & VOL_RELATIVE) ...
    instead of
        if ((vol_flags & VOL_RELATIVE) == VOL_RELATIVE) ...
    
    Signed-off-by: Peter Meerwald <pmeerw at pmeerw.net>

diff --git a/src/utils/pactl.c b/src/utils/pactl.c
index e6498d0..13ea649 100644
--- a/src/utils/pactl.c
+++ b/src/utils/pactl.c
@@ -837,7 +837,7 @@ static void index_callback(pa_context *c, uint32_t idx, void *userdata) {
 }
 
 static void volume_relative_adjust(pa_cvolume *cv) {
-    pa_assert((volume_flags & VOL_RELATIVE) == VOL_RELATIVE);
+    pa_assert(volume_flags & VOL_RELATIVE);
 
     /* Relative volume change is additive in case of UINT or PERCENT
      * and multiplicative for LINEAR or DECIBEL */
@@ -1492,7 +1492,7 @@ static int parse_volume(const char *vol_spec, pa_volume_t *vol, enum volume_flag
 
     pa_xfree(vs);
 
-    if ((*vol_flags & VOL_RELATIVE) == VOL_RELATIVE) {
+    if (*vol_flags & VOL_RELATIVE) {
         if ((*vol_flags & 0x0F) == VOL_UINT)
             v += (double) PA_VOLUME_NORM;
         if ((*vol_flags & 0x0F) == VOL_PERCENT)

commit edaa0282904b11cd4a708b2f985477284c17ec4c
Author: Peter Meerwald <pmeerw at pmeerw.net>
Date:   Thu Feb 13 21:15:04 2014 +0100

    pactl: Document ability to specify channel volumes individually
    
    Signed-off-by: Peter Meerwald <pmeerw at pmeerw.net>

diff --git a/man/pactl.1.xml.in b/man/pactl.1.xml.in
index 29071b3..a195b1d 100644
--- a/man/pactl.1.xml.in
+++ b/man/pactl.1.xml.in
@@ -189,33 +189,37 @@ USA.
     </option>
 
     <option>
-      <p><opt>set-sink-volume</opt> <arg>SINK</arg> <arg>VOLUME</arg></p>
+      <p><opt>set-sink-volume</opt> <arg>SINK</arg> <arg>VOLUME [VOLUME ...]</arg></p>
       <optdesc><p>Set the volume of the specified sink (identified by its symbolic name or numerical index).
       <arg>VOLUME</arg> can be specified as an integer (e.g. 2000, 16384), a linear factor (e.g. 0.4, 1.100), a percentage
       (e.g.  10%, 100%) or a decibel value (e.g. 0dB, 20dB).  If the volume specification start with a + or - the volume
-      adjustment will be relative to the current sink volume.</p></optdesc>
+      adjustment will be relative to the current sink volume.  A single volume value affects all channels; if multiple
+      volume values are given their number has to match the sink's number of channels.</p></optdesc>
     </option>
 
     <option>
-      <p><opt>set-source-volume</opt> <arg>SOURCE</arg> <arg>VOLUME</arg></p>
+      <p><opt>set-source-volume</opt> <arg>SOURCE</arg> <arg>VOLUME [VOLUME ...]</arg></p>
       <optdesc><p>Set the volume of the specified source (identified by its symbolic name or numerical index).
       <arg>VOLUME</arg> can be specified as an integer (e.g. 2000, 16384), a linear factor (e.g. 0.4, 1.100), a percentage
       (e.g.  10%, 100%) or a decibel value (e.g. 0dB, 20dB).  If the volume specification start with a + or - the volume
-      adjustment will be relative to the current source volume.</p></optdesc> </option>
+      adjustment will be relative to the current source volume.  A single volume value affects all channels; if multiple
+      volume values are given their number has to match the source's number of channels.</p></optdesc> </option>
 
     <option>
-      <p><opt>set-sink-input-volume</opt> <arg>INPUT</arg> <arg>VOLUME</arg></p>
+      <p><opt>set-sink-input-volume</opt> <arg>INPUT</arg> <arg>VOLUME [VOLUME ...]</arg></p>
       <optdesc><p>Set the volume of the specified sink input (identified by its numerical index).
       <arg>VOLUME</arg> can be specified as an integer (e.g. 2000, 16384), a linear factor (e.g. 0.4, 1.100), a percentage
       (e.g.  10%, 100%) or a decibel value (e.g. 0dB, 20dB).  If the volume specification start with a + or - the volume
-      adjustment will be relative to the current sink input volume.</p></optdesc> </option>
+      adjustment will be relative to the current sink input volume.  A single volume value affects all channels; if multiple
+      volume values are given their number has to match the sink input's number of channels.</p></optdesc> </option>
 
     <option>
-      <p><opt>set-source-output-volume</opt> <arg>OUTPUT</arg> <arg>VOLUME</arg></p>
+      <p><opt>set-source-output-volume</opt> <arg>OUTPUT</arg> <arg>VOLUME [VOLUME ...]</arg></p>
       <optdesc><p>Set the volume of the specified source output (identified by its numerical index).
       <arg>VOLUME</arg> can be specified as an integer (e.g. 2000, 16384), a linear factor (e.g. 0.4, 1.100), a percentage
       (e.g.  10%, 100%) or a decibel value (e.g. 0dB, 20dB).  If the volume specification start with a + or - the volume
-      adjustment will be relative to the current source output volume.</p></optdesc>
+      adjustment will be relative to the current source output volume.  A single volume value affects all channels; if multiple
+      volume values are given their number has to match the source output's number of channels.</p></optdesc>
     </option>
 
     <option>
diff --git a/src/utils/pactl.c b/src/utils/pactl.c
index 1eac826..e6498d0 100644
--- a/src/utils/pactl.c
+++ b/src/utils/pactl.c
@@ -1577,8 +1577,8 @@ static void help(const char *argv0) {
     printf("%s %s %s %s\n", argv0, _("[options]"), "set-card-profile ", _("CARD PROFILE"));
     printf("%s %s %s %s\n", argv0, _("[options]"), "set-default-(sink|source)", _("NAME"));
     printf("%s %s %s %s\n", argv0, _("[options]"), "set-(sink|source)-port", _("NAME|#N PORT"));
-    printf("%s %s %s %s\n", argv0, _("[options]"), "set-(sink|source)-volume", _("NAME|#N VOLUME"));
-    printf("%s %s %s %s\n", argv0, _("[options]"), "set-(sink-input|source-output)-volume", _("#N VOLUME"));
+    printf("%s %s %s %s\n", argv0, _("[options]"), "set-(sink|source)-volume", _("NAME|#N VOLUME [VOLUME ...]"));
+    printf("%s %s %s %s\n", argv0, _("[options]"), "set-(sink-input|source-output)-volume", _("#N VOLUME [VOLUME ...]"));
     printf("%s %s %s %s\n", argv0, _("[options]"), "set-(sink|source)-mute", _("NAME|#N 1|0|toggle"));
     printf("%s %s %s %s\n", argv0, _("[options]"), "set-(sink-input|source-output)-mute", _("#N 1|0|toggle"));
     printf("%s %s %s %s\n", argv0, _("[options]"), "set-sink-formats", _("#N FORMATS"));

commit 930159d4c5feeda3c6abad02e4c74dea366f9c39
Author: Peter Meerwald <pmeerw at pmeerw.net>
Date:   Thu Feb 13 21:07:06 2014 +0100

    pactl: Check consistency of volumes specified
    
    Must use one way to specify volumes consistently, e.g.
    +3dB +3dB, mixing different ways is not allowed, such as
    40% 1000
    
    Signed-off-by: Peter Meerwald <pmeerw at pmeerw.net>

diff --git a/src/utils/pactl.c b/src/utils/pactl.c
index 8c71cff..1eac826 100644
--- a/src/utils/pactl.c
+++ b/src/utils/pactl.c
@@ -1517,6 +1517,31 @@ static int parse_volume(const char *vol_spec, pa_volume_t *vol, enum volume_flag
     return 0;
 }
 
+static int parse_volumes(char *args[], unsigned n) {
+    unsigned i;
+
+    if (n >= PA_CHANNELS_MAX) {
+        pa_log(_("Invalid number of volume specifications.\n"));
+        return -1;
+    }
+
+    volume.channels = n;
+    for (i = 0; i < volume.channels; i++) {
+        enum volume_flags flags;
+
+        if (parse_volume(args[i], &volume.values[i], &flags) < 0)
+            return -1;
+
+        if (i > 0 && flags != volume_flags) {
+            pa_log(_("Inconsistent volume specification.\n"));
+            return -1;
+        } else
+            volume_flags = flags;
+    }
+
+    return 0;
+}
+
 static enum mute_flags parse_mute(const char *mute_text) {
     int b;
 
@@ -1873,7 +1898,6 @@ int main(int argc, char *argv[]) {
             source_name = pa_xstrdup(argv[optind+1]);
 
         } else if (pa_streq(argv[optind], "set-sink-volume")) {
-            unsigned i;
             action = SET_SINK_VOLUME;
 
             if (argc < optind+3) {
@@ -1883,16 +1907,10 @@ int main(int argc, char *argv[]) {
 
             sink_name = pa_xstrdup(argv[optind+1]);
 
-            volume.channels = argc-3;
-
-            for (i = 0; i < volume.channels; i++) {
-                if (parse_volume(argv[optind+2+i],
-                    &volume.values[i], &volume_flags) < 0)
-                    goto quit;
-            }
+            if (parse_volumes(argv+optind+2, argc-3) < 0)
+                goto quit;
 
         } else if (pa_streq(argv[optind], "set-source-volume")) {
-            unsigned i;
             action = SET_SOURCE_VOLUME;
 
             if (argc < optind+3) {
@@ -1902,15 +1920,10 @@ int main(int argc, char *argv[]) {
 
             source_name = pa_xstrdup(argv[optind+1]);
 
-            volume.channels = argc-3;
-
-            for (i = 0; i < volume.channels; i++) {
-                if (parse_volume(argv[optind+2+i], &volume.values[i], &volume_flags) < 0)
-                    goto quit;
-            }
+            if (parse_volumes(argv+optind+2, argc-3) < 0)
+                goto quit;
 
         } else if (pa_streq(argv[optind], "set-sink-input-volume")) {
-            unsigned i;
             action = SET_SINK_INPUT_VOLUME;
 
             if (argc < optind+3) {
@@ -1923,15 +1936,10 @@ int main(int argc, char *argv[]) {
                 goto quit;
             }
 
-            volume.channels = argc-3;
-
-            for (i = 0; i < volume.channels; i++) {
-                if (parse_volume(argv[optind+2+i], &volume.values[i], &volume_flags) < 0)
-                    goto quit;
-            }
+            if (parse_volumes(argv+optind+2, argc-3) < 0)
+                goto quit;
 
         } else if (pa_streq(argv[optind], "set-source-output-volume")) {
-            unsigned i;
             action = SET_SOURCE_OUTPUT_VOLUME;
 
             if (argc < optind+3) {
@@ -1944,12 +1952,8 @@ int main(int argc, char *argv[]) {
                 goto quit;
             }
 
-            volume.channels = argc-3;
-
-            for (i = 0; i < volume.channels; i++) {
-                if (parse_volume(argv[optind+2+i], &volume.values[i], &volume_flags) < 0)
-                    goto quit;
-            }
+            if (parse_volumes(argv+optind+2, argc-3) < 0)
+                goto quit;
 
         } else if (pa_streq(argv[optind], "set-sink-mute")) {
             action = SET_SINK_MUTE;

commit fc9fdfaf7b4534a48556b31d5a29b8f62664ab3c
Author: Parin Porecha <parinporecha at gmail.com>
Date:   Thu Dec 19 17:28:15 2013 +0530

    pactl: Allow to set volume of each channel independently (Bug #39190)
    
    Example: pactl set-sink-volume "sink_name" 32000 40000
    If the number of volumes provided is different than the number of channels
    (excluding the case where a single volume is provided), an error message
    is displayed explaining why the volumes could not be set.
    
    patch proposed by Parin Porecha
    code refactoring and commit message slightly edited by Peter Meerwald

diff --git a/src/utils/pactl.c b/src/utils/pactl.c
index 555cb48..8c71cff 100644
--- a/src/utils/pactl.c
+++ b/src/utils/pactl.c
@@ -69,7 +69,7 @@ static bool short_list_format = false;
 static uint32_t module_index;
 static int32_t latency_offset;
 static bool suspend;
-static pa_volume_t volume;
+static pa_cvolume volume;
 static enum volume_flags {
     VOL_UINT     = 0,
     VOL_PERCENT  = 1,
@@ -842,13 +842,16 @@ static void volume_relative_adjust(pa_cvolume *cv) {
     /* Relative volume change is additive in case of UINT or PERCENT
      * and multiplicative for LINEAR or DECIBEL */
     if ((volume_flags & 0x0F) == VOL_UINT || (volume_flags & 0x0F) == VOL_PERCENT) {
-        pa_volume_t v = pa_cvolume_avg(cv);
-        v = v + volume < PA_VOLUME_NORM ? PA_VOLUME_MUTED : v + volume - PA_VOLUME_NORM;
-        pa_cvolume_set(cv, 1, v);
-    }
-    if ((volume_flags & 0x0F) == VOL_LINEAR || (volume_flags & 0x0F) == VOL_DECIBEL) {
-        pa_sw_cvolume_multiply_scalar(cv, cv, volume);
+        unsigned i;
+        for (i = 0; i < cv->channels; i++) {
+            if (cv->values[i] + volume.values[i] < PA_VOLUME_NORM)
+                cv->values[i] = PA_VOLUME_MUTED;
+            else
+                cv->values[i] = cv->values[i] + volume.values[i] - PA_VOLUME_NORM;
+        }
     }
+    if ((volume_flags & 0x0F) == VOL_LINEAR || (volume_flags & 0x0F) == VOL_DECIBEL)
+        pa_sw_cvolume_multiply(cv, cv, &volume);
 }
 
 static void unload_module_by_name_callback(pa_context *c, const pa_module_info *i, int is_last, void *userdata) {
@@ -876,6 +879,22 @@ static void unload_module_by_name_callback(pa_context *c, const pa_module_info *
     }
 }
 
+static void fill_volume(pa_cvolume *cv, unsigned supported) {
+    if (volume.channels == 1) {
+        pa_cvolume_set(&volume, supported, volume.values[0]);
+    } else if (volume.channels != supported) {
+        pa_log(_("Failed to set volume: You tried to set volumes for %d channels, whereas channel/s supported = %d\n"),
+            volume.channels, supported);
+        quit(1);
+        return;
+    }
+
+    if (volume_flags & VOL_RELATIVE)
+        volume_relative_adjust(cv);
+    else
+        *cv = volume;
+}
+
 static void get_sink_volume_callback(pa_context *c, const pa_sink_info *i, int is_last, void *userdata) {
     pa_cvolume cv;
 
@@ -891,7 +910,8 @@ static void get_sink_volume_callback(pa_context *c, const pa_sink_info *i, int i
     pa_assert(i);
 
     cv = i->volume;
-    volume_relative_adjust(&cv);
+    fill_volume(&cv, i->channel_map.channels);
+
     pa_operation_unref(pa_context_set_sink_volume_by_name(c, sink_name, &cv, simple_callback, NULL));
 }
 
@@ -910,7 +930,8 @@ static void get_source_volume_callback(pa_context *c, const pa_source_info *i, i
     pa_assert(i);
 
     cv = i->volume;
-    volume_relative_adjust(&cv);
+    fill_volume(&cv, i->channel_map.channels);
+
     pa_operation_unref(pa_context_set_source_volume_by_name(c, source_name, &cv, simple_callback, NULL));
 }
 
@@ -929,7 +950,8 @@ static void get_sink_input_volume_callback(pa_context *c, const pa_sink_input_in
     pa_assert(i);
 
     cv = i->volume;
-    volume_relative_adjust(&cv);
+    fill_volume(&cv, i->channel_map.channels);
+
     pa_operation_unref(pa_context_set_sink_input_volume(c, sink_input_idx, &cv, simple_callback, NULL));
 }
 
@@ -948,7 +970,8 @@ static void get_source_output_volume_callback(pa_context *c, const pa_source_out
     pa_assert(o);
 
     cv = o->volume;
-    volume_relative_adjust(&cv);
+    fill_volume(&cv, o->channel_map.channels);
+
     pa_operation_unref(pa_context_set_source_output_volume(c, source_output_idx, &cv, simple_callback, NULL));
 }
 
@@ -1367,43 +1390,19 @@ static void context_state_callback(pa_context *c, void *userdata) {
                     break;
 
                 case SET_SINK_VOLUME:
-                    if ((volume_flags & VOL_RELATIVE) == VOL_RELATIVE) {
-                        o = pa_context_get_sink_info_by_name(c, sink_name, get_sink_volume_callback, NULL);
-                    } else {
-                        pa_cvolume v;
-                        pa_cvolume_set(&v, 1, volume);
-                        o = pa_context_set_sink_volume_by_name(c, sink_name, &v, simple_callback, NULL);
-                    }
+                    o = pa_context_get_sink_info_by_name(c, sink_name, get_sink_volume_callback, NULL);
                     break;
 
                 case SET_SOURCE_VOLUME:
-                    if ((volume_flags & VOL_RELATIVE) == VOL_RELATIVE) {
-                        o = pa_context_get_source_info_by_name(c, source_name, get_source_volume_callback, NULL);
-                    } else {
-                        pa_cvolume v;
-                        pa_cvolume_set(&v, 1, volume);
-                        o = pa_context_set_source_volume_by_name(c, source_name, &v, simple_callback, NULL);
-                    }
+                    o = pa_context_get_source_info_by_name(c, source_name, get_source_volume_callback, NULL);
                     break;
 
                 case SET_SINK_INPUT_VOLUME:
-                    if ((volume_flags & VOL_RELATIVE) == VOL_RELATIVE) {
-                        o = pa_context_get_sink_input_info(c, sink_input_idx, get_sink_input_volume_callback, NULL);
-                    } else {
-                        pa_cvolume v;
-                        pa_cvolume_set(&v, 1, volume);
-                        o = pa_context_set_sink_input_volume(c, sink_input_idx, &v, simple_callback, NULL);
-                    }
+                    o = pa_context_get_sink_input_info(c, sink_input_idx, get_sink_input_volume_callback, NULL);
                     break;
 
                 case SET_SOURCE_OUTPUT_VOLUME:
-                    if ((volume_flags & VOL_RELATIVE) == VOL_RELATIVE) {
-                        o = pa_context_get_source_output_info(c, source_output_idx, get_source_output_volume_callback, NULL);
-                    } else {
-                        pa_cvolume v;
-                        pa_cvolume_set(&v, 1, volume);
-                        o = pa_context_set_source_output_volume(c, source_output_idx, &v, simple_callback, NULL);
-                    }
+                    o = pa_context_get_source_output_info(c, source_output_idx, get_source_output_volume_callback, NULL);
                     break;
 
                 case SET_SINK_FORMATS:
@@ -1874,35 +1873,47 @@ int main(int argc, char *argv[]) {
             source_name = pa_xstrdup(argv[optind+1]);
 
         } else if (pa_streq(argv[optind], "set-sink-volume")) {
+            unsigned i;
             action = SET_SINK_VOLUME;
 
-            if (argc != optind+3) {
+            if (argc < optind+3) {
                 pa_log(_("You have to specify a sink name/index and a volume"));
                 goto quit;
             }
 
             sink_name = pa_xstrdup(argv[optind+1]);
 
-            if (parse_volume(argv[optind+2], &volume, &volume_flags) < 0)
-                goto quit;
+            volume.channels = argc-3;
+
+            for (i = 0; i < volume.channels; i++) {
+                if (parse_volume(argv[optind+2+i],
+                    &volume.values[i], &volume_flags) < 0)
+                    goto quit;
+            }
 
         } else if (pa_streq(argv[optind], "set-source-volume")) {
+            unsigned i;
             action = SET_SOURCE_VOLUME;
 
-            if (argc != optind+3) {
+            if (argc < optind+3) {
                 pa_log(_("You have to specify a source name/index and a volume"));
                 goto quit;
             }
 
             source_name = pa_xstrdup(argv[optind+1]);
 
-            if (parse_volume(argv[optind+2], &volume, &volume_flags) < 0)
-                goto quit;
+            volume.channels = argc-3;
+
+            for (i = 0; i < volume.channels; i++) {
+                if (parse_volume(argv[optind+2+i], &volume.values[i], &volume_flags) < 0)
+                    goto quit;
+            }
 
         } else if (pa_streq(argv[optind], "set-sink-input-volume")) {
+            unsigned i;
             action = SET_SINK_INPUT_VOLUME;
 
-            if (argc != optind+3) {
+            if (argc < optind+3) {
                 pa_log(_("You have to specify a sink input index and a volume"));
                 goto quit;
             }
@@ -1912,13 +1923,18 @@ int main(int argc, char *argv[]) {
                 goto quit;
             }
 
-            if (parse_volume(argv[optind+2], &volume, &volume_flags) < 0)
-                goto quit;
+            volume.channels = argc-3;
+
+            for (i = 0; i < volume.channels; i++) {
+                if (parse_volume(argv[optind+2+i], &volume.values[i], &volume_flags) < 0)
+                    goto quit;
+            }
 
         } else if (pa_streq(argv[optind], "set-source-output-volume")) {
+            unsigned i;
             action = SET_SOURCE_OUTPUT_VOLUME;
 
-            if (argc != optind+3) {
+            if (argc < optind+3) {
                 pa_log(_("You have to specify a source output index and a volume"));
                 goto quit;
             }
@@ -1928,8 +1944,12 @@ int main(int argc, char *argv[]) {
                 goto quit;
             }
 
-            if (parse_volume(argv[optind+2], &volume, &volume_flags) < 0)
-                goto quit;
+            volume.channels = argc-3;
+
+            for (i = 0; i < volume.channels; i++) {
+                if (parse_volume(argv[optind+2+i], &volume.values[i], &volume_flags) < 0)
+                    goto quit;
+            }
 
         } else if (pa_streq(argv[optind], "set-sink-mute")) {
             action = SET_SINK_MUTE;



More information about the pulseaudio-commits mailing list