mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-11-10 00:05:42 +01:00
amixer: Add the support for mapped volumes like alsamixer
When -M option is given, amixer handles the volumes in percent unit with the mapping more intuitive to human ears just like in alsamixer. The -R option is to take the raw value as the volume percentage. This mode is still used as default. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
2d105e0f18
commit
a2b66855e6
2 changed files with 141 additions and 99 deletions
|
@ -4,7 +4,7 @@ LDADD = -lm
|
||||||
# CFLAGS += -g -Wall
|
# CFLAGS += -g -Wall
|
||||||
|
|
||||||
bin_PROGRAMS = amixer
|
bin_PROGRAMS = amixer
|
||||||
amixer_SOURCES = amixer.c
|
amixer_SOURCES = amixer.c ../alsamixer/volume_mapping.c
|
||||||
noinst_HEADERS = amixer.h
|
noinst_HEADERS = amixer.h
|
||||||
man_MANS = amixer.1
|
man_MANS = amixer.1
|
||||||
EXTRA_DIST = amixer.1
|
EXTRA_DIST = amixer.1
|
||||||
|
|
234
amixer/amixer.c
234
amixer/amixer.c
|
@ -29,7 +29,9 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <alsa/asoundlib.h>
|
#include <alsa/asoundlib.h>
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include "amixer.h"
|
#include "amixer.h"
|
||||||
|
#include "../alsamixer/volume_mapping.h"
|
||||||
|
|
||||||
#define LEVEL_BASIC (1<<0)
|
#define LEVEL_BASIC (1<<0)
|
||||||
#define LEVEL_INACTIVE (1<<1)
|
#define LEVEL_INACTIVE (1<<1)
|
||||||
|
@ -68,6 +70,8 @@ static int help(void)
|
||||||
printf(" -i,--inactive show also inactive controls\n");
|
printf(" -i,--inactive show also inactive controls\n");
|
||||||
printf(" -a,--abstract L select abstraction level (none or basic)\n");
|
printf(" -a,--abstract L select abstraction level (none or basic)\n");
|
||||||
printf(" -s,--stdin Read and execute commands from stdin sequentially\n");
|
printf(" -s,--stdin Read and execute commands from stdin sequentially\n");
|
||||||
|
printf(" -R,--raw-volume Use the raw value (default)\n");
|
||||||
|
printf(" -M,--mapped-volume Use the mapped volume\n");
|
||||||
printf("\nAvailable commands:\n");
|
printf("\nAvailable commands:\n");
|
||||||
printf(" scontrols show all mixer simple controls\n");
|
printf(" scontrols show all mixer simple controls\n");
|
||||||
printf(" scontents show contents of all mixer simple controls (default command)\n");
|
printf(" scontents show contents of all mixer simple controls (default command)\n");
|
||||||
|
@ -187,9 +191,9 @@ static int convert_db_range(int val, int omin, int omax, int nmin, int nmax)
|
||||||
|
|
||||||
/* Fuction to convert from volume to percentage. val = volume */
|
/* Fuction to convert from volume to percentage. val = volume */
|
||||||
|
|
||||||
static int convert_prange(int val, int min, int max)
|
static int convert_prange(long val, long min, long max)
|
||||||
{
|
{
|
||||||
int range = max - min;
|
long range = max - min;
|
||||||
int tmp;
|
int tmp;
|
||||||
|
|
||||||
if (range == 0)
|
if (range == 0)
|
||||||
|
@ -204,29 +208,6 @@ static int convert_prange(int val, int min, int max)
|
||||||
#define convert_prange1(val, min, max) \
|
#define convert_prange1(val, min, max) \
|
||||||
ceil((val) * ((max) - (min)) * 0.01 + (min))
|
ceil((val) * ((max) - (min)) * 0.01 + (min))
|
||||||
|
|
||||||
static const char *get_percent(int val, int min, int max)
|
|
||||||
{
|
|
||||||
static char str[32];
|
|
||||||
int p;
|
|
||||||
|
|
||||||
p = convert_prange(val, min, max);
|
|
||||||
sprintf(str, "%i [%i%%]", val, p);
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static const char *get_percent1(int val, int min, int max, int min_dB, int max_dB)
|
|
||||||
{
|
|
||||||
static char str[32];
|
|
||||||
int p, db;
|
|
||||||
|
|
||||||
p = convert_prange(val, min, max);
|
|
||||||
db = convert_db_range(val, min, max, min_dB, max_dB);
|
|
||||||
sprintf(str, "%i [%i%%] [%i.%02idB]", val, p, db / 100, abs(db % 100));
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static long get_integer(char **ptr, long min, long max)
|
static long get_integer(char **ptr, long min, long max)
|
||||||
{
|
{
|
||||||
long val = min;
|
long val = min;
|
||||||
|
@ -288,26 +269,83 @@ struct volume_ops {
|
||||||
int (*get)(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t c,
|
int (*get)(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t c,
|
||||||
long *value);
|
long *value);
|
||||||
int (*set)(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t c,
|
int (*set)(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t c,
|
||||||
long value);
|
long value, int dir);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { VOL_RAW, VOL_DB };
|
enum { VOL_RAW, VOL_DB, VOL_MAP };
|
||||||
|
|
||||||
struct volume_ops_set {
|
struct volume_ops_set {
|
||||||
int (*has_volume)(snd_mixer_elem_t *elem);
|
int (*has_volume)(snd_mixer_elem_t *elem);
|
||||||
struct volume_ops v[2];
|
struct volume_ops v[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
static int set_playback_dB(snd_mixer_elem_t *elem,
|
static int set_playback_dB(snd_mixer_elem_t *elem,
|
||||||
snd_mixer_selem_channel_id_t c, long value)
|
snd_mixer_selem_channel_id_t c, long value, int dir)
|
||||||
{
|
{
|
||||||
return snd_mixer_selem_set_playback_dB(elem, c, value, 0);
|
return snd_mixer_selem_set_playback_dB(elem, c, value, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_capture_dB(snd_mixer_elem_t *elem,
|
static int set_capture_dB(snd_mixer_elem_t *elem,
|
||||||
snd_mixer_selem_channel_id_t c, long value)
|
snd_mixer_selem_channel_id_t c, long value, int dir)
|
||||||
{
|
{
|
||||||
return snd_mixer_selem_set_capture_dB(elem, c, value, 0);
|
return snd_mixer_selem_set_capture_dB(elem, c, value, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_playback_raw_volume(snd_mixer_elem_t *elem,
|
||||||
|
snd_mixer_selem_channel_id_t c,
|
||||||
|
long value, int dir)
|
||||||
|
{
|
||||||
|
return snd_mixer_selem_set_playback_volume(elem, c, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_capture_raw_volume(snd_mixer_elem_t *elem,
|
||||||
|
snd_mixer_selem_channel_id_t c,
|
||||||
|
long value, int dir)
|
||||||
|
{
|
||||||
|
return snd_mixer_selem_set_capture_volume(elem, c, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: normalize to int32 space to be compatible with other types */
|
||||||
|
#define MAP_VOL_RES (INT32_MAX / 100)
|
||||||
|
|
||||||
|
static int get_mapped_volume_range(snd_mixer_elem_t *elem,
|
||||||
|
long *pmin, long *pmax)
|
||||||
|
{
|
||||||
|
*pmin = 0;
|
||||||
|
*pmax = MAP_VOL_RES;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_playback_mapped_volume(snd_mixer_elem_t *elem,
|
||||||
|
snd_mixer_selem_channel_id_t c,
|
||||||
|
long *value)
|
||||||
|
{
|
||||||
|
*value = (rint)(get_normalized_playback_volume(elem, c) * MAP_VOL_RES);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_playback_mapped_volume(snd_mixer_elem_t *elem,
|
||||||
|
snd_mixer_selem_channel_id_t c,
|
||||||
|
long value, int dir)
|
||||||
|
{
|
||||||
|
return set_normalized_playback_volume(elem, c,
|
||||||
|
(double)value / MAP_VOL_RES, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_capture_mapped_volume(snd_mixer_elem_t *elem,
|
||||||
|
snd_mixer_selem_channel_id_t c,
|
||||||
|
long *value)
|
||||||
|
{
|
||||||
|
*value = (rint)(get_normalized_capture_volume(elem, c) * MAP_VOL_RES);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_capture_mapped_volume(snd_mixer_elem_t *elem,
|
||||||
|
snd_mixer_selem_channel_id_t c,
|
||||||
|
long value, int dir)
|
||||||
|
{
|
||||||
|
return set_normalized_capture_volume(elem, c,
|
||||||
|
(double)value / MAP_VOL_RES, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct volume_ops_set vol_ops[2] = {
|
static const struct volume_ops_set vol_ops[2] = {
|
||||||
|
@ -315,29 +353,42 @@ static const struct volume_ops_set vol_ops[2] = {
|
||||||
.has_volume = snd_mixer_selem_has_playback_volume,
|
.has_volume = snd_mixer_selem_has_playback_volume,
|
||||||
.v = {{ snd_mixer_selem_get_playback_volume_range,
|
.v = {{ snd_mixer_selem_get_playback_volume_range,
|
||||||
snd_mixer_selem_get_playback_volume,
|
snd_mixer_selem_get_playback_volume,
|
||||||
snd_mixer_selem_set_playback_volume },
|
set_playback_raw_volume },
|
||||||
{ snd_mixer_selem_get_playback_dB_range,
|
{ snd_mixer_selem_get_playback_dB_range,
|
||||||
snd_mixer_selem_get_playback_dB,
|
snd_mixer_selem_get_playback_dB,
|
||||||
set_playback_dB }},
|
set_playback_dB },
|
||||||
|
{ get_mapped_volume_range,
|
||||||
|
get_playback_mapped_volume,
|
||||||
|
set_playback_mapped_volume },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.has_volume = snd_mixer_selem_has_capture_volume,
|
.has_volume = snd_mixer_selem_has_capture_volume,
|
||||||
.v = {{ snd_mixer_selem_get_capture_volume_range,
|
.v = {{ snd_mixer_selem_get_capture_volume_range,
|
||||||
snd_mixer_selem_get_capture_volume,
|
snd_mixer_selem_get_capture_volume,
|
||||||
snd_mixer_selem_set_capture_volume },
|
set_capture_raw_volume },
|
||||||
{ snd_mixer_selem_get_capture_dB_range,
|
{ snd_mixer_selem_get_capture_dB_range,
|
||||||
snd_mixer_selem_get_capture_dB,
|
snd_mixer_selem_get_capture_dB,
|
||||||
set_capture_dB }},
|
set_capture_dB },
|
||||||
|
{ get_mapped_volume_range,
|
||||||
|
get_capture_mapped_volume,
|
||||||
|
set_capture_mapped_volume },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int std_vol_type = VOL_RAW;
|
||||||
|
|
||||||
static int set_volume_simple(snd_mixer_elem_t *elem,
|
static int set_volume_simple(snd_mixer_elem_t *elem,
|
||||||
snd_mixer_selem_channel_id_t chn,
|
snd_mixer_selem_channel_id_t chn,
|
||||||
char **ptr, int dir)
|
char **ptr, int dir)
|
||||||
{
|
{
|
||||||
long val, orig, pmin, pmax;
|
long val, orig, pmin, pmax;
|
||||||
char *p = *ptr, *s;
|
char *p = *ptr, *s;
|
||||||
int invalid = 0, err = 0, vol_type = VOL_RAW;
|
int invalid = 0, percent = 0, err = 0;
|
||||||
|
int vol_type = std_vol_type;
|
||||||
|
double scale = 1.0;
|
||||||
|
int correct = 0;
|
||||||
|
|
||||||
if (! vol_ops[dir].has_volume(elem))
|
if (! vol_ops[dir].has_volume(elem))
|
||||||
invalid = 1;
|
invalid = 1;
|
||||||
|
@ -347,10 +398,6 @@ static int set_volume_simple(snd_mixer_elem_t *elem,
|
||||||
if (*p == '\0' || (!isdigit(*p) && *p != '-'))
|
if (*p == '\0' || (!isdigit(*p) && *p != '-'))
|
||||||
goto skip;
|
goto skip;
|
||||||
|
|
||||||
if (! invalid &&
|
|
||||||
vol_ops[dir].v[VOL_RAW].get_range(elem, &pmin, &pmax) < 0)
|
|
||||||
invalid = 1;
|
|
||||||
|
|
||||||
s = p;
|
s = p;
|
||||||
val = strtol(s, &p, 10);
|
val = strtol(s, &p, 10);
|
||||||
if (*p == '.') {
|
if (*p == '.') {
|
||||||
|
@ -358,32 +405,37 @@ static int set_volume_simple(snd_mixer_elem_t *elem,
|
||||||
strtol(p, &p, 10);
|
strtol(p, &p, 10);
|
||||||
}
|
}
|
||||||
if (*p == '%') {
|
if (*p == '%') {
|
||||||
if (! invalid)
|
percent = 1;
|
||||||
val = (long)convert_prange1(strtod(s, NULL), pmin, pmax);
|
|
||||||
p++;
|
p++;
|
||||||
} else if (p[0] == 'd' && p[1] == 'B') {
|
} else if (p[0] == 'd' && p[1] == 'B') {
|
||||||
if (! invalid) {
|
|
||||||
val = (long)(strtod(s, NULL) * 100.0);
|
|
||||||
vol_type = VOL_DB;
|
vol_type = VOL_DB;
|
||||||
|
p += 2;
|
||||||
|
scale = 100;
|
||||||
|
} else
|
||||||
|
vol_type = VOL_RAW;
|
||||||
|
|
||||||
|
val = (long)(strtod(s, NULL) * scale);
|
||||||
if (vol_ops[dir].v[vol_type].get_range(elem, &pmin, &pmax) < 0)
|
if (vol_ops[dir].v[vol_type].get_range(elem, &pmin, &pmax) < 0)
|
||||||
invalid = 1;
|
invalid = 1;
|
||||||
}
|
if (percent)
|
||||||
p += 2;
|
val = (long)convert_prange1(val, pmin, pmax);
|
||||||
}
|
|
||||||
if (*p == '+' || *p == '-') {
|
if (*p == '+' || *p == '-') {
|
||||||
if (! invalid) {
|
if (! invalid) {
|
||||||
if (vol_ops[dir].v[vol_type].get(elem, chn, &orig) < 0)
|
if (vol_ops[dir].v[vol_type].get(elem, chn, &orig) < 0)
|
||||||
invalid = 1;
|
invalid = 1;
|
||||||
if (*p == '+')
|
if (*p == '+') {
|
||||||
val = orig + val;
|
val = orig + val;
|
||||||
else
|
correct = -1;
|
||||||
|
} else {
|
||||||
val = orig - val;
|
val = orig - val;
|
||||||
|
correct = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
if (! invalid) {
|
if (! invalid) {
|
||||||
val = check_range(val, pmin, pmax);
|
val = check_range(val, pmin, pmax);
|
||||||
err = vol_ops[dir].v[vol_type].set(elem, chn, val);
|
err = vol_ops[dir].v[vol_type].set(elem, chn, val, correct);
|
||||||
}
|
}
|
||||||
skip:
|
skip:
|
||||||
if (*p == ',')
|
if (*p == ',')
|
||||||
|
@ -711,15 +763,33 @@ static int controls(int level)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void show_selem_volume(snd_mixer_elem_t *elem,
|
||||||
|
snd_mixer_selem_channel_id_t chn, int dir,
|
||||||
|
long min, long max)
|
||||||
|
{
|
||||||
|
long raw, val;
|
||||||
|
vol_ops[dir].v[VOL_RAW].get(elem, chn, &raw);
|
||||||
|
if (std_vol_type == VOL_RAW)
|
||||||
|
val = convert_prange(raw, min, max);
|
||||||
|
else {
|
||||||
|
vol_ops[dir].v[std_vol_type].get(elem, chn, &val);
|
||||||
|
val = convert_prange(val, 0, MAP_VOL_RES);
|
||||||
|
}
|
||||||
|
printf(" %li [%li%%]", raw, val);
|
||||||
|
if (!vol_ops[dir].v[VOL_DB].get(elem, chn, &val)) {
|
||||||
|
printf(" [");
|
||||||
|
print_dB(val);
|
||||||
|
printf("]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int show_selem(snd_mixer_t *handle, snd_mixer_selem_id_t *id, const char *space, int level)
|
static int show_selem(snd_mixer_t *handle, snd_mixer_selem_id_t *id, const char *space, int level)
|
||||||
{
|
{
|
||||||
snd_mixer_selem_channel_id_t chn;
|
snd_mixer_selem_channel_id_t chn;
|
||||||
long pmin = 0, pmax = 0;
|
long pmin = 0, pmax = 0;
|
||||||
long cmin = 0, cmax = 0;
|
long cmin = 0, cmax = 0;
|
||||||
long pvol, cvol;
|
|
||||||
int psw, csw;
|
int psw, csw;
|
||||||
int pmono, cmono, mono_ok = 0;
|
int pmono, cmono, mono_ok = 0;
|
||||||
long db;
|
|
||||||
snd_mixer_elem_t *elem;
|
snd_mixer_elem_t *elem;
|
||||||
|
|
||||||
elem = snd_mixer_find_selem(handle, id);
|
elem = snd_mixer_find_selem(handle, id);
|
||||||
|
@ -868,13 +938,7 @@ static int show_selem(snd_mixer_t *handle, snd_mixer_selem_id_t *id, const char
|
||||||
mono_ok = 1;
|
mono_ok = 1;
|
||||||
}
|
}
|
||||||
if (snd_mixer_selem_has_common_volume(elem)) {
|
if (snd_mixer_selem_has_common_volume(elem)) {
|
||||||
snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_MONO, &pvol);
|
show_selem_volume(elem, SND_MIXER_SCHN_MONO, 0, pmin, pmax);
|
||||||
printf(" %s", get_percent(pvol, pmin, pmax));
|
|
||||||
if (!snd_mixer_selem_get_playback_dB(elem, SND_MIXER_SCHN_MONO, &db)) {
|
|
||||||
printf(" [");
|
|
||||||
print_dB(db);
|
|
||||||
printf("]");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (snd_mixer_selem_has_common_switch(elem)) {
|
if (snd_mixer_selem_has_common_switch(elem)) {
|
||||||
snd_mixer_selem_get_playback_switch(elem, SND_MIXER_SCHN_MONO, &psw);
|
snd_mixer_selem_get_playback_switch(elem, SND_MIXER_SCHN_MONO, &psw);
|
||||||
|
@ -891,13 +955,7 @@ static int show_selem(snd_mixer_t *handle, snd_mixer_selem_id_t *id, const char
|
||||||
if (snd_mixer_selem_has_playback_volume(elem)) {
|
if (snd_mixer_selem_has_playback_volume(elem)) {
|
||||||
printf(" Playback");
|
printf(" Playback");
|
||||||
title = 1;
|
title = 1;
|
||||||
snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_MONO, &pvol);
|
show_selem_volume(elem, SND_MIXER_SCHN_MONO, 0, pmin, pmax);
|
||||||
printf(" %s", get_percent(pvol, pmin, pmax));
|
|
||||||
if (!snd_mixer_selem_get_playback_dB(elem, SND_MIXER_SCHN_MONO, &db)) {
|
|
||||||
printf(" [");
|
|
||||||
print_dB(db);
|
|
||||||
printf("]");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!snd_mixer_selem_has_common_switch(elem)) {
|
if (!snd_mixer_selem_has_common_switch(elem)) {
|
||||||
|
@ -919,13 +977,7 @@ static int show_selem(snd_mixer_t *handle, snd_mixer_selem_id_t *id, const char
|
||||||
if (snd_mixer_selem_has_capture_volume(elem)) {
|
if (snd_mixer_selem_has_capture_volume(elem)) {
|
||||||
printf(" Capture");
|
printf(" Capture");
|
||||||
title = 1;
|
title = 1;
|
||||||
snd_mixer_selem_get_capture_volume(elem, SND_MIXER_SCHN_MONO, &cvol);
|
show_selem_volume(elem, SND_MIXER_SCHN_MONO, 1, cmin, cmax);
|
||||||
printf(" %s", get_percent(cvol, cmin, cmax));
|
|
||||||
if (!snd_mixer_selem_get_capture_dB(elem, SND_MIXER_SCHN_MONO, &db)) {
|
|
||||||
printf(" [");
|
|
||||||
print_dB(db);
|
|
||||||
printf("]");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!snd_mixer_selem_has_common_switch(elem)) {
|
if (!snd_mixer_selem_has_common_switch(elem)) {
|
||||||
|
@ -946,13 +998,7 @@ static int show_selem(snd_mixer_t *handle, snd_mixer_selem_id_t *id, const char
|
||||||
continue;
|
continue;
|
||||||
printf("%s%s:", space, snd_mixer_selem_channel_name(chn));
|
printf("%s%s:", space, snd_mixer_selem_channel_name(chn));
|
||||||
if (!pmono && !cmono && snd_mixer_selem_has_common_volume(elem)) {
|
if (!pmono && !cmono && snd_mixer_selem_has_common_volume(elem)) {
|
||||||
snd_mixer_selem_get_playback_volume(elem, chn, &pvol);
|
show_selem_volume(elem, chn, 0, pmin, pmax);
|
||||||
printf(" %s", get_percent(pvol, pmin, pmax));
|
|
||||||
if (!snd_mixer_selem_get_playback_dB(elem, chn, &db)) {
|
|
||||||
printf(" [");
|
|
||||||
print_dB(db);
|
|
||||||
printf("]");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!pmono && !cmono && snd_mixer_selem_has_common_switch(elem)) {
|
if (!pmono && !cmono && snd_mixer_selem_has_common_switch(elem)) {
|
||||||
snd_mixer_selem_get_playback_switch(elem, chn, &psw);
|
snd_mixer_selem_get_playback_switch(elem, chn, &psw);
|
||||||
|
@ -964,13 +1010,7 @@ static int show_selem(snd_mixer_t *handle, snd_mixer_selem_id_t *id, const char
|
||||||
if (snd_mixer_selem_has_playback_volume(elem)) {
|
if (snd_mixer_selem_has_playback_volume(elem)) {
|
||||||
printf(" Playback");
|
printf(" Playback");
|
||||||
title = 1;
|
title = 1;
|
||||||
snd_mixer_selem_get_playback_volume(elem, chn, &pvol);
|
show_selem_volume(elem, chn, 0, pmin, pmax);
|
||||||
printf(" %s", get_percent(pvol, pmin, pmax));
|
|
||||||
if (!snd_mixer_selem_get_playback_dB(elem, chn, &db)) {
|
|
||||||
printf(" [");
|
|
||||||
print_dB(db);
|
|
||||||
printf("]");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!snd_mixer_selem_has_common_switch(elem)) {
|
if (!snd_mixer_selem_has_common_switch(elem)) {
|
||||||
|
@ -988,13 +1028,7 @@ static int show_selem(snd_mixer_t *handle, snd_mixer_selem_id_t *id, const char
|
||||||
if (snd_mixer_selem_has_capture_volume(elem)) {
|
if (snd_mixer_selem_has_capture_volume(elem)) {
|
||||||
printf(" Capture");
|
printf(" Capture");
|
||||||
title = 1;
|
title = 1;
|
||||||
snd_mixer_selem_get_capture_volume(elem, chn, &cvol);
|
show_selem_volume(elem, chn, 1, cmin, cmax);
|
||||||
printf(" %s", get_percent(cvol, cmin, cmax));
|
|
||||||
if (!snd_mixer_selem_get_capture_dB(elem, chn, &db)) {
|
|
||||||
printf(" [");
|
|
||||||
print_dB(db);
|
|
||||||
printf("]");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!snd_mixer_selem_has_common_switch(elem)) {
|
if (!snd_mixer_selem_has_common_switch(elem)) {
|
||||||
|
@ -1927,6 +1961,8 @@ int main(int argc, char *argv[])
|
||||||
{"version", 0, NULL, 'v'},
|
{"version", 0, NULL, 'v'},
|
||||||
{"abstract", 1, NULL, 'a'},
|
{"abstract", 1, NULL, 'a'},
|
||||||
{"stdin", 0, NULL, 's'},
|
{"stdin", 0, NULL, 's'},
|
||||||
|
{"raw-volume", 0, NULL, 'R'},
|
||||||
|
{"mapped-volume", 0, NULL, 'M'},
|
||||||
{NULL, 0, NULL, 0},
|
{NULL, 0, NULL, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1934,7 +1970,7 @@ int main(int argc, char *argv[])
|
||||||
while (1) {
|
while (1) {
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
if ((c = getopt_long(argc, argv, "hc:D:qidnva:s", long_option, NULL)) < 0)
|
if ((c = getopt_long(argc, argv, "hc:D:qidnva:sRM", long_option, NULL)) < 0)
|
||||||
break;
|
break;
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'h':
|
case 'h':
|
||||||
|
@ -1987,6 +2023,12 @@ int main(int argc, char *argv[])
|
||||||
case 's':
|
case 's':
|
||||||
read_stdin = 1;
|
read_stdin = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'R':
|
||||||
|
std_vol_type = VOL_RAW;
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
std_vol_type = VOL_MAP;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Invalid switch or option needs an argument.\n");
|
fprintf(stderr, "Invalid switch or option needs an argument.\n");
|
||||||
morehelp++;
|
morehelp++;
|
||||||
|
|
Loading…
Reference in a new issue