From 1a2e4a61990cd5985f67af4dc357a90b5933dcfb Mon Sep 17 00:00:00 2001 From: Abramo Bagnara Date: Thu, 15 Feb 2001 23:05:42 +0000 Subject: [PATCH] New simple mixer implementation --- alsamixer/alsamixer.c | 233 +++++++++++++++++++++--------------------- amixer/amixer.c | 213 ++++++++++++++++++++++---------------- 2 files changed, 244 insertions(+), 202 deletions(-) diff --git a/alsamixer/alsamixer.c b/alsamixer/alsamixer.c index 0e27be2..39b1bd5 100644 --- a/alsamixer/alsamixer.c +++ b/alsamixer/alsamixer.c @@ -465,14 +465,14 @@ mixer_conv(int val, int omin, int omax, int nmin, int nmax) } static int -mixer_calc_volume(snd_mixer_selem_info_t *info, - snd_mixer_selem_value_t *value, +mixer_calc_volume(snd_mixer_elem_t *elem, int vol, snd_mixer_selem_channel_id_t chn) { int vol1; - long min = snd_mixer_selem_info_get_min(info); - long max = snd_mixer_selem_info_get_max(info); + long v; + long min = snd_mixer_selem_get_playback_min(elem); + long max = snd_mixer_selem_get_playback_max(elem); vol1 = (vol < 0) ? -vol : vol; if (vol1 > 0) { if (vol1 > 100) @@ -484,7 +484,8 @@ mixer_calc_volume(snd_mixer_selem_info_t *info, if (vol < 0) vol1 = -vol1; } - vol1 += snd_mixer_selem_value_get_volume(value, chn); + snd_mixer_selem_get_playback_volume(elem, chn, &v); + vol1 += v; return CLAMP(vol1, min, max); } @@ -494,15 +495,11 @@ static void mixer_write_cbar (int elem_index) { snd_mixer_elem_t *elem; - snd_mixer_selem_info_t *info; - snd_mixer_selem_value_t *value; int vleft, vright, vbalance; int type; snd_mixer_selem_id_t *sid; snd_mixer_selem_channel_id_t chn_left, chn_right, chn; - int err, changed; - snd_mixer_selem_info_alloca(&info); - snd_mixer_selem_value_alloca(&value); + int sw; if (mixer_sid == NULL) return; @@ -511,52 +508,59 @@ mixer_write_cbar (int elem_index) elem = snd_mixer_find_selem(mixer_handle, sid); if (elem == NULL) CHECK_ABORT (ERR_FCN, "snd_mixer_find_selem()", -EINVAL); - if ((err = snd_mixer_selem_info(elem, info)) < 0) - CHECK_ABORT (ERR_FCN, "snd_mixer_selem_info()", err); - if ((err = snd_mixer_selem_read(elem, value)) < 0) - CHECK_ABORT (ERR_FCN, "snd_mixer_selem_read()", err); type = mixer_type[elem_index]; chn_left = mixer_elem_chn[type][MIXER_CHN_LEFT]; - if (!snd_mixer_selem_info_has_channel(info, chn_left)) + if (!snd_mixer_selem_has_playback_channel(elem, chn_left)) return; /* ..??.. */ chn_right = mixer_elem_chn[type][MIXER_CHN_RIGHT]; - if (chn_right != SND_MIXER_SCHN_UNKNOWN && ! snd_mixer_selem_info_has_channel(info, chn_right)) + if (chn_right != SND_MIXER_SCHN_UNKNOWN && + !snd_mixer_selem_has_playback_channel(elem, chn_right)) chn_right = SND_MIXER_SCHN_UNKNOWN; - changed = 0; - /* volume */ if ((mixer_volume_delta[MIXER_CHN_LEFT] || mixer_volume_delta[MIXER_CHN_RIGHT] || mixer_balance_volumes) && - snd_mixer_selem_info_has_volume(info)) { + snd_mixer_selem_has_playback_volume(elem)) { int mono = (chn_right == SND_MIXER_SCHN_UNKNOWN || - snd_mixer_selem_info_has_joined_volume(info)); + snd_mixer_selem_has_playback_volume_joined(elem)); if (mono && !mixer_volume_delta[MIXER_CHN_LEFT]) mixer_volume_delta[MIXER_CHN_LEFT] = mixer_volume_delta[MIXER_CHN_RIGHT]; - vleft = mixer_calc_volume(info, value, mixer_volume_delta[MIXER_CHN_LEFT], chn_left); + vleft = mixer_calc_volume(elem, mixer_volume_delta[MIXER_CHN_LEFT], chn_left); vbalance = vleft; if (! mono) { - vright = mixer_calc_volume(info, value, mixer_volume_delta[MIXER_CHN_RIGHT], chn_right); + vright = mixer_calc_volume(elem, mixer_volume_delta[MIXER_CHN_RIGHT], chn_right); vbalance += vright; vbalance /= 2; } else vright = vleft; if (vleft >= 0 && vright >= 0) { - if (snd_mixer_selem_info_has_joined_volume(info)) { + if (snd_mixer_selem_has_playback_volume_joined(elem)) { for (chn = 0; chn < SND_MIXER_SCHN_LAST; snd_enum_incr(chn)) - if (snd_mixer_selem_info_has_channel(info, chn)) - snd_mixer_selem_value_set_volume(value, chn, vleft); + if (snd_mixer_selem_has_playback_channel(elem, chn)) + snd_mixer_selem_set_playback_volume(elem, chn, vleft); + if (snd_mixer_selem_has_capture_channel(elem, chn)) + snd_mixer_selem_set_capture_volume(elem, chn, vleft); } else { if (mixer_balance_volumes) vleft = vright = vbalance; - snd_mixer_selem_value_set_volume(value, chn_left, vleft); - if (! mono) - snd_mixer_selem_value_set_volume(value, chn_right, vright); + if (snd_mixer_selem_has_playback_volume(elem) && + snd_mixer_selem_has_playback_channel(elem, chn_left)) + snd_mixer_selem_set_playback_volume(elem, chn_left, vleft); + if (snd_mixer_selem_has_capture_volume(elem) && + snd_mixer_selem_has_capture_channel(elem, chn_left)) + snd_mixer_selem_set_capture_volume(elem, chn_left, vleft); + if (! mono) { + if (snd_mixer_selem_has_playback_volume(elem) && + snd_mixer_selem_has_playback_channel(elem, chn_right)) + snd_mixer_selem_set_playback_volume(elem, chn_right, vright); + if (snd_mixer_selem_has_capture_volume(elem) && + snd_mixer_selem_has_capture_channel(elem, chn_right)) + snd_mixer_selem_set_capture_volume(elem, chn_right, vright); + } } - changed = 1; } } mixer_volume_delta[MIXER_CHN_LEFT] = mixer_volume_delta[MIXER_CHN_RIGHT] = 0; @@ -564,39 +568,43 @@ mixer_write_cbar (int elem_index) /* mute */ - if (mixer_toggle_mute && snd_mixer_selem_info_has_mute(info)) { - if (snd_mixer_selem_info_has_joined_mute(info)) - snd_mixer_selem_value_set_mute_all(value, snd_mixer_selem_value_get_mute(value, chn_left) ? 0 : 1); - else { - if (mixer_toggle_mute & MIXER_MASK_LEFT) - snd_mixer_selem_value_set_mute(value, chn_left, snd_mixer_selem_value_get_mute(value, chn_left) ? 0 : 1); + if (mixer_toggle_mute && snd_mixer_selem_has_playback_switch(elem)) { + if (snd_mixer_selem_has_playback_switch_joined(elem)) { + snd_mixer_selem_get_playback_switch(elem, chn_left, &sw); + snd_mixer_selem_set_playback_switch_all(elem, !sw); + } else { + if (mixer_toggle_mute & MIXER_MASK_LEFT) { + snd_mixer_selem_get_playback_switch(elem, chn_left, &sw); + snd_mixer_selem_set_playback_switch(elem, chn_left, !sw); + } if (chn_right != SND_MIXER_SCHN_UNKNOWN && - (mixer_toggle_mute & MIXER_MASK_RIGHT)) - snd_mixer_selem_value_set_mute(value, chn_right, snd_mixer_selem_value_get_mute(value, chn_right) ? 0 : 1); + (mixer_toggle_mute & MIXER_MASK_RIGHT)) { + snd_mixer_selem_get_playback_switch(elem, chn_right, &sw); + snd_mixer_selem_set_playback_switch(elem, chn_right, !sw); + } } - changed = 1; } mixer_toggle_mute = 0; /* capture */ - if (mixer_toggle_capture && snd_mixer_selem_info_has_capture(info)) { - if (snd_mixer_selem_info_has_joined_capture(info)) - snd_mixer_selem_value_set_capture_all(value, snd_mixer_selem_value_get_capture(value, chn_left) ? 0 : 1); - else { - if (mixer_toggle_capture & MIXER_MASK_LEFT) - snd_mixer_selem_value_set_capture(value, chn_left, snd_mixer_selem_value_get_capture(value, chn_left) ? 0 : 1); - if (chn_right != SND_MIXER_SCHN_UNKNOWN && (mixer_toggle_capture & MIXER_MASK_RIGHT)) - snd_mixer_selem_value_set_capture(value, chn_right, snd_mixer_selem_value_get_capture(value, chn_right) ? 0 : 1); + if (mixer_toggle_capture && snd_mixer_selem_has_capture_switch(elem)) { + if (snd_mixer_selem_has_capture_switch_joined(elem)) { + snd_mixer_selem_get_capture_switch(elem, chn_left, &sw); + snd_mixer_selem_set_capture_switch_all(elem, !sw); + } else { + if (mixer_toggle_capture & MIXER_MASK_LEFT) { + snd_mixer_selem_get_capture_switch(elem, chn_left, &sw); + snd_mixer_selem_set_capture_switch(elem, chn_left, !sw); + } + if (chn_right != SND_MIXER_SCHN_UNKNOWN && + (mixer_toggle_capture & MIXER_MASK_RIGHT)) { + snd_mixer_selem_get_capture_switch(elem, chn_right, &sw); + snd_mixer_selem_set_capture_switch(elem, chn_right, !sw); + } } - changed = 1; } mixer_toggle_capture = 0; - - if (changed) { - if ((err = snd_mixer_selem_write (elem, value)) < 0) - CHECK_ABORT (ERR_FCN, "snd_mixer_selem_write()", err); - } } @@ -604,17 +612,14 @@ static void mixer_update_cbar (int elem_index) { char string[128], string1[64]; - int err, dc; + int dc; snd_mixer_elem_t *elem; - snd_mixer_selem_info_t *info; - snd_mixer_selem_value_t *value; - int vleft, vright; + long vleft, vright; int type; snd_mixer_selem_id_t *sid; snd_mixer_selem_channel_id_t chn_left, chn_right; int x, y, i; - snd_mixer_selem_info_alloca(&info); - snd_mixer_selem_value_alloca(&value); + int swl, swr; /* set new scontrol indices and read info */ @@ -625,33 +630,33 @@ mixer_update_cbar (int elem_index) elem = snd_mixer_find_selem(mixer_handle, sid); if (elem == NULL) CHECK_ABORT (ERR_FCN, "snd_mixer_find_selem()", -EINVAL); - if ((err = snd_mixer_selem_info(elem, info)) < 0) - CHECK_ABORT (ERR_FCN, "snd_mixer_selem_info()", err); - if ((err = snd_mixer_selem_read(elem, value)) < 0) - CHECK_ABORT (ERR_FCN, "snd_mixer_selem_read()", err); type = mixer_type[elem_index]; chn_left = mixer_elem_chn[type][MIXER_CHN_LEFT]; - if (!snd_mixer_selem_info_has_channel(info, chn_left)) + if (!snd_mixer_selem_has_playback_channel(elem, chn_left)) return; /* ..??.. */ chn_right = mixer_elem_chn[type][MIXER_CHN_RIGHT]; - if (chn_right != SND_MIXER_SCHN_UNKNOWN && ! snd_mixer_selem_info_has_channel(info, chn_right)) + if (chn_right != SND_MIXER_SCHN_UNKNOWN && + !snd_mixer_selem_has_playback_channel(elem, chn_right)) chn_right = SND_MIXER_SCHN_UNKNOWN; - vleft = snd_mixer_selem_value_get_volume(value, chn_left); - vleft = mixer_conv(vleft, - snd_mixer_selem_info_get_min(info), - snd_mixer_selem_info_get_max(info), - 0, 100); - if (chn_right != SND_MIXER_SCHN_UNKNOWN) { - vright = snd_mixer_selem_value_get_volume(value, chn_right); - vright = mixer_conv(vright, - snd_mixer_selem_info_get_min(info), - snd_mixer_selem_info_get_max(info), - 0, 100); - } else { - vright = vleft; - } + if (snd_mixer_selem_has_playback_volume(elem)) { + snd_mixer_selem_get_playback_volume(elem, chn_left, &vleft); + vleft = mixer_conv(vleft, + snd_mixer_selem_get_playback_min(elem), + snd_mixer_selem_get_playback_max(elem), + 0, 100); + if (chn_right != SND_MIXER_SCHN_UNKNOWN) { + snd_mixer_selem_get_playback_volume(elem, chn_right, &vright); + vright = mixer_conv(vright, + snd_mixer_selem_get_playback_min(elem), + snd_mixer_selem_get_playback_max(elem), + 0, 100); + } else { + vright = vleft; + } + } else + vleft = vright = 0; /* update the focused full bar name */ @@ -698,13 +703,13 @@ mixer_update_cbar (int elem_index) mixer_dc (DC_BACK); mvaddstr (y, x, " "); mixer_dc (DC_TEXT); - sprintf (string, "%d", vleft); + sprintf (string, "%ld", vleft); mvaddstr (y, x + 3 - strlen (string), string); mixer_dc (DC_CBAR_FRAME); mvaddch (y, x + 3, '<'); mvaddch (y, x + 4, '>'); mixer_dc (DC_TEXT); - sprintf (string, "%d", vright); + sprintf (string, "%ld", vright); mvaddstr (y, x + 5, string); y--; @@ -741,41 +746,46 @@ mixer_update_cbar (int elem_index) */ mixer_dc (DC_BACK); mvaddstr (y, x, " "); - mixer_dc (DC_CBAR_FRAME); - mvaddch (y, x + 2, ACS_ULCORNER); - dc = snd_mixer_selem_value_get_mute(value, chn_left) ? DC_CBAR_MUTE : DC_CBAR_NOMUTE; - mvaddch (y, x + 3, mixer_dc (dc)); - if (chn_right != SND_MIXER_SCHN_UNKNOWN) - dc = snd_mixer_selem_value_get_mute(value, chn_right) ? DC_CBAR_MUTE : DC_CBAR_NOMUTE; - mvaddch (y, x + 4, mixer_dc (dc)); - mixer_dc (DC_CBAR_FRAME); - mvaddch (y, x + 5, ACS_URCORNER); + if (snd_mixer_selem_has_playback_switch(elem)) { + mixer_dc (DC_CBAR_FRAME); + mvaddch (y, x + 2, ACS_ULCORNER); + snd_mixer_selem_get_playback_switch(elem, chn_left, &swl); + dc = swl ? DC_CBAR_NOMUTE : DC_CBAR_MUTE; + mvaddch (y, x + 3, mixer_dc (dc)); + if (chn_right != SND_MIXER_SCHN_UNKNOWN) { + snd_mixer_selem_get_playback_switch(elem, chn_right, &swr); + dc = swr ? DC_CBAR_NOMUTE : DC_CBAR_MUTE; + } + mvaddch (y, x + 4, mixer_dc (dc)); + mixer_dc (DC_CBAR_FRAME); + mvaddch (y, x + 5, ACS_URCORNER); + } y--; /* capture input? */ - if ((snd_mixer_selem_value_get_capture(value, chn_left)) || - (chn_right != SND_MIXER_SCHN_UNKNOWN && snd_mixer_selem_value_get_capture(value, chn_right))) - { + if (snd_mixer_selem_has_capture_switch(elem)) { + snd_mixer_selem_get_capture_switch(elem, chn_left, &swl); + if (chn_right != SND_MIXER_SCHN_UNKNOWN) + snd_mixer_selem_get_capture_switch(elem, chn_right, &swr); + if (swl || (chn_right != SND_MIXER_SCHN_UNKNOWN && swr)) { mixer_dc (DC_CBAR_CAPTURE); mvaddstr (y, x + 1, "CAPTUR"); - if (snd_mixer_selem_value_get_capture(value, chn_left)) { + if (swl) { mvaddstr (y + 1, x + 1, "L"); if (chn_right == SND_MIXER_SCHN_UNKNOWN) mvaddstr (y + 1, x + 6, "R"); } - if (chn_right != SND_MIXER_SCHN_UNKNOWN && - snd_mixer_selem_value_get_capture(value, chn_right)) + if (chn_right != SND_MIXER_SCHN_UNKNOWN && swr) mvaddstr (y + 1, x + 6, "R"); + } else { + for (i = 0; i < 6; i++) + mvaddch (y, x + 1 + i, mixer_dc (DC_CBAR_NOCAPTURE)); } - else if (snd_mixer_selem_info_has_capture(info)) - for (i = 0; i < 6; i++) - mvaddch (y, x + 1 + i, mixer_dc (DC_CBAR_NOCAPTURE)); - else - { - mixer_dc (DC_BACK); - mvaddstr (y, x, " "); - } + } else { + mixer_dc (DC_BACK); + mvaddstr (y, x, " "); + } y--; } @@ -1243,7 +1253,7 @@ mixer_init (void) mixer_abort (ERR_FCN, "snd_mixer_open", err); if ((err = snd_mixer_attach (mixer_handle, card_id)) < 0) mixer_abort (ERR_FCN, "snd_mixer_attach", err); - if ((err = snd_mixer_selem_register (mixer_handle, NULL)) < 0) + if ((err = snd_mixer_selem_register (mixer_handle, NULL, NULL)) < 0) mixer_abort (ERR_FCN, "snd_mixer_selem_register", err); if ((err = snd_mixer_load (mixer_handle)) < 0) mixer_abort (ERR_FCN, "snd_mixer_load", err); @@ -1258,7 +1268,7 @@ static void mixer_reinit (void) { snd_mixer_elem_t *elem; - int idx, err, elem_index, i, j; + int idx, elem_index, i, j; snd_mixer_selem_id_t *sid; snd_mixer_selem_id_t *focus_gid; int focus_type = -1; @@ -1283,18 +1293,14 @@ mixer_reinit (void) mixer_n_elems = 0; for (idx = 0; idx < mixer_n_selems; idx++) { - snd_mixer_selem_info_t *info; - snd_mixer_selem_info_alloca(&info); sid = (snd_mixer_selem_id_t *)(((char *)mixer_sid) + snd_mixer_selem_id_sizeof() * idx); elem = snd_mixer_find_selem(mixer_handle, sid); if (elem == NULL) CHECK_ABORT (ERR_FCN, "snd_mixer_find_selem()", -EINVAL); - if ((err = snd_mixer_selem_info(elem, info)) < 0) - CHECK_ABORT (ERR_FCN, "snd_mixer_selem_info()", 0); for (i = 0; i < MIXER_ELEM_END; i++) { int ok; for (j = ok = 0; j < 2; j++) { - if (snd_mixer_selem_info_has_channel(info, mixer_elem_chn[i][j])) + if (snd_mixer_selem_has_playback_channel(elem, mixer_elem_chn[i][j])) ok++; } if (ok) @@ -1314,18 +1320,14 @@ mixer_reinit (void) mixer_abort(ERR_FCN, "malloc", 0); elem_index = 0; for (idx = 0; idx < mixer_n_selems; idx++) { - snd_mixer_selem_info_t *info; - snd_mixer_selem_info_alloca(&info); sid = (snd_mixer_selem_id_t *)(((char *)mixer_sid) + snd_mixer_selem_id_sizeof() * idx); elem = snd_mixer_find_selem(mixer_handle, sid); if (elem == NULL) CHECK_ABORT (ERR_FCN, "snd_mixer_find_selem()", -EINVAL); - if ((err = snd_mixer_selem_info(elem, info)) < 0) - CHECK_ABORT (ERR_FCN, "snd_mixer_selem_info()", 0); for (i = 0; i < MIXER_ELEM_END; i++) { int ok; for (j = ok = 0; j < 2; j++) { - if (snd_mixer_selem_info_has_channel(info, mixer_elem_chn[i][j])) + if (snd_mixer_selem_has_playback_channel(elem, mixer_elem_chn[i][j])) ok++; } if (ok) { @@ -1550,6 +1552,7 @@ mixer_iteration (void) mixer_view = VIEW_PROCINFO; key = 0; break; + case '\014': case 'L': case 'l': mixer_clear (TRUE); diff --git a/amixer/amixer.c b/amixer/amixer.c index 40b09d3..ad64dd2 100644 --- a/amixer/amixer.c +++ b/amixer/amixer.c @@ -109,7 +109,7 @@ static int info(void) snd_mixer_close(mhandle); return err; } - if ((err = snd_mixer_selem_register(mhandle, 0)) < 0) { + if ((err = snd_mixer_selem_register(mhandle, NULL, NULL)) < 0) { error("Mixer register error: %s", snd_strerror(err)); snd_mixer_close(mhandle); return err; @@ -423,14 +423,13 @@ static int controls(int level) static int show_selem(snd_mixer_t *handle, snd_mixer_selem_id_t *id, const char *space, int level) { - int err; snd_mixer_selem_channel_id_t chn; - long min, max; + long pmin = 0, pmax = 0; + long cmin = 0, cmax = 0; + long pvol, cvol; + int psw, csw; + int mono; snd_mixer_elem_t *elem; - snd_mixer_selem_info_t *sinfo; - snd_mixer_selem_value_t *scontrol; - snd_mixer_selem_info_alloca(&sinfo); - snd_mixer_selem_value_alloca(&scontrol); elem = snd_mixer_find_selem(handle, id); if (!elem) { @@ -438,65 +437,122 @@ static int show_selem(snd_mixer_t *handle, snd_mixer_selem_id_t *id, const char return -ENOENT; } - if ((err = snd_mixer_selem_info(elem, sinfo)) < 0) { - error("Mixer %s selem info error: %s", card, snd_strerror(err)); - return err; - } - if ((err = snd_mixer_selem_read(elem, scontrol)) < 0) { - error("Mixer %s selem read error: %s", card, snd_strerror(err)); - return err; - } if ((level & 1) != 0) { printf("%sCapabilities:", space); - if (snd_mixer_selem_info_has_volume(sinfo)) + if (snd_mixer_selem_has_common_volume(elem)) { printf(" volume"); - if (snd_mixer_selem_info_has_joined_volume(sinfo)) - printf(" joined-volume"); - if (snd_mixer_selem_info_has_mute(sinfo)) - printf(" mute"); - if (snd_mixer_selem_info_has_joined_mute(sinfo)) - printf(" joined-mute"); - if (snd_mixer_selem_info_has_capture(sinfo)) { - printf(" capture"); + if (snd_mixer_selem_has_playback_volume_joined(elem)) + printf(" volume-joined"); + } else if (snd_mixer_selem_has_playback_volume(elem)) { + printf(" pvolume"); + if (snd_mixer_selem_has_playback_volume_joined(elem)) + printf(" pvolume-joined"); + } + if (snd_mixer_selem_has_common_switch(elem)) { + printf(" switch"); + if (snd_mixer_selem_has_playback_switch_joined(elem)) + printf(" switch-joined"); + } else if (snd_mixer_selem_has_playback_switch(elem)) { + printf(" pswitch"); + if (snd_mixer_selem_has_playback_switch_joined(elem)) + printf(" pswitch-joined"); } - if (snd_mixer_selem_info_has_joined_capture(sinfo)) - printf(" joined-capture"); - if (snd_mixer_selem_info_has_exclusive_capture(sinfo)) - printf(" exclusive-capture"); + if (snd_mixer_selem_has_capture_volume(elem)) + printf(" cvolume"); + if (snd_mixer_selem_has_capture_volume_joined(elem)) + printf(" cvolume-joined"); + if (snd_mixer_selem_has_capture_switch(elem)) + printf(" cswitch"); + if (snd_mixer_selem_has_capture_switch_joined(elem)) + printf(" cswitch-joined"); + if (snd_mixer_selem_has_capture_switch_exclusive(elem)) + printf(" cswitch_exclusive"); printf("\n"); - if (snd_mixer_selem_info_has_capture(sinfo) && - snd_mixer_selem_info_has_exclusive_capture(sinfo)) + if (snd_mixer_selem_has_capture_switch_exclusive(elem)) printf("%sCapture exclusive group: %i\n", space, - snd_mixer_selem_info_get_capture_group(sinfo)); - printf("%sChannels: ", space); - if (snd_mixer_selem_info_is_mono(sinfo)) { - printf("Mono"); - } else { - for (chn = 0; chn <= SND_MIXER_SCHN_LAST; snd_enum_incr(chn)){ - if (!snd_mixer_selem_info_has_channel(sinfo, chn)) - continue; - printf("%s ", snd_mixer_selem_channel_name(chn)); + snd_mixer_selem_get_capture_group(elem)); + if (snd_mixer_selem_has_playback_volume(elem) || + snd_mixer_selem_has_playback_switch(elem)) { + printf("%sPlayback channels: ", space); + if (snd_mixer_selem_is_playback_mono(elem)) { + printf("Mono"); + } else { + for (chn = 0; chn <= SND_MIXER_SCHN_LAST; snd_enum_incr(chn)){ + if (!snd_mixer_selem_has_playback_channel(elem, chn)) + continue; + printf("%s ", snd_mixer_selem_channel_name(chn)); + } } + printf("\n"); } - printf("\n"); - min = snd_mixer_selem_info_get_min(sinfo); - max = snd_mixer_selem_info_get_max(sinfo); - printf("%sLimits: min = %li, max = %li\n", space, min, max); - if (snd_mixer_selem_info_is_mono(sinfo)) { - printf("%sMono: %s [%s]\n", space, - get_percent(snd_mixer_selem_value_get_volume(scontrol, SND_MIXER_SCHN_MONO), min, max), - snd_mixer_selem_value_get_mute(scontrol, SND_MIXER_SCHN_MONO) ? "mute" : "on"); - } else { - for (chn = 0; chn <= SND_MIXER_SCHN_LAST; snd_enum_incr(chn)) { - if (!snd_mixer_selem_info_has_channel(sinfo, chn)) - continue; - printf("%s%s: %s [%s] [%s]\n", - space, - snd_mixer_selem_channel_name(chn), - get_percent(snd_mixer_selem_value_get_volume(scontrol, chn), min, max), - snd_mixer_selem_value_get_mute(scontrol, chn) ? "mute" : "on", - snd_mixer_selem_value_get_capture(scontrol, chn) ? "capture" : "---"); + if (snd_mixer_selem_has_capture_volume(elem) || + snd_mixer_selem_has_capture_switch(elem)) { + printf("%sCapture channels: ", space); + if (snd_mixer_selem_is_capture_mono(elem)) { + printf("Mono"); + } else { + for (chn = 0; chn <= SND_MIXER_SCHN_LAST; snd_enum_incr(chn)){ + if (!snd_mixer_selem_has_capture_channel(elem, chn)) + continue; + printf("%s ", snd_mixer_selem_channel_name(chn)); + } + } + printf("\n"); + } + if (snd_mixer_selem_has_playback_volume(elem) || + snd_mixer_selem_has_capture_volume(elem)) { + cmin = snd_mixer_selem_get_capture_min(elem); + cmax = snd_mixer_selem_get_capture_max(elem); + printf("%sLimits: ", space); + if (snd_mixer_selem_has_playback_volume(elem)) { + pmin = snd_mixer_selem_get_playback_min(elem); + pmax = snd_mixer_selem_get_playback_max(elem); + if (!snd_mixer_selem_has_common_volume(elem)) + printf("Playback "); + printf("%li - %li ", pmin, pmax); + } + if (snd_mixer_selem_has_capture_volume(elem)) { + cmin = snd_mixer_selem_get_capture_min(elem); + cmax = snd_mixer_selem_get_capture_max(elem); + printf("Capture %li - %li", cmin, cmax); + } + printf("\n"); + } + mono = ((snd_mixer_selem_is_playback_mono(elem) || + (!snd_mixer_selem_has_playback_volume(elem) && + !snd_mixer_selem_has_playback_switch(elem))) && + (snd_mixer_selem_is_capture_mono(elem) || + (!snd_mixer_selem_has_capture_volume(elem) && + !snd_mixer_selem_has_capture_switch(elem)))); + for (chn = 0; chn <= SND_MIXER_SCHN_LAST; snd_enum_incr(chn)) { + if (!snd_mixer_selem_has_playback_channel(elem, chn) && + !snd_mixer_selem_has_capture_channel(elem, chn)) + continue; + printf("%s%s: ", space, mono ? "Mono" : snd_mixer_selem_channel_name(chn)); + if (snd_mixer_selem_has_playback_channel(elem, chn)) { + if (!snd_mixer_selem_has_common_volume(elem)) + printf("Playback "); + if (snd_mixer_selem_has_playback_volume(elem)) { + snd_mixer_selem_get_playback_volume(elem, chn, &pvol); + printf("%s ", get_percent(pvol, pmin, pmax)); + } + if (snd_mixer_selem_has_playback_switch(elem)) { + snd_mixer_selem_get_playback_switch(elem, chn, &psw); + printf("[%s] ", psw ? "on" : "off"); + } + } + if (snd_mixer_selem_has_capture_channel(elem, chn)) { + printf("Capture "); + if (snd_mixer_selem_has_capture_volume(elem)) { + snd_mixer_selem_get_capture_volume(elem, chn, &cvol); + printf("%s ", get_percent(cvol, cmin, cmax)); + } + if (snd_mixer_selem_has_capture_switch(elem)) { + snd_mixer_selem_get_capture_switch(elem, chn, &csw); + printf("[%s] ", csw ? "on" : "off"); + } } + printf("\n"); } } return 0; @@ -519,7 +575,7 @@ static int selems(int level) snd_mixer_close(handle); return err; } - if ((err = snd_mixer_selem_register(handle, 0)) < 0) { + if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0) { error("Mixer register error: %s", snd_strerror(err)); snd_mixer_close(handle); return err; @@ -825,11 +881,7 @@ static int sset(unsigned int argc, char *argv[], int roflag) snd_mixer_t *handle; snd_mixer_elem_t *elem; snd_mixer_selem_id_t *sid; - snd_mixer_selem_value_t *control; - snd_mixer_selem_info_t *info; snd_mixer_selem_id_alloca(&sid); - snd_mixer_selem_value_alloca(&control); - snd_mixer_selem_info_alloca(&info); if (argc < 1) { fprintf(stderr, "Specify a scontrol identifier: 'name',index\n"); @@ -852,7 +904,7 @@ static int sset(unsigned int argc, char *argv[], int roflag) snd_mixer_close(handle); return err; } - if ((err = snd_mixer_selem_register(handle, 0)) < 0) { + if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0) { error("Mixer register error: %s", snd_strerror(err)); snd_mixer_close(handle); return err; @@ -869,36 +921,26 @@ static int sset(unsigned int argc, char *argv[], int roflag) snd_mixer_close(handle); return -ENOENT; } - if ((err = snd_mixer_selem_info(elem, info))<0) { - error("Unable to get simple info '%s',%i: %s\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid), snd_strerror(err)); - snd_mixer_close(handle); - return err; - } - if ((err = snd_mixer_selem_read(elem, control))<0) { - error("Unable to read simple control '%s',%i: %s\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid), snd_strerror(err)); - snd_mixer_close(handle); - return err; - } - min = snd_mixer_selem_info_get_min(info); - max = snd_mixer_selem_info_get_max(info); + min = snd_mixer_selem_get_playback_min(elem); + max = snd_mixer_selem_get_playback_max(elem); if (roflag) goto __skip_write; for (idx = 1; idx < argc; idx++) { if (!strncmp(argv[idx], "mute", 4) || !strncmp(argv[idx], "off", 3)) { - snd_mixer_selem_value_set_mute_all(control, 1); + snd_mixer_selem_set_playback_switch_all(elem, 1); continue; } else if (!strncmp(argv[idx], "unmute", 6) || !strncmp(argv[idx], "on", 2)) { - snd_mixer_selem_value_set_mute_all(control, 0); + snd_mixer_selem_set_playback_switch_all(elem, 0); continue; } else if (!strncmp(argv[idx], "cap", 3) || !strncmp(argv[idx], "rec", 3)) { - snd_mixer_selem_value_set_capture_all(control, 1); + snd_mixer_selem_set_capture_switch_all(elem, 1); continue; } else if (!strncmp(argv[idx], "nocap", 5) || !strncmp(argv[idx], "norec", 5)) { - snd_mixer_selem_value_set_capture_all(control, 0); + snd_mixer_selem_set_capture_switch_all(elem, 0); continue; } channels = channels_mask(argv[idx]); @@ -911,13 +953,15 @@ static int sset(unsigned int argc, char *argv[], int roflag) multi = (strchr(argv[idx], ',') != NULL); ptr = argv[idx]; for (chn = 0; chn <= SND_MIXER_SCHN_LAST; snd_enum_incr(chn)) { + long vol; if (!(channels & (1 << chn)) || - !snd_mixer_selem_info_has_channel(info, chn)) + !snd_mixer_selem_has_playback_channel(elem, chn)) continue; if (! multi) ptr = argv[idx]; - snd_mixer_selem_value_set_volume(control, chn, get_volume_simple(&ptr, min, max, snd_mixer_selem_value_get_volume(control, chn))); + snd_mixer_selem_get_playback_volume(elem, chn, &vol); + snd_mixer_selem_set_playback_volume(elem, chn, get_volume_simple(&ptr, min, max, vol)); } } else { error("Unknown setup '%s'..\n", argv[idx]); @@ -925,11 +969,6 @@ static int sset(unsigned int argc, char *argv[], int roflag) return err; } } - if ((err = snd_mixer_selem_write(elem, control))<0) { - error("Unable to write control '%s',%i: %s\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid), snd_strerror(err)); - snd_mixer_close(handle); - return err; - } __skip_write: if (!quiet) { printf("Simple mixer control '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid)); @@ -1093,7 +1132,7 @@ static int sevents(int argc ATTRIBUTE_UNUSED, char *argv[] ATTRIBUTE_UNUSED) snd_mixer_close(handle); return err; } - if ((err = snd_mixer_selem_register(handle, 0)) < 0) { + if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0) { error("Mixer register error: %s", snd_strerror(err)); snd_mixer_close(handle); return err; -- 2.47.1