With this you can specify the volume with 6554, 10%, 0.001 or -60dB, all resulting in the same volume change. --- src/utils/pactl.c | 98 +++++++++++++++++++++++++++++++++------------------- 1 files changed, 62 insertions(+), 36 deletions(-) diff --git a/src/utils/pactl.c b/src/utils/pactl.c index ad5c0b8..672bfbb 100644 --- a/src/utils/pactl.c +++ b/src/utils/pactl.c @@ -65,6 +65,12 @@ static uint32_t module_index; static pa_bool_t suspend; static pa_bool_t mute; static pa_volume_t volume; +enum volume_type { + VOL_SW, + VOL_PERCENT, + VOL_LINEAR, + VOL_DECIBEL +}; static pa_proplist *proplist = NULL; @@ -956,6 +962,54 @@ static void exit_signal_callback(pa_mainloop_api *m, pa_signal_event *e, int sig quit(0); } +static int parse_volume(const char *vol_spec, pa_volume_t *vol) { + int volume_type = VOL_SW; + double v; + char *vs; + + pa_assert(vol_spec); + pa_assert(vol); + + vs = pa_xstrdup(vol_spec); + + for (char *c = vs; *c; c++) { + if (*c == '.') + volume_type = VOL_LINEAR; + } + if (pa_endswith(vs, "%")) { + volume_type = VOL_PERCENT; + vs[strlen(vs)-1] = 0; + } + if (pa_endswith(vs, "db") || pa_endswith(vs, "dB")) { + volume_type = VOL_DECIBEL; + vs[strlen(vs)-2] = 0; + } + + if (pa_atod(vs, &v) < 0) { + pa_log(_("Invalid volume specification")); + pa_xfree(vs); + return -1; + } + + pa_xfree(vs); + + if (volume_type == VOL_PERCENT) + v = v * (double) PA_VOLUME_NORM / 100; + if (volume_type == VOL_LINEAR) + v = pa_sw_volume_from_linear(v); + if (volume_type == VOL_DECIBEL) + v = pa_sw_volume_from_dB(v); + + if (!PA_VOLUME_IS_VALID((pa_volume_t) v)) { + pa_log(_("Volume outside permissible range.\n")); + return -1; + } + + *vol = (pa_volume_t) v; + + return 0; +} + static void help(const char *argv0) { printf(_("%s [options] stat\n" @@ -1235,7 +1289,6 @@ int main(int argc, char *argv[]) { port_name = pa_xstrdup(argv[optind+2]); } else if (pa_streq(argv[optind], "set-sink-volume")) { - uint32_t v; action = SET_SINK_VOLUME; if (argc != optind+3) { @@ -1243,21 +1296,12 @@ int main(int argc, char *argv[]) { goto quit; } - if (pa_atou(argv[optind+2], &v) < 0) { - pa_log(_("Invalid volume specification")); - goto quit; - } + sink_name = pa_xstrdup(argv[optind+1]); - if (!PA_VOLUME_IS_VALID(v)) { - pa_log(_("Volume outside permissible range.\n")); + if (parse_volume(argv[optind+2], &volume) < 0) goto quit; - } - - sink_name = pa_xstrdup(argv[optind+1]); - volume = (pa_volume_t) v; } else if (pa_streq(argv[optind], "set-source-volume")) { - uint32_t v; action = SET_SOURCE_VOLUME; if (argc != optind+3) { @@ -1265,21 +1309,12 @@ int main(int argc, char *argv[]) { goto quit; } - if (pa_atou(argv[optind+2], &v) < 0) { - pa_log(_("Invalid volume specification")); - goto quit; - } + source_name = pa_xstrdup(argv[optind+1]); - if (!PA_VOLUME_IS_VALID(v)) { - pa_log(_("Volume outside permissible range.\n")); + if (parse_volume(argv[optind+2], &volume) < 0) goto quit; - } - - source_name = pa_xstrdup(argv[optind+1]); - volume = (pa_volume_t) v; } else if (pa_streq(argv[optind], "set-sink-input-volume")) { - uint32_t v; action = SET_SINK_INPUT_VOLUME; if (argc != optind+3) { @@ -1292,17 +1327,8 @@ int main(int argc, char *argv[]) { goto quit; } - if (pa_atou(argv[optind+2], &v) < 0) { - pa_log(_("Invalid volume specification")); - goto quit; - } - - if (!PA_VOLUME_IS_VALID(v)) { - pa_log(_("Volume outside permissible range.\n")); + if (parse_volume(argv[optind+2], &volume) < 0) goto quit; - } - - volume = (pa_volume_t) v; } else if (pa_streq(argv[optind], "set-sink-mute")) { int b; @@ -1314,7 +1340,7 @@ int main(int argc, char *argv[]) { } if ((b = pa_parse_boolean(argv[optind+2])) < 0) { - pa_log(_("Invalid volume specification")); + pa_log(_("Invalid mute specification")); goto quit; } @@ -1331,7 +1357,7 @@ int main(int argc, char *argv[]) { } if ((b = pa_parse_boolean(argv[optind+2])) < 0) { - pa_log(_("Invalid volume specification")); + pa_log(_("Invalid mute specification")); goto quit; } @@ -1353,7 +1379,7 @@ int main(int argc, char *argv[]) { } if ((b = pa_parse_boolean(argv[optind+2])) < 0) { - pa_log(_("Invalid volume specification")); + pa_log(_("Invalid mute specification")); goto quit; } -- 1.7.1