New simple mixer implementation

This commit is contained in:
Abramo Bagnara 2001-02-15 23:05:42 +00:00
parent 20c7e5b667
commit 1a2e4a6199
2 changed files with 244 additions and 202 deletions

View file

@ -465,14 +465,14 @@ mixer_conv(int val, int omin, int omax, int nmin, int nmax)
} }
static int static int
mixer_calc_volume(snd_mixer_selem_info_t *info, mixer_calc_volume(snd_mixer_elem_t *elem,
snd_mixer_selem_value_t *value,
int vol, int vol,
snd_mixer_selem_channel_id_t chn) snd_mixer_selem_channel_id_t chn)
{ {
int vol1; int vol1;
long min = snd_mixer_selem_info_get_min(info); long v;
long max = snd_mixer_selem_info_get_max(info); long min = snd_mixer_selem_get_playback_min(elem);
long max = snd_mixer_selem_get_playback_max(elem);
vol1 = (vol < 0) ? -vol : vol; vol1 = (vol < 0) ? -vol : vol;
if (vol1 > 0) { if (vol1 > 0) {
if (vol1 > 100) if (vol1 > 100)
@ -484,7 +484,8 @@ mixer_calc_volume(snd_mixer_selem_info_t *info,
if (vol < 0) if (vol < 0)
vol1 = -vol1; 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); return CLAMP(vol1, min, max);
} }
@ -494,15 +495,11 @@ static void
mixer_write_cbar (int elem_index) mixer_write_cbar (int elem_index)
{ {
snd_mixer_elem_t *elem; snd_mixer_elem_t *elem;
snd_mixer_selem_info_t *info;
snd_mixer_selem_value_t *value;
int vleft, vright, vbalance; int vleft, vright, vbalance;
int type; int type;
snd_mixer_selem_id_t *sid; snd_mixer_selem_id_t *sid;
snd_mixer_selem_channel_id_t chn_left, chn_right, chn; snd_mixer_selem_channel_id_t chn_left, chn_right, chn;
int err, changed; int sw;
snd_mixer_selem_info_alloca(&info);
snd_mixer_selem_value_alloca(&value);
if (mixer_sid == NULL) if (mixer_sid == NULL)
return; return;
@ -511,52 +508,59 @@ mixer_write_cbar (int elem_index)
elem = snd_mixer_find_selem(mixer_handle, sid); elem = snd_mixer_find_selem(mixer_handle, sid);
if (elem == NULL) if (elem == NULL)
CHECK_ABORT (ERR_FCN, "snd_mixer_find_selem()", -EINVAL); 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]; type = mixer_type[elem_index];
chn_left = mixer_elem_chn[type][MIXER_CHN_LEFT]; 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; /* ..??.. */ return; /* ..??.. */
chn_right = mixer_elem_chn[type][MIXER_CHN_RIGHT]; 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; chn_right = SND_MIXER_SCHN_UNKNOWN;
changed = 0;
/* volume /* volume
*/ */
if ((mixer_volume_delta[MIXER_CHN_LEFT] || if ((mixer_volume_delta[MIXER_CHN_LEFT] ||
mixer_volume_delta[MIXER_CHN_RIGHT] || mixer_volume_delta[MIXER_CHN_RIGHT] ||
mixer_balance_volumes) && mixer_balance_volumes) &&
snd_mixer_selem_info_has_volume(info)) { snd_mixer_selem_has_playback_volume(elem)) {
int mono = int mono =
(chn_right == SND_MIXER_SCHN_UNKNOWN || (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]) if (mono && !mixer_volume_delta[MIXER_CHN_LEFT])
mixer_volume_delta[MIXER_CHN_LEFT] = mixer_volume_delta[MIXER_CHN_RIGHT]; 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; vbalance = vleft;
if (! mono) { 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 += vright;
vbalance /= 2; vbalance /= 2;
} else } else
vright = vleft; vright = vleft;
if (vleft >= 0 && vright >= 0) { 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)) for (chn = 0; chn < SND_MIXER_SCHN_LAST; snd_enum_incr(chn))
if (snd_mixer_selem_info_has_channel(info, chn)) if (snd_mixer_selem_has_playback_channel(elem, chn))
snd_mixer_selem_value_set_volume(value, chn, vleft); 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 { } else {
if (mixer_balance_volumes) if (mixer_balance_volumes)
vleft = vright = vbalance; vleft = vright = vbalance;
snd_mixer_selem_value_set_volume(value, chn_left, vleft); if (snd_mixer_selem_has_playback_volume(elem) &&
if (! mono) snd_mixer_selem_has_playback_channel(elem, chn_left))
snd_mixer_selem_value_set_volume(value, chn_right, vright); 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; mixer_volume_delta[MIXER_CHN_LEFT] = mixer_volume_delta[MIXER_CHN_RIGHT] = 0;
@ -564,39 +568,43 @@ mixer_write_cbar (int elem_index)
/* mute /* mute
*/ */
if (mixer_toggle_mute && snd_mixer_selem_info_has_mute(info)) { if (mixer_toggle_mute && snd_mixer_selem_has_playback_switch(elem)) {
if (snd_mixer_selem_info_has_joined_mute(info)) if (snd_mixer_selem_has_playback_switch_joined(elem)) {
snd_mixer_selem_value_set_mute_all(value, snd_mixer_selem_value_get_mute(value, chn_left) ? 0 : 1); snd_mixer_selem_get_playback_switch(elem, chn_left, &sw);
else { snd_mixer_selem_set_playback_switch_all(elem, !sw);
if (mixer_toggle_mute & MIXER_MASK_LEFT) } else {
snd_mixer_selem_value_set_mute(value, chn_left, snd_mixer_selem_value_get_mute(value, chn_left) ? 0 : 1); if (mixer_toggle_mute & MIXER_MASK_LEFT) {
if (chn_right != SND_MIXER_SCHN_UNKNOWN && snd_mixer_selem_get_playback_switch(elem, chn_left, &sw);
(mixer_toggle_mute & MIXER_MASK_RIGHT)) snd_mixer_selem_set_playback_switch(elem, chn_left, !sw);
snd_mixer_selem_value_set_mute(value, chn_right, snd_mixer_selem_value_get_mute(value, chn_right) ? 0 : 1); }
if (chn_right != SND_MIXER_SCHN_UNKNOWN &&
(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; mixer_toggle_mute = 0;
/* capture /* capture
*/ */
if (mixer_toggle_capture && snd_mixer_selem_info_has_capture(info)) { if (mixer_toggle_capture && snd_mixer_selem_has_capture_switch(elem)) {
if (snd_mixer_selem_info_has_joined_capture(info)) if (snd_mixer_selem_has_capture_switch_joined(elem)) {
snd_mixer_selem_value_set_capture_all(value, snd_mixer_selem_value_get_capture(value, chn_left) ? 0 : 1); snd_mixer_selem_get_capture_switch(elem, chn_left, &sw);
else { snd_mixer_selem_set_capture_switch_all(elem, !sw);
if (mixer_toggle_capture & MIXER_MASK_LEFT) } else {
snd_mixer_selem_value_set_capture(value, chn_left, snd_mixer_selem_value_get_capture(value, chn_left) ? 0 : 1); if (mixer_toggle_capture & MIXER_MASK_LEFT) {
if (chn_right != SND_MIXER_SCHN_UNKNOWN && (mixer_toggle_capture & MIXER_MASK_RIGHT)) snd_mixer_selem_get_capture_switch(elem, chn_left, &sw);
snd_mixer_selem_value_set_capture(value, chn_right, snd_mixer_selem_value_get_capture(value, chn_right) ? 0 : 1); 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; 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) mixer_update_cbar (int elem_index)
{ {
char string[128], string1[64]; char string[128], string1[64];
int err, dc; int dc;
snd_mixer_elem_t *elem; snd_mixer_elem_t *elem;
snd_mixer_selem_info_t *info; long vleft, vright;
snd_mixer_selem_value_t *value;
int vleft, vright;
int type; int type;
snd_mixer_selem_id_t *sid; snd_mixer_selem_id_t *sid;
snd_mixer_selem_channel_id_t chn_left, chn_right; snd_mixer_selem_channel_id_t chn_left, chn_right;
int x, y, i; int x, y, i;
snd_mixer_selem_info_alloca(&info); int swl, swr;
snd_mixer_selem_value_alloca(&value);
/* set new scontrol indices and read info /* 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); elem = snd_mixer_find_selem(mixer_handle, sid);
if (elem == NULL) if (elem == NULL)
CHECK_ABORT (ERR_FCN, "snd_mixer_find_selem()", -EINVAL); 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]; type = mixer_type[elem_index];
chn_left = mixer_elem_chn[type][MIXER_CHN_LEFT]; 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; /* ..??.. */ return; /* ..??.. */
chn_right = mixer_elem_chn[type][MIXER_CHN_RIGHT]; 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; chn_right = SND_MIXER_SCHN_UNKNOWN;
vleft = snd_mixer_selem_value_get_volume(value, chn_left); if (snd_mixer_selem_has_playback_volume(elem)) {
snd_mixer_selem_get_playback_volume(elem, chn_left, &vleft);
vleft = mixer_conv(vleft, vleft = mixer_conv(vleft,
snd_mixer_selem_info_get_min(info), snd_mixer_selem_get_playback_min(elem),
snd_mixer_selem_info_get_max(info), snd_mixer_selem_get_playback_max(elem),
0, 100); 0, 100);
if (chn_right != SND_MIXER_SCHN_UNKNOWN) { if (chn_right != SND_MIXER_SCHN_UNKNOWN) {
vright = snd_mixer_selem_value_get_volume(value, chn_right); snd_mixer_selem_get_playback_volume(elem, chn_right, &vright);
vright = mixer_conv(vright, vright = mixer_conv(vright,
snd_mixer_selem_info_get_min(info), snd_mixer_selem_get_playback_min(elem),
snd_mixer_selem_info_get_max(info), snd_mixer_selem_get_playback_max(elem),
0, 100); 0, 100);
} else { } else {
vright = vleft; vright = vleft;
} }
} else
vleft = vright = 0;
/* update the focused full bar name /* update the focused full bar name
*/ */
@ -698,13 +703,13 @@ mixer_update_cbar (int elem_index)
mixer_dc (DC_BACK); mixer_dc (DC_BACK);
mvaddstr (y, x, " "); mvaddstr (y, x, " ");
mixer_dc (DC_TEXT); mixer_dc (DC_TEXT);
sprintf (string, "%d", vleft); sprintf (string, "%ld", vleft);
mvaddstr (y, x + 3 - strlen (string), string); mvaddstr (y, x + 3 - strlen (string), string);
mixer_dc (DC_CBAR_FRAME); mixer_dc (DC_CBAR_FRAME);
mvaddch (y, x + 3, '<'); mvaddch (y, x + 3, '<');
mvaddch (y, x + 4, '>'); mvaddch (y, x + 4, '>');
mixer_dc (DC_TEXT); mixer_dc (DC_TEXT);
sprintf (string, "%d", vright); sprintf (string, "%ld", vright);
mvaddstr (y, x + 5, string); mvaddstr (y, x + 5, string);
y--; y--;
@ -741,38 +746,43 @@ mixer_update_cbar (int elem_index)
*/ */
mixer_dc (DC_BACK); mixer_dc (DC_BACK);
mvaddstr (y, x, " "); mvaddstr (y, x, " ");
if (snd_mixer_selem_has_playback_switch(elem)) {
mixer_dc (DC_CBAR_FRAME); mixer_dc (DC_CBAR_FRAME);
mvaddch (y, x + 2, ACS_ULCORNER); mvaddch (y, x + 2, ACS_ULCORNER);
dc = snd_mixer_selem_value_get_mute(value, chn_left) ? DC_CBAR_MUTE : DC_CBAR_NOMUTE; 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)); mvaddch (y, x + 3, mixer_dc (dc));
if (chn_right != SND_MIXER_SCHN_UNKNOWN) if (chn_right != SND_MIXER_SCHN_UNKNOWN) {
dc = snd_mixer_selem_value_get_mute(value, chn_right) ? DC_CBAR_MUTE : DC_CBAR_NOMUTE; 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)); mvaddch (y, x + 4, mixer_dc (dc));
mixer_dc (DC_CBAR_FRAME); mixer_dc (DC_CBAR_FRAME);
mvaddch (y, x + 5, ACS_URCORNER); mvaddch (y, x + 5, ACS_URCORNER);
}
y--; y--;
/* capture input? /* capture input?
*/ */
if ((snd_mixer_selem_value_get_capture(value, chn_left)) || if (snd_mixer_selem_has_capture_switch(elem)) {
(chn_right != SND_MIXER_SCHN_UNKNOWN && snd_mixer_selem_value_get_capture(value, chn_right))) 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); mixer_dc (DC_CBAR_CAPTURE);
mvaddstr (y, x + 1, "CAPTUR"); mvaddstr (y, x + 1, "CAPTUR");
if (snd_mixer_selem_value_get_capture(value, chn_left)) { if (swl) {
mvaddstr (y + 1, x + 1, "L"); mvaddstr (y + 1, x + 1, "L");
if (chn_right == SND_MIXER_SCHN_UNKNOWN) if (chn_right == SND_MIXER_SCHN_UNKNOWN)
mvaddstr (y + 1, x + 6, "R"); mvaddstr (y + 1, x + 6, "R");
} }
if (chn_right != SND_MIXER_SCHN_UNKNOWN && if (chn_right != SND_MIXER_SCHN_UNKNOWN && swr)
snd_mixer_selem_value_get_capture(value, chn_right))
mvaddstr (y + 1, x + 6, "R"); mvaddstr (y + 1, x + 6, "R");
} } else {
else if (snd_mixer_selem_info_has_capture(info))
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
mvaddch (y, x + 1 + i, mixer_dc (DC_CBAR_NOCAPTURE)); mvaddch (y, x + 1 + i, mixer_dc (DC_CBAR_NOCAPTURE));
else }
{ } else {
mixer_dc (DC_BACK); mixer_dc (DC_BACK);
mvaddstr (y, x, " "); mvaddstr (y, x, " ");
} }
@ -1243,7 +1253,7 @@ mixer_init (void)
mixer_abort (ERR_FCN, "snd_mixer_open", err); mixer_abort (ERR_FCN, "snd_mixer_open", err);
if ((err = snd_mixer_attach (mixer_handle, card_id)) < 0) if ((err = snd_mixer_attach (mixer_handle, card_id)) < 0)
mixer_abort (ERR_FCN, "snd_mixer_attach", err); 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); mixer_abort (ERR_FCN, "snd_mixer_selem_register", err);
if ((err = snd_mixer_load (mixer_handle)) < 0) if ((err = snd_mixer_load (mixer_handle)) < 0)
mixer_abort (ERR_FCN, "snd_mixer_load", err); mixer_abort (ERR_FCN, "snd_mixer_load", err);
@ -1258,7 +1268,7 @@ static void
mixer_reinit (void) mixer_reinit (void)
{ {
snd_mixer_elem_t *elem; 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 *sid;
snd_mixer_selem_id_t *focus_gid; snd_mixer_selem_id_t *focus_gid;
int focus_type = -1; int focus_type = -1;
@ -1283,18 +1293,14 @@ mixer_reinit (void)
mixer_n_elems = 0; mixer_n_elems = 0;
for (idx = 0; idx < mixer_n_selems; idx++) { 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); sid = (snd_mixer_selem_id_t *)(((char *)mixer_sid) + snd_mixer_selem_id_sizeof() * idx);
elem = snd_mixer_find_selem(mixer_handle, sid); elem = snd_mixer_find_selem(mixer_handle, sid);
if (elem == NULL) if (elem == NULL)
CHECK_ABORT (ERR_FCN, "snd_mixer_find_selem()", -EINVAL); 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++) { for (i = 0; i < MIXER_ELEM_END; i++) {
int ok; int ok;
for (j = ok = 0; j < 2; j++) { 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++; ok++;
} }
if (ok) if (ok)
@ -1314,18 +1320,14 @@ mixer_reinit (void)
mixer_abort(ERR_FCN, "malloc", 0); mixer_abort(ERR_FCN, "malloc", 0);
elem_index = 0; elem_index = 0;
for (idx = 0; idx < mixer_n_selems; idx++) { 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); sid = (snd_mixer_selem_id_t *)(((char *)mixer_sid) + snd_mixer_selem_id_sizeof() * idx);
elem = snd_mixer_find_selem(mixer_handle, sid); elem = snd_mixer_find_selem(mixer_handle, sid);
if (elem == NULL) if (elem == NULL)
CHECK_ABORT (ERR_FCN, "snd_mixer_find_selem()", -EINVAL); 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++) { for (i = 0; i < MIXER_ELEM_END; i++) {
int ok; int ok;
for (j = ok = 0; j < 2; j++) { 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++; ok++;
} }
if (ok) { if (ok) {
@ -1550,6 +1552,7 @@ mixer_iteration (void)
mixer_view = VIEW_PROCINFO; mixer_view = VIEW_PROCINFO;
key = 0; key = 0;
break; break;
case '\014':
case 'L': case 'L':
case 'l': case 'l':
mixer_clear (TRUE); mixer_clear (TRUE);

View file

@ -109,7 +109,7 @@ static int info(void)
snd_mixer_close(mhandle); snd_mixer_close(mhandle);
return err; 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)); error("Mixer register error: %s", snd_strerror(err));
snd_mixer_close(mhandle); snd_mixer_close(mhandle);
return err; 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) 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; 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_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); elem = snd_mixer_find_selem(handle, id);
if (!elem) { if (!elem) {
@ -438,66 +437,123 @@ static int show_selem(snd_mixer_t *handle, snd_mixer_selem_id_t *id, const char
return -ENOENT; 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) { if ((level & 1) != 0) {
printf("%sCapabilities:", space); printf("%sCapabilities:", space);
if (snd_mixer_selem_info_has_volume(sinfo)) if (snd_mixer_selem_has_common_volume(elem)) {
printf(" volume"); printf(" volume");
if (snd_mixer_selem_info_has_joined_volume(sinfo)) if (snd_mixer_selem_has_playback_volume_joined(elem))
printf(" joined-volume"); printf(" volume-joined");
if (snd_mixer_selem_info_has_mute(sinfo)) } else if (snd_mixer_selem_has_playback_volume(elem)) {
printf(" mute"); printf(" pvolume");
if (snd_mixer_selem_info_has_joined_mute(sinfo)) if (snd_mixer_selem_has_playback_volume_joined(elem))
printf(" joined-mute"); printf(" pvolume-joined");
if (snd_mixer_selem_info_has_capture(sinfo)) {
printf(" capture");
} }
if (snd_mixer_selem_info_has_joined_capture(sinfo)) if (snd_mixer_selem_has_common_switch(elem)) {
printf(" joined-capture"); printf(" switch");
if (snd_mixer_selem_info_has_exclusive_capture(sinfo)) if (snd_mixer_selem_has_playback_switch_joined(elem))
printf(" exclusive-capture"); 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_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"); printf("\n");
if (snd_mixer_selem_info_has_capture(sinfo) && if (snd_mixer_selem_has_capture_switch_exclusive(elem))
snd_mixer_selem_info_has_exclusive_capture(sinfo))
printf("%sCapture exclusive group: %i\n", space, printf("%sCapture exclusive group: %i\n", space,
snd_mixer_selem_info_get_capture_group(sinfo)); snd_mixer_selem_get_capture_group(elem));
printf("%sChannels: ", space); if (snd_mixer_selem_has_playback_volume(elem) ||
if (snd_mixer_selem_info_is_mono(sinfo)) { snd_mixer_selem_has_playback_switch(elem)) {
printf("%sPlayback channels: ", space);
if (snd_mixer_selem_is_playback_mono(elem)) {
printf("Mono"); printf("Mono");
} else { } else {
for (chn = 0; chn <= SND_MIXER_SCHN_LAST; snd_enum_incr(chn)){ for (chn = 0; chn <= SND_MIXER_SCHN_LAST; snd_enum_incr(chn)){
if (!snd_mixer_selem_info_has_channel(sinfo, chn)) if (!snd_mixer_selem_has_playback_channel(elem, chn))
continue; continue;
printf("%s ", snd_mixer_selem_channel_name(chn)); 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); if (snd_mixer_selem_has_capture_volume(elem) ||
printf("%sLimits: min = %li, max = %li\n", space, min, max); snd_mixer_selem_has_capture_switch(elem)) {
if (snd_mixer_selem_info_is_mono(sinfo)) { printf("%sCapture channels: ", space);
printf("%sMono: %s [%s]\n", space, if (snd_mixer_selem_is_capture_mono(elem)) {
get_percent(snd_mixer_selem_value_get_volume(scontrol, SND_MIXER_SCHN_MONO), min, max), printf("Mono");
snd_mixer_selem_value_get_mute(scontrol, SND_MIXER_SCHN_MONO) ? "mute" : "on");
} else { } else {
for (chn = 0; chn <= SND_MIXER_SCHN_LAST; snd_enum_incr(chn)){ for (chn = 0; chn <= SND_MIXER_SCHN_LAST; snd_enum_incr(chn)){
if (!snd_mixer_selem_info_has_channel(sinfo, chn)) if (!snd_mixer_selem_has_capture_channel(elem, chn))
continue; continue;
printf("%s%s: %s [%s] [%s]\n", printf("%s ", snd_mixer_selem_channel_name(chn));
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" : "---");
} }
} }
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; return 0;
} }
@ -519,7 +575,7 @@ static int selems(int level)
snd_mixer_close(handle); snd_mixer_close(handle);
return err; 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)); error("Mixer register error: %s", snd_strerror(err));
snd_mixer_close(handle); snd_mixer_close(handle);
return err; return err;
@ -825,11 +881,7 @@ static int sset(unsigned int argc, char *argv[], int roflag)
snd_mixer_t *handle; snd_mixer_t *handle;
snd_mixer_elem_t *elem; snd_mixer_elem_t *elem;
snd_mixer_selem_id_t *sid; 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_id_alloca(&sid);
snd_mixer_selem_value_alloca(&control);
snd_mixer_selem_info_alloca(&info);
if (argc < 1) { if (argc < 1) {
fprintf(stderr, "Specify a scontrol identifier: 'name',index\n"); 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); snd_mixer_close(handle);
return err; 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)); error("Mixer register error: %s", snd_strerror(err));
snd_mixer_close(handle); snd_mixer_close(handle);
return err; return err;
@ -869,36 +921,26 @@ static int sset(unsigned int argc, char *argv[], int roflag)
snd_mixer_close(handle); snd_mixer_close(handle);
return -ENOENT; return -ENOENT;
} }
if ((err = snd_mixer_selem_info(elem, info))<0) { min = snd_mixer_selem_get_playback_min(elem);
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)); max = snd_mixer_selem_get_playback_max(elem);
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);
if (roflag) if (roflag)
goto __skip_write; goto __skip_write;
for (idx = 1; idx < argc; idx++) { for (idx = 1; idx < argc; idx++) {
if (!strncmp(argv[idx], "mute", 4) || if (!strncmp(argv[idx], "mute", 4) ||
!strncmp(argv[idx], "off", 3)) { !strncmp(argv[idx], "off", 3)) {
snd_mixer_selem_value_set_mute_all(control, 1); snd_mixer_selem_set_playback_switch_all(elem, 1);
continue; continue;
} else if (!strncmp(argv[idx], "unmute", 6) || } else if (!strncmp(argv[idx], "unmute", 6) ||
!strncmp(argv[idx], "on", 2)) { !strncmp(argv[idx], "on", 2)) {
snd_mixer_selem_value_set_mute_all(control, 0); snd_mixer_selem_set_playback_switch_all(elem, 0);
continue; continue;
} else if (!strncmp(argv[idx], "cap", 3) || } else if (!strncmp(argv[idx], "cap", 3) ||
!strncmp(argv[idx], "rec", 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; continue;
} else if (!strncmp(argv[idx], "nocap", 5) || } else if (!strncmp(argv[idx], "nocap", 5) ||
!strncmp(argv[idx], "norec", 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; continue;
} }
channels = channels_mask(argv[idx]); channels = channels_mask(argv[idx]);
@ -911,13 +953,15 @@ static int sset(unsigned int argc, char *argv[], int roflag)
multi = (strchr(argv[idx], ',') != NULL); multi = (strchr(argv[idx], ',') != NULL);
ptr = argv[idx]; ptr = argv[idx];
for (chn = 0; chn <= SND_MIXER_SCHN_LAST; snd_enum_incr(chn)) { for (chn = 0; chn <= SND_MIXER_SCHN_LAST; snd_enum_incr(chn)) {
long vol;
if (!(channels & (1 << chn)) || if (!(channels & (1 << chn)) ||
!snd_mixer_selem_info_has_channel(info, chn)) !snd_mixer_selem_has_playback_channel(elem, chn))
continue; continue;
if (! multi) if (! multi)
ptr = argv[idx]; 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 { } else {
error("Unknown setup '%s'..\n", argv[idx]); error("Unknown setup '%s'..\n", argv[idx]);
@ -925,11 +969,6 @@ static int sset(unsigned int argc, char *argv[], int roflag)
return err; 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: __skip_write:
if (!quiet) { if (!quiet) {
printf("Simple mixer control '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid)); 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); snd_mixer_close(handle);
return err; 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)); error("Mixer register error: %s", snd_strerror(err));
snd_mixer_close(handle); snd_mixer_close(handle);
return err; return err;