Completed mixer API. Improved iterators. Renamed control values struct. Rewritten simple elements implementation

This commit is contained in:
Abramo Bagnara 2001-02-11 15:45:44 +00:00
parent 7346943471
commit fbec0a5f8d
4 changed files with 248 additions and 173 deletions

View file

@ -142,7 +142,7 @@ static int snd_config_compound_add(snd_config_t *father, const char *id, int joi
static int get_control(snd_ctl_t *handle, snd_ctl_elem_id_t *id, snd_config_t *top) static int get_control(snd_ctl_t *handle, snd_ctl_elem_id_t *id, snd_config_t *top)
{ {
snd_ctl_elem_t *ctl; snd_ctl_elem_value_t *ctl;
snd_ctl_elem_info_t *info; snd_ctl_elem_info_t *info;
snd_config_t *control, *comment, *item, *value; snd_config_t *control, *comment, *item, *value;
const char *s; const char *s;
@ -153,7 +153,7 @@ static int get_control(snd_ctl_t *handle, snd_ctl_elem_id_t *id, snd_config_t *t
const char *name; const char *name;
snd_ctl_elem_type_t type; snd_ctl_elem_type_t type;
unsigned int count; unsigned int count;
snd_ctl_elem_alloca(&ctl); snd_ctl_elem_value_alloca(&ctl);
snd_ctl_elem_info_alloca(&info); snd_ctl_elem_info_alloca(&info);
snd_ctl_elem_info_set_id(info, id); snd_ctl_elem_info_set_id(info, id);
err = snd_ctl_elem_info(handle, info); err = snd_ctl_elem_info(handle, info);
@ -164,7 +164,7 @@ static int get_control(snd_ctl_t *handle, snd_ctl_elem_id_t *id, snd_config_t *t
if (!snd_ctl_elem_info_is_readable(info)) if (!snd_ctl_elem_info_is_readable(info))
return 0; return 0;
snd_ctl_elem_set_id(ctl, id); snd_ctl_elem_value_set_id(ctl, id);
err = snd_ctl_elem_read(handle, ctl); err = snd_ctl_elem_read(handle, ctl);
if (err < 0) { if (err < 0) {
error("Cannot read control '%s': %s", id_str(id), snd_strerror(err)); error("Cannot read control '%s': %s", id_str(id), snd_strerror(err));
@ -303,7 +303,7 @@ static int get_control(snd_ctl_t *handle, snd_ctl_elem_id_t *id, snd_config_t *t
char buf[size * 2 + 1]; char buf[size * 2 + 1];
char *p = buf; char *p = buf;
char *hex = "0123456789abcdef"; char *hex = "0123456789abcdef";
const unsigned char *bytes = snd_ctl_elem_get_bytes(ctl); const unsigned char *bytes = snd_ctl_elem_value_get_bytes(ctl);
for (idx = 0; idx < size; idx++) { for (idx = 0; idx < size; idx++) {
int v = bytes[idx]; int v = bytes[idx];
*p++ = hex[v >> 4]; *p++ = hex[v >> 4];
@ -324,14 +324,14 @@ static int get_control(snd_ctl_t *handle, snd_ctl_elem_id_t *id, snd_config_t *t
if (count == 1) { if (count == 1) {
switch (snd_enum_to_int(type)) { switch (snd_enum_to_int(type)) {
case SND_CTL_ELEM_TYPE_BOOLEAN: case SND_CTL_ELEM_TYPE_BOOLEAN:
err = snd_config_string_add(control, "value", snd_ctl_elem_get_boolean(ctl, 0) ? "true" : "false"); err = snd_config_string_add(control, "value", snd_ctl_elem_value_get_boolean(ctl, 0) ? "true" : "false");
if (err < 0) { if (err < 0) {
error("snd_config_string_add: %s", snd_strerror(err)); error("snd_config_string_add: %s", snd_strerror(err));
return err; return err;
} }
return 0; return 0;
case SND_CTL_ELEM_TYPE_INTEGER: case SND_CTL_ELEM_TYPE_INTEGER:
err = snd_config_integer_add(control, "value", snd_ctl_elem_get_integer(ctl, 0)); err = snd_config_integer_add(control, "value", snd_ctl_elem_value_get_integer(ctl, 0));
if (err < 0) { if (err < 0) {
error("snd_config_integer_add: %s", snd_strerror(err)); error("snd_config_integer_add: %s", snd_strerror(err));
return err; return err;
@ -339,7 +339,7 @@ static int get_control(snd_ctl_t *handle, snd_ctl_elem_id_t *id, snd_config_t *t
return 0; return 0;
case SND_CTL_ELEM_TYPE_ENUMERATED: case SND_CTL_ELEM_TYPE_ENUMERATED:
{ {
unsigned int v = snd_ctl_elem_get_enumerated(ctl, 0); unsigned int v = snd_ctl_elem_value_get_enumerated(ctl, 0);
snd_config_t *c; snd_config_t *c;
err = snd_config_search(item, num_str(v), &c); err = snd_config_search(item, num_str(v), &c);
if (err == 0) { if (err == 0) {
@ -368,7 +368,7 @@ static int get_control(snd_ctl_t *handle, snd_ctl_elem_id_t *id, snd_config_t *t
switch (snd_enum_to_int(type)) { switch (snd_enum_to_int(type)) {
case SND_CTL_ELEM_TYPE_BOOLEAN: case SND_CTL_ELEM_TYPE_BOOLEAN:
for (idx = 0; idx < count; idx++) { for (idx = 0; idx < count; idx++) {
err = snd_config_string_add(value, num_str(idx), snd_ctl_elem_get_boolean(ctl, idx) ? "true" : "false"); err = snd_config_string_add(value, num_str(idx), snd_ctl_elem_value_get_boolean(ctl, idx) ? "true" : "false");
if (err < 0) { if (err < 0) {
error("snd_config_string_add: %s", snd_strerror(err)); error("snd_config_string_add: %s", snd_strerror(err));
return err; return err;
@ -377,7 +377,7 @@ static int get_control(snd_ctl_t *handle, snd_ctl_elem_id_t *id, snd_config_t *t
break; break;
case SND_CTL_ELEM_TYPE_INTEGER: case SND_CTL_ELEM_TYPE_INTEGER:
for (idx = 0; idx < count; idx++) { for (idx = 0; idx < count; idx++) {
err = snd_config_integer_add(value, num_str(idx), snd_ctl_elem_get_integer(ctl, idx)); err = snd_config_integer_add(value, num_str(idx), snd_ctl_elem_value_get_integer(ctl, idx));
if (err < 0) { if (err < 0) {
error("snd_config_integer_add: %s", snd_strerror(err)); error("snd_config_integer_add: %s", snd_strerror(err));
return err; return err;
@ -386,7 +386,7 @@ static int get_control(snd_ctl_t *handle, snd_ctl_elem_id_t *id, snd_config_t *t
break; break;
case SND_CTL_ELEM_TYPE_ENUMERATED: case SND_CTL_ELEM_TYPE_ENUMERATED:
for (idx = 0; idx < count; idx++) { for (idx = 0; idx < count; idx++) {
unsigned int v = snd_ctl_elem_get_enumerated(ctl, idx); unsigned int v = snd_ctl_elem_value_get_enumerated(ctl, idx);
snd_config_t *c; snd_config_t *c;
err = snd_config_search(item, num_str(v), &c); err = snd_config_search(item, num_str(v), &c);
if (err == 0) { if (err == 0) {
@ -592,9 +592,9 @@ static int config_enumerated(snd_config_t *n, snd_ctl_t *handle,
static int set_control(snd_ctl_t *handle, snd_config_t *control) static int set_control(snd_ctl_t *handle, snd_config_t *control)
{ {
snd_ctl_elem_t *ctl; snd_ctl_elem_value_t *ctl;
snd_ctl_elem_info_t *info; snd_ctl_elem_info_t *info;
snd_config_iterator_t i; snd_config_iterator_t i, next;
unsigned int numid1, iface1, device1, subdevice1, index1; unsigned int numid1, iface1, device1, subdevice1, index1;
const char *name1; const char *name1;
unsigned int numid; unsigned int numid;
@ -610,16 +610,16 @@ static int set_control(snd_ctl_t *handle, snd_config_t *control)
unsigned int idx; unsigned int idx;
int err; int err;
char *set; char *set;
snd_ctl_elem_alloca(&ctl); snd_ctl_elem_value_alloca(&ctl);
snd_ctl_elem_info_alloca(&info); snd_ctl_elem_info_alloca(&info);
if (snd_config_get_type(control) != SND_CONFIG_TYPE_COMPOUND) { if (snd_config_get_type(control) != SND_CONFIG_TYPE_COMPOUND) {
error("control is not a compound"); error("control is not a compound");
return -EINVAL; return -EINVAL;
} }
numid = atoi(snd_config_get_id(control)); numid = atoi(snd_config_get_id(control));
snd_config_foreach(i, control) { snd_config_for_each(i, next, control) {
snd_config_t *n = snd_config_iterator_entry(i); snd_config_t *n = snd_config_iterator_entry(i);
char *fld = snd_config_get_id(n); const char *fld = snd_config_get_id(n);
if (strcmp(fld, "comment") == 0) if (strcmp(fld, "comment") == 0)
continue; continue;
if (strcmp(fld, "iface") == 0) { if (strcmp(fld, "iface") == 0) {
@ -720,28 +720,28 @@ static int set_control(snd_ctl_t *handle, snd_config_t *control)
if (!snd_ctl_elem_info_is_writable(info)) if (!snd_ctl_elem_info_is_writable(info))
return 0; return 0;
snd_ctl_elem_set_numid(ctl, numid); snd_ctl_elem_value_set_numid(ctl, numid);
if (count == 1) { if (count == 1) {
switch (snd_enum_to_int(type)) { switch (snd_enum_to_int(type)) {
case SND_CTL_ELEM_TYPE_BOOLEAN: case SND_CTL_ELEM_TYPE_BOOLEAN:
val = config_bool(value); val = config_bool(value);
if (val >= 0) { if (val >= 0) {
snd_ctl_elem_set_boolean(ctl, 0, val); snd_ctl_elem_value_set_boolean(ctl, 0, val);
goto _ok; goto _ok;
} }
break; break;
case SND_CTL_ELEM_TYPE_INTEGER: case SND_CTL_ELEM_TYPE_INTEGER:
err = snd_config_get_integer(value, &val); err = snd_config_get_integer(value, &val);
if (err == 0) { if (err == 0) {
snd_ctl_elem_set_integer(ctl, 0, val); snd_ctl_elem_value_set_integer(ctl, 0, val);
goto _ok; goto _ok;
} }
break; break;
case SND_CTL_ELEM_TYPE_ENUMERATED: case SND_CTL_ELEM_TYPE_ENUMERATED:
val = config_enumerated(value, handle, info); val = config_enumerated(value, handle, info);
if (val >= 0) { if (val >= 0) {
snd_ctl_elem_set_enumerated(ctl, 0, val); snd_ctl_elem_value_set_enumerated(ctl, 0, val);
goto _ok; goto _ok;
} }
break; break;
@ -783,7 +783,7 @@ static int set_control(snd_ctl_t *handle, snd_config_t *control)
} }
idx++; idx++;
if (idx % 2 == 0) if (idx % 2 == 0)
snd_ctl_elem_set_byte(ctl, idx / 2, c1 << 4 | c); snd_ctl_elem_value_set_byte(ctl, idx / 2, c1 << 4 | c);
else else
c1 = c; c1 = c;
} }
@ -800,7 +800,7 @@ static int set_control(snd_ctl_t *handle, snd_config_t *control)
set = alloca(count); set = alloca(count);
memset(set, 0, count); memset(set, 0, count);
snd_config_foreach(i, value) { snd_config_for_each(i, next, value) {
snd_config_t *n = snd_config_iterator_entry(i); snd_config_t *n = snd_config_iterator_entry(i);
idx = atoi(snd_config_get_id(n)); idx = atoi(snd_config_get_id(n));
if (idx < 0 || idx >= count || if (idx < 0 || idx >= count ||
@ -815,7 +815,7 @@ static int set_control(snd_ctl_t *handle, snd_config_t *control)
error("bad control.%d.value.%d content", numid, idx); error("bad control.%d.value.%d content", numid, idx);
return -EINVAL; return -EINVAL;
} }
snd_ctl_elem_set_boolean(ctl, idx, val); snd_ctl_elem_value_set_boolean(ctl, idx, val);
break; break;
case SND_CTL_ELEM_TYPE_INTEGER: case SND_CTL_ELEM_TYPE_INTEGER:
err = snd_config_get_integer(n, &val); err = snd_config_get_integer(n, &val);
@ -823,7 +823,7 @@ static int set_control(snd_ctl_t *handle, snd_config_t *control)
error("bad control.%d.value.%d content", numid, idx); error("bad control.%d.value.%d content", numid, idx);
return -EINVAL; return -EINVAL;
} }
snd_ctl_elem_set_integer(ctl, idx, val); snd_ctl_elem_value_set_integer(ctl, idx, val);
break; break;
case SND_CTL_ELEM_TYPE_ENUMERATED: case SND_CTL_ELEM_TYPE_ENUMERATED:
val = config_enumerated(n, handle, info); val = config_enumerated(n, handle, info);
@ -831,7 +831,7 @@ static int set_control(snd_ctl_t *handle, snd_config_t *control)
error("bad control.%d.value.%d content", numid, idx); error("bad control.%d.value.%d content", numid, idx);
return -EINVAL; return -EINVAL;
} }
snd_ctl_elem_set_enumerated(ctl, idx, val); snd_ctl_elem_value_set_enumerated(ctl, idx, val);
break; break;
case SND_CTL_ELEM_TYPE_BYTES: case SND_CTL_ELEM_TYPE_BYTES:
case SND_CTL_ELEM_TYPE_IEC958: case SND_CTL_ELEM_TYPE_IEC958:
@ -840,7 +840,7 @@ static int set_control(snd_ctl_t *handle, snd_config_t *control)
error("bad control.%d.value.%d content", numid, idx); error("bad control.%d.value.%d content", numid, idx);
return -EINVAL; return -EINVAL;
} }
snd_ctl_elem_set_byte(ctl, idx, val); snd_ctl_elem_value_set_byte(ctl, idx, val);
break; break;
default: default:
break; break;
@ -859,7 +859,7 @@ static int set_control(snd_ctl_t *handle, snd_config_t *control)
if (err < 0) { if (err < 0) {
snd_ctl_elem_id_t *id; snd_ctl_elem_id_t *id;
snd_ctl_elem_id_alloca(&id); snd_ctl_elem_id_alloca(&id);
snd_ctl_elem_get_id(ctl, id); snd_ctl_elem_value_get_id(ctl, id);
error("Cannot write control '%s': %s", id_str(id), snd_strerror(err)); error("Cannot write control '%s': %s", id_str(id), snd_strerror(err));
return err; return err;
} }
@ -871,7 +871,7 @@ static int set_controls(int card, snd_config_t *top)
snd_ctl_t *handle; snd_ctl_t *handle;
snd_ctl_card_info_t *info; snd_ctl_card_info_t *info;
snd_config_t *control; snd_config_t *control;
snd_config_iterator_t i; snd_config_iterator_t i, next;
int err; int err;
char name[32]; char name[32];
const char *id; const char *id;
@ -899,7 +899,7 @@ static int set_controls(int card, snd_config_t *top)
error("state.%s.control is not a compound\n", id); error("state.%s.control is not a compound\n", id);
return -EINVAL; return -EINVAL;
} }
snd_config_foreach(i, control) { snd_config_for_each(i, next, control) {
snd_config_t *n = snd_config_iterator_entry(i); snd_config_t *n = snd_config_iterator_entry(i);
err = set_control(handle, n); err = set_control(handle, n);
if (err < 0) if (err < 0)

View file

@ -202,18 +202,18 @@ enum {
/* channel mask for each type */ /* channel mask for each type */
static int mixer_elem_mask[] = { static int mixer_elem_mask[] = {
(SND_MIXER_CHN_MASK_FRONT_LEFT | SND_MIXER_CHN_MASK_FRONT_RIGHT), (SND_MIXER_SCHN_MASK_FRONT_LEFT | SND_MIXER_SCHN_MASK_FRONT_RIGHT),
(SND_MIXER_CHN_MASK_REAR_LEFT | SND_MIXER_CHN_MASK_REAR_RIGHT), (SND_MIXER_SCHN_MASK_REAR_LEFT | SND_MIXER_SCHN_MASK_REAR_RIGHT),
SND_MIXER_CHN_MASK_FRONT_CENTER, SND_MIXER_SCHN_MASK_FRONT_CENTER,
SND_MIXER_CHN_MASK_WOOFER, SND_MIXER_SCHN_MASK_WOOFER,
}; };
/* left and right channels for each type */ /* left and right channels for each type */
static snd_mixer_channel_id_t mixer_elem_chn[][2] = { static snd_mixer_selem_channel_id_t mixer_elem_chn[][2] = {
{ SND_MIXER_CHN_FRONT_LEFT, SND_MIXER_CHN_FRONT_RIGHT }, { SND_MIXER_SCHN_FRONT_LEFT, SND_MIXER_SCHN_FRONT_RIGHT },
{ SND_MIXER_CHN_REAR_LEFT, SND_MIXER_CHN_REAR_RIGHT }, { SND_MIXER_SCHN_REAR_LEFT, SND_MIXER_SCHN_REAR_RIGHT },
{ SND_MIXER_CHN_FRONT_CENTER, SND_MIXER_CHN_UNKNOWN }, { SND_MIXER_SCHN_FRONT_CENTER, SND_MIXER_SCHN_UNKNOWN },
{ SND_MIXER_CHN_WOOFER, SND_MIXER_CHN_UNKNOWN }, { SND_MIXER_SCHN_WOOFER, SND_MIXER_SCHN_UNKNOWN },
}; };
static snd_mixer_selem_id_t *mixer_sid = NULL; static snd_mixer_selem_id_t *mixer_sid = NULL;
@ -471,7 +471,7 @@ mixer_conv(int val, int omin, int omax, int nmin, int nmax)
} }
static int static int
mixer_calc_volume(snd_mixer_selem_t *scontrol, int vol, snd_mixer_channel_id_t chn) mixer_calc_volume(snd_mixer_selem_t *scontrol, int vol, snd_mixer_selem_channel_id_t chn)
{ {
int vol1; int vol1;
long min = snd_mixer_selem_get_min(scontrol); long min = snd_mixer_selem_get_min(scontrol);
@ -499,7 +499,7 @@ mixer_write_cbar (int elem_index)
snd_mixer_selem_t *scontrol; snd_mixer_selem_t *scontrol;
int vleft, vright, vbalance; int vleft, vright, vbalance;
int type; int type;
snd_mixer_channel_id_t chn_left, chn_right, chn; snd_mixer_selem_channel_id_t chn_left, chn_right, chn;
int err, changed; int err, changed;
snd_mixer_selem_alloca(&scontrol); snd_mixer_selem_alloca(&scontrol);
@ -514,8 +514,8 @@ mixer_write_cbar (int elem_index)
if (! (scontrol.channels & (1 << snd_enum_to_int(chn_left)))) if (! (scontrol.channels & (1 << snd_enum_to_int(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_CHN_UNKNOWN && ! (scontrol.channels & (1 << snd_enum_to_int(chn_right)))) if (chn_right != SND_MIXER_SCHN_UNKNOWN && ! (scontrol.channels & (1 << snd_enum_to_int(chn_right))))
chn_right = SND_MIXER_CHN_UNKNOWN; chn_right = SND_MIXER_SCHN_UNKNOWN;
changed = 0; changed = 0;
@ -526,7 +526,7 @@ mixer_write_cbar (int elem_index)
mixer_balance_volumes) && mixer_balance_volumes) &&
(scontrol.caps & SND_MIXER_SCTCAP_VOLUME)) { (scontrol.caps & SND_MIXER_SCTCAP_VOLUME)) {
int mono = int mono =
(chn_right == SND_MIXER_CHN_UNKNOWN || (scontrol.caps & SND_MIXER_SCTCAP_JOINTLY_VOLUME)); (chn_right == SND_MIXER_SCHN_UNKNOWN || (scontrol.caps & SND_MIXER_SCTCAP_JOINTLY_VOLUME));
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(&scontrol, mixer_volume_delta[MIXER_CHN_LEFT], chn_left); vleft = mixer_calc_volume(&scontrol, mixer_volume_delta[MIXER_CHN_LEFT], chn_left);
@ -539,7 +539,7 @@ mixer_write_cbar (int elem_index)
vright = vleft; vright = vleft;
if (vleft >= 0 && vright >= 0) { if (vleft >= 0 && vright >= 0) {
if (scontrol.caps & SND_MIXER_SCTCAP_JOINTLY_VOLUME) { if (scontrol.caps & SND_MIXER_SCTCAP_JOINTLY_VOLUME) {
for (chn = 0; chn < SND_MIXER_CHN_LAST; snd_enum_incr(chn)) { for (chn = 0; chn < SND_MIXER_SCHN_LAST; snd_enum_incr(chn)) {
int c = snd_enum_to_int(chn); int c = snd_enum_to_int(chn);
if (scontrol.channels & (1 << c)) if (scontrol.channels & (1 << c))
scontrol.volume.values[c] = vleft; scontrol.volume.values[c] = vleft;
@ -566,7 +566,7 @@ mixer_write_cbar (int elem_index)
else { else {
if (mixer_toggle_mute & MIXER_MASK_LEFT) if (mixer_toggle_mute & MIXER_MASK_LEFT)
scontrol.mute ^= (1 << snd_enum_to_int(chn_left)); scontrol.mute ^= (1 << snd_enum_to_int(chn_left));
if (chn_right != SND_MIXER_CHN_UNKNOWN && if (chn_right != SND_MIXER_SCHN_UNKNOWN &&
(mixer_toggle_mute & MIXER_MASK_RIGHT)) (mixer_toggle_mute & MIXER_MASK_RIGHT))
scontrol.mute ^= (1 << snd_enum_to_int(chn_right)); scontrol.mute ^= (1 << snd_enum_to_int(chn_right));
} }
@ -583,7 +583,7 @@ mixer_write_cbar (int elem_index)
else { else {
if (mixer_toggle_capture & MIXER_MASK_LEFT) if (mixer_toggle_capture & MIXER_MASK_LEFT)
scontrol.capture ^= (1 << snd_enum_to_int(chn_left)); scontrol.capture ^= (1 << snd_enum_to_int(chn_left));
if (chn_right != SND_MIXER_CHN_UNKNOWN && (mixer_toggle_capture & MIXER_MASK_RIGHT)) if (chn_right != SND_MIXER_SCHN_UNKNOWN && (mixer_toggle_capture & MIXER_MASK_RIGHT))
scontrol.capture ^= (1 << snd_enum_to_int(chn_right)); scontrol.capture ^= (1 << snd_enum_to_int(chn_right));
} }
changed = 1; changed = 1;
@ -605,7 +605,7 @@ mixer_update_cbar (int elem_index)
snd_mixer_selem_t scontrol; snd_mixer_selem_t scontrol;
int vleft, vright; int vleft, vright;
int type; int type;
snd_mixer_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;
int c_left, c_right; int c_left, c_right;
@ -623,9 +623,9 @@ mixer_update_cbar (int elem_index)
if (! (scontrol.channels & (1 << snd_enum_to_int(chn_left)))) if (! (scontrol.channels & (1 << snd_enum_to_int(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_CHN_UNKNOWN && if (chn_right != SND_MIXER_SCHN_UNKNOWN &&
! (scontrol.channels & (1 << snd_enum_to_int(chn_right)))) ! (scontrol.channels & (1 << snd_enum_to_int(chn_right))))
chn_right = SND_MIXER_CHN_UNKNOWN; chn_right = SND_MIXER_SCHN_UNKNOWN;
c_left = snd_enum_to_int(chn_left); c_left = snd_enum_to_int(chn_left);
c_right = snd_enum_to_int(chn_right); c_right = snd_enum_to_int(chn_right);
@ -636,7 +636,7 @@ mixer_update_cbar (int elem_index)
vleft = scontrol.volume.values[c_left]; vleft = scontrol.volume.values[c_left];
vleft = mixer_conv(vleft, scontrol.min, scontrol.max, 0, 100); vleft = mixer_conv(vleft, scontrol.min, scontrol.max, 0, 100);
if (chn_right != SND_MIXER_CHN_UNKNOWN) { if (chn_right != SND_MIXER_SCHN_UNKNOWN) {
vright = scontrol.volume.values[c_right]; vright = scontrol.volume.values[c_right];
vright = mixer_conv(vright, scontrol.min, scontrol.max, 0, 100); vright = mixer_conv(vright, scontrol.min, scontrol.max, 0, 100);
} else { } else {
@ -735,7 +735,7 @@ mixer_update_cbar (int elem_index)
mvaddch (y, x + 2, ACS_ULCORNER); mvaddch (y, x + 2, ACS_ULCORNER);
dc = scontrol.mute & (1 << c_left) ? DC_CBAR_MUTE : DC_CBAR_NOMUTE; dc = scontrol.mute & (1 << c_left) ? DC_CBAR_MUTE : DC_CBAR_NOMUTE;
mvaddch (y, x + 3, mixer_dc (dc)); mvaddch (y, x + 3, mixer_dc (dc));
if (chn_right != SND_MIXER_CHN_UNKNOWN) if (chn_right != SND_MIXER_SCHN_UNKNOWN)
dc = scontrol.mute & (1 << c_right) ? DC_CBAR_MUTE : DC_CBAR_NOMUTE; dc = scontrol.mute & (1 << c_right) ? DC_CBAR_MUTE : DC_CBAR_NOMUTE;
mvaddch (y, x + 4, mixer_dc (dc)); mvaddch (y, x + 4, mixer_dc (dc));
mixer_dc (DC_CBAR_FRAME); mixer_dc (DC_CBAR_FRAME);
@ -745,16 +745,16 @@ mixer_update_cbar (int elem_index)
/* capture input? /* capture input?
*/ */
if ((scontrol.capture & (1 << c_left)) || if ((scontrol.capture & (1 << c_left)) ||
(chn_right != SND_MIXER_CHN_UNKNOWN && (scontrol.capture & (1 << c_right)))) (chn_right != SND_MIXER_SCHN_UNKNOWN && (scontrol.capture & (1 << c_right))))
{ {
mixer_dc (DC_CBAR_CAPTURE); mixer_dc (DC_CBAR_CAPTURE);
mvaddstr (y, x + 1, "CAPTUR"); mvaddstr (y, x + 1, "CAPTUR");
if (scontrol.capture & (1 << c_left)) { if (scontrol.capture & (1 << c_left)) {
mvaddstr (y + 1, x + 1, "L"); mvaddstr (y + 1, x + 1, "L");
if (chn_right == SND_MIXER_CHN_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_CHN_UNKNOWN && if (chn_right != SND_MIXER_SCHN_UNKNOWN &&
(scontrol.capture & (1 << c_right))) (scontrol.capture & (1 << c_right)))
mvaddstr (y + 1, x + 6, "R"); mvaddstr (y + 1, x + 6, "R");
} }

View file

@ -100,16 +100,27 @@ static int info(void)
printf(" Controls : %i\n", snd_ctl_elem_list_get_count(clist)); printf(" Controls : %i\n", snd_ctl_elem_list_get_count(clist));
} }
snd_ctl_close(handle); snd_ctl_close(handle);
if ((err = snd_mixer_open(&mhandle, card)) < 0) { if ((err = snd_mixer_open(&mhandle)) < 0) {
error("Mixer %s open error: %s", card, snd_strerror(err)); error("Mixer open error: %s", snd_strerror(err));
return err; return err;
} }
err = snd_mixer_simple_build(mhandle); if ((err = snd_mixer_attach(mhandle, card)) < 0) {
if (err < 0) { error("Mixer attach %s error: %s", card, snd_strerror(err));
error("Mixer %s build error: %s", card, snd_strerror(err)); snd_mixer_close(mhandle);
} else { return err;
printf(" Simple ctrls : %i\n", snd_mixer_get_count(mhandle));
} }
if ((err = snd_mixer_selem_register(mhandle, 0)) < 0) {
error("Mixer register error: %s", snd_strerror(err));
snd_mixer_close(mhandle);
return err;
}
err = snd_mixer_load(mhandle);
if (err < 0) {
error("Mixer load error: %s", card, snd_strerror(err));
snd_mixer_close(mhandle);
return err;
}
printf(" Simple ctrls : %i\n", snd_mixer_get_count(mhandle));
snd_mixer_close(mhandle); snd_mixer_close(mhandle);
return 0; return 0;
} }
@ -301,24 +312,25 @@ static void show_control_id(snd_ctl_elem_id_t *id)
printf(",subdevice=%i", subdevice); printf(",subdevice=%i", subdevice);
} }
static int show_control(const char *space, snd_hctl_t *handle, static int show_control(const char *space, snd_hctl_elem_t *elem,
snd_ctl_elem_id_t *id, int level) int level)
{ {
int err; int err;
unsigned int item, idx; unsigned int item, idx;
unsigned int count; unsigned int count;
snd_ctl_elem_type_t type; snd_ctl_elem_type_t type;
snd_ctl_elem_id_t *id;
snd_ctl_elem_info_t *info; snd_ctl_elem_info_t *info;
snd_hctl_elem_t *helem; snd_ctl_elem_value_t *control;
snd_ctl_elem_id_alloca(&id);
snd_ctl_elem_info_alloca(&info); snd_ctl_elem_info_alloca(&info);
if ((helem = snd_hctl_find_elem(handle, id)) == NULL) snd_ctl_elem_value_alloca(&control);
return -EINVAL; if ((err = snd_hctl_elem_info(elem, info)) < 0) {
if ((err = snd_hctl_elem_info(helem, info)) < 0) {
error("Control %s cinfo error: %s\n", card, snd_strerror(err)); error("Control %s cinfo error: %s\n", card, snd_strerror(err));
return err; return err;
} }
if (level & 2) { if (level & 2) {
snd_ctl_elem_info_get_id(info, id); snd_hctl_elem_get_id(elem, id);
show_control_id(id); show_control_id(id);
printf("\n"); printf("\n");
} }
@ -338,7 +350,7 @@ static int show_control(const char *space, snd_hctl_t *handle,
printf(",items=%u\n", items); printf(",items=%u\n", items);
for (item = 0; item < items; item++) { for (item = 0; item < items; item++) {
snd_ctl_elem_info_set_item(info, item); snd_ctl_elem_info_set_item(info, item);
if ((err = snd_hctl_elem_info(helem, info)) < 0) { if ((err = snd_hctl_elem_info(elem, info)) < 0) {
error("Control %s element info error: %s\n", card, snd_strerror(err)); error("Control %s element info error: %s\n", card, snd_strerror(err));
return err; return err;
} }
@ -351,10 +363,7 @@ static int show_control(const char *space, snd_hctl_t *handle,
break; break;
} }
if (level & 1) { if (level & 1) {
snd_ctl_elem_t *elem; if ((err = snd_hctl_elem_read(elem, control)) < 0) {
snd_ctl_elem_alloca(&elem);
snd_ctl_elem_set_id(elem, id);
if ((err = snd_hctl_elem_read(helem, elem)) < 0) {
error("Control %s element read error: %s\n", card, snd_strerror(err)); error("Control %s element read error: %s\n", card, snd_strerror(err));
return err; return err;
} }
@ -364,16 +373,16 @@ static int show_control(const char *space, snd_hctl_t *handle,
printf(","); printf(",");
switch (snd_enum_to_int(type)) { switch (snd_enum_to_int(type)) {
case SND_CTL_ELEM_TYPE_BOOLEAN: case SND_CTL_ELEM_TYPE_BOOLEAN:
printf("%s", snd_ctl_elem_get_boolean(elem, idx) ? "on" : "off"); printf("%s", snd_ctl_elem_value_get_boolean(control, idx) ? "on" : "off");
break; break;
case SND_CTL_ELEM_TYPE_INTEGER: case SND_CTL_ELEM_TYPE_INTEGER:
printf("%li", snd_ctl_elem_get_integer(elem, idx)); printf("%li", snd_ctl_elem_value_get_integer(control, idx));
break; break;
case SND_CTL_ELEM_TYPE_ENUMERATED: case SND_CTL_ELEM_TYPE_ENUMERATED:
printf("%u", snd_ctl_elem_get_enumerated(elem, idx)); printf("%u", snd_ctl_elem_value_get_enumerated(control, idx));
break; break;
case SND_CTL_ELEM_TYPE_BYTES: case SND_CTL_ELEM_TYPE_BYTES:
printf("0x%02x", snd_ctl_elem_get_byte(elem, idx)); printf("0x%02x", snd_ctl_elem_value_get_byte(control, idx));
break; break;
default: default:
printf("?"); printf("?");
@ -397,12 +406,16 @@ static int controls(int level)
error("Control %s open error: %s", card, snd_strerror(err)); error("Control %s open error: %s", card, snd_strerror(err));
return err; return err;
} }
if ((err = snd_hctl_load(handle)) < 0) {
error("Control %s local error: %s\n", card, snd_strerror(err));
return err;
}
for (elem = snd_hctl_first_elem(handle); elem; elem = snd_hctl_elem_next(elem)) { for (elem = snd_hctl_first_elem(handle); elem; elem = snd_hctl_elem_next(elem)) {
snd_hctl_elem_get_id(elem, id); snd_hctl_elem_get_id(elem, id);
show_control_id(id); show_control_id(id);
printf("\n"); printf("\n");
if (level > 0) if (level > 0)
show_control(" ", handle, id, 1); show_control(" ", elem, 1);
} }
snd_hctl_close(handle); snd_hctl_close(handle);
return 0; return 0;
@ -411,11 +424,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; int err;
snd_mixer_channel_id_t chn; snd_mixer_selem_channel_id_t chn;
long min, max; long min, max;
snd_mixer_elem_t *elem; snd_mixer_elem_t *elem;
snd_mixer_selem_t *scontrol; snd_mixer_selem_info_t *sinfo;
snd_mixer_selem_alloca(&scontrol); 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) {
@ -423,60 +438,64 @@ 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) { if ((err = snd_mixer_selem_read(elem, scontrol)) < 0) {
error("Mixer %s selem error: %s", card, snd_strerror(err)); error("Mixer %s selem read error: %s", card, snd_strerror(err));
return err; return err;
} }
if ((level & 1) != 0) { if ((level & 1) != 0) {
printf("%sCapabilities:", space); printf("%sCapabilities:", space);
if (snd_mixer_selem_has_volume(scontrol)) if (snd_mixer_selem_info_has_volume(sinfo))
printf(" volume"); printf(" volume");
if (snd_mixer_selem_has_joined_volume(scontrol)) if (snd_mixer_selem_info_has_joined_volume(sinfo))
printf(" joined-volume"); printf(" joined-volume");
if (snd_mixer_selem_has_mute(scontrol)) if (snd_mixer_selem_info_has_mute(sinfo))
printf(" mute"); printf(" mute");
if (snd_mixer_selem_has_joined_mute(scontrol)) if (snd_mixer_selem_info_has_joined_mute(sinfo))
printf(" joined-mute"); printf(" joined-mute");
if (snd_mixer_selem_has_capture(scontrol)) { if (snd_mixer_selem_info_has_capture(sinfo)) {
printf(" capture"); printf(" capture");
} }
if (snd_mixer_selem_has_joined_capture(scontrol)) if (snd_mixer_selem_info_has_joined_capture(sinfo))
printf(" joined-capture"); printf(" joined-capture");
if (snd_mixer_selem_has_exclusive_capture(scontrol)) if (snd_mixer_selem_info_has_exclusive_capture(sinfo))
printf(" exclusive-capture"); printf(" exclusive-capture");
printf("\n"); printf("\n");
if (snd_mixer_selem_has_capture(scontrol) && if (snd_mixer_selem_info_has_capture(sinfo) &&
snd_mixer_selem_has_exclusive_capture(scontrol)) snd_mixer_selem_info_has_exclusive_capture(sinfo))
printf("%sCapture exclusive scontrol: %i\n", space, printf("%sCapture exclusive group: %i\n", space,
snd_mixer_selem_get_capture_group(scontrol)); snd_mixer_selem_info_get_capture_group(sinfo));
printf("%sChannels: ", space); printf("%sChannels: ", space);
if (snd_mixer_selem_is_mono(scontrol)) { if (snd_mixer_selem_info_is_mono(sinfo)) {
printf("Mono"); printf("Mono");
} else { } else {
for (chn = 0; chn <= SND_MIXER_CHN_LAST; snd_enum_incr(chn)){ for (chn = 0; chn <= SND_MIXER_SCHN_LAST; snd_enum_incr(chn)){
if (!snd_mixer_selem_has_channel(scontrol, chn)) if (!snd_mixer_selem_info_has_channel(sinfo, chn))
continue; continue;
printf("%s ", snd_mixer_channel_name(chn)); printf("%s ", snd_mixer_selem_channel_name(chn));
} }
} }
printf("\n"); printf("\n");
min = snd_mixer_selem_get_min(scontrol); min = snd_mixer_selem_info_get_min(sinfo);
max = snd_mixer_selem_get_max(scontrol); max = snd_mixer_selem_info_get_max(sinfo);
printf("%sLimits: min = %li, max = %li\n", space, min, max); printf("%sLimits: min = %li, max = %li\n", space, min, max);
if (snd_mixer_selem_is_mono(scontrol)) { if (snd_mixer_selem_info_is_mono(sinfo)) {
printf("%sMono: %s [%s]\n", space, printf("%sMono: %s [%s]\n", space,
get_percent(snd_mixer_selem_get_volume(scontrol, SND_MIXER_CHN_MONO), min, max), get_percent(snd_mixer_selem_value_get_volume(scontrol, SND_MIXER_SCHN_MONO), min, max),
snd_mixer_selem_get_mute(scontrol, SND_MIXER_CHN_MONO) ? "mute" : "on"); snd_mixer_selem_value_get_mute(scontrol, SND_MIXER_SCHN_MONO) ? "mute" : "on");
} else { } else {
for (chn = 0; chn <= SND_MIXER_CHN_LAST; snd_enum_incr(chn)) { for (chn = 0; chn <= SND_MIXER_SCHN_LAST; snd_enum_incr(chn)) {
if (!snd_mixer_selem_has_channel(scontrol, chn)) if (!snd_mixer_selem_info_has_channel(sinfo, chn))
continue; continue;
printf("%s%s: %s [%s] [%s]\n", printf("%s%s: %s [%s] [%s]\n",
space, space,
snd_mixer_channel_name(chn), snd_mixer_selem_channel_name(chn),
get_percent(snd_mixer_selem_get_volume(scontrol, chn), min, max), get_percent(snd_mixer_selem_value_get_volume(scontrol, chn), min, max),
snd_mixer_selem_get_mute(scontrol, chn) ? "mute" : "on", snd_mixer_selem_value_get_mute(scontrol, chn) ? "mute" : "on",
snd_mixer_selem_get_capture(scontrol, chn) ? "capture" : "---"); snd_mixer_selem_value_get_capture(scontrol, chn) ? "capture" : "---");
} }
} }
} }
@ -491,13 +510,24 @@ static int selems(int level)
snd_mixer_elem_t *elem; snd_mixer_elem_t *elem;
snd_mixer_selem_id_alloca(&sid); snd_mixer_selem_id_alloca(&sid);
if ((err = snd_mixer_open(&handle, card)) < 0) { if ((err = snd_mixer_open(&handle)) < 0) {
error("Mixer %s open error: %s", card, snd_strerror(err)); error("Mixer %s open error: %s", card, snd_strerror(err));
return err; return err;
} }
err = snd_mixer_simple_build(handle); if ((err = snd_mixer_attach(handle, card)) < 0) {
error("Mixer attach %s error: %s", card, snd_strerror(err));
snd_mixer_close(handle);
return err;
}
if ((err = snd_mixer_selem_register(handle, 0)) < 0) {
error("Mixer register error: %s", snd_strerror(err));
snd_mixer_close(handle);
return err;
}
err = snd_mixer_load(handle);
if (err < 0) { if (err < 0) {
error("Mixer %s build error: %s", card, snd_strerror(err)); error("Mixer load error: %s", card, snd_strerror(err));
snd_mixer_close(handle);
return err; return err;
} }
for (elem = snd_mixer_first_elem(handle); elem; elem = snd_mixer_elem_next(elem)) { for (elem = snd_mixer_first_elem(handle); elem; elem = snd_mixer_elem_next(elem)) {
@ -650,14 +680,14 @@ static int cset(int argc, char *argv[], int roflag)
snd_ctl_t *handle; snd_ctl_t *handle;
snd_ctl_elem_info_t *info; snd_ctl_elem_info_t *info;
snd_ctl_elem_id_t *id; snd_ctl_elem_id_t *id;
snd_ctl_elem_t *control; snd_ctl_elem_value_t *control;
char *ptr; char *ptr;
unsigned int idx, count; unsigned int idx, count;
long tmp; long tmp;
snd_ctl_elem_type_t type; snd_ctl_elem_type_t type;
snd_ctl_elem_info_alloca(&info); snd_ctl_elem_info_alloca(&info);
snd_ctl_elem_id_alloca(&id); snd_ctl_elem_id_alloca(&id);
snd_ctl_elem_alloca(&control); snd_ctl_elem_value_alloca(&control);
if (argc < 1) { if (argc < 1) {
fprintf(stderr, "Specify a full control identifier: [[iface=<iface>,][name='name',][index=<index>,][device=<device>,][subdevice=<subdevice>]]|[numid=<numid>]\n"); fprintf(stderr, "Specify a full control identifier: [[iface=<iface>,][name='name',][index=<index>,][device=<device>,][subdevice=<subdevice>]]|[numid=<numid>]\n");
@ -683,7 +713,7 @@ static int cset(int argc, char *argv[], int roflag)
} }
type = snd_ctl_elem_info_get_type(info); type = snd_ctl_elem_info_get_type(info);
count = snd_ctl_elem_info_get_count(info); count = snd_ctl_elem_info_get_count(info);
snd_ctl_elem_set_id(control, id); snd_ctl_elem_value_set_id(control, id);
if (!roflag) { if (!roflag) {
ptr = argv[1]; ptr = argv[1];
@ -702,21 +732,21 @@ static int cset(int argc, char *argv[], int roflag)
while (isdigit(*ptr)) while (isdigit(*ptr))
ptr++; ptr++;
} }
snd_ctl_elem_set_boolean(control, idx, tmp); snd_ctl_elem_value_set_boolean(control, idx, tmp);
break; break;
case SND_CTL_ELEM_TYPE_INTEGER: case SND_CTL_ELEM_TYPE_INTEGER:
tmp = get_integer(&ptr, tmp = get_integer(&ptr,
snd_ctl_elem_info_get_min(info), snd_ctl_elem_info_get_min(info),
snd_ctl_elem_info_get_max(info)); snd_ctl_elem_info_get_max(info));
snd_ctl_elem_set_integer(control, idx, tmp); snd_ctl_elem_value_set_integer(control, idx, tmp);
break; break;
case SND_CTL_ELEM_TYPE_ENUMERATED: case SND_CTL_ELEM_TYPE_ENUMERATED:
tmp = get_integer(&ptr, 0, snd_ctl_elem_info_get_items(info) - 1); tmp = get_integer(&ptr, 0, snd_ctl_elem_info_get_items(info) - 1);
snd_ctl_elem_set_enumerated(control, idx, tmp); snd_ctl_elem_value_set_enumerated(control, idx, tmp);
break; break;
case SND_CTL_ELEM_TYPE_BYTES: case SND_CTL_ELEM_TYPE_BYTES:
tmp = get_integer(&ptr, 0, 255); tmp = get_integer(&ptr, 0, 255);
snd_ctl_elem_set_byte(control, idx, tmp); snd_ctl_elem_value_set_byte(control, idx, tmp);
break; break;
default: default:
break; break;
@ -732,15 +762,25 @@ static int cset(int argc, char *argv[], int roflag)
} }
} }
snd_ctl_close(handle); snd_ctl_close(handle);
#if 0
/* FIXME */
if (!quiet) { if (!quiet) {
snd_hctl_t *hctl; snd_hctl_t *hctl;
snd_hctl_t *elem;
if ((err = snd_hctl_open(&hctl, card)) < 0) { if ((err = snd_hctl_open(&hctl, card)) < 0) {
error("Control %s open error: %s\n", card, snd_strerror(err)); error("Control %s open error: %s\n", card, snd_strerror(err));
return err; return err;
} }
show_control(" ", hctl, id, 3); if ((err = snd_hctl_load(&hctl)) < 0) {
error("Control %s load error: %s\n", card, snd_strerror(err));
return err;
}
elem = snd_hctl_find_elem(hctl, id);
assert(elem);
show_control(" ", elem, 3);
snd_hctl_close(hctl); snd_hctl_close(hctl);
} }
#endif
return 0; return 0;
} }
@ -749,17 +789,17 @@ typedef struct channel_mask {
unsigned int mask; unsigned int mask;
} channel_mask_t; } channel_mask_t;
static channel_mask_t chanmask[] = { static channel_mask_t chanmask[] = {
{"frontleft", 1 << SND_MIXER_CHN_FRONT_LEFT}, {"frontleft", 1 << SND_MIXER_SCHN_FRONT_LEFT},
{"frontright", 1 << SND_MIXER_CHN_FRONT_RIGHT}, {"frontright", 1 << SND_MIXER_SCHN_FRONT_RIGHT},
{"frontcenter", 1 << SND_MIXER_CHN_FRONT_CENTER}, {"frontcenter", 1 << SND_MIXER_SCHN_FRONT_CENTER},
{"front", ((1 << SND_MIXER_CHN_FRONT_LEFT) | {"front", ((1 << SND_MIXER_SCHN_FRONT_LEFT) |
(1 << SND_MIXER_CHN_FRONT_RIGHT))}, (1 << SND_MIXER_SCHN_FRONT_RIGHT))},
{"center", 1 << SND_MIXER_CHN_FRONT_CENTER}, {"center", 1 << SND_MIXER_SCHN_FRONT_CENTER},
{"rearleft", 1 << SND_MIXER_CHN_REAR_LEFT}, {"rearleft", 1 << SND_MIXER_SCHN_REAR_LEFT},
{"rearright", 1 << SND_MIXER_CHN_REAR_RIGHT}, {"rearright", 1 << SND_MIXER_SCHN_REAR_RIGHT},
{"rear", ((1 << SND_MIXER_CHN_REAR_LEFT) | {"rear", ((1 << SND_MIXER_SCHN_REAR_LEFT) |
(1 << SND_MIXER_CHN_REAR_RIGHT))}, (1 << SND_MIXER_SCHN_REAR_RIGHT))},
{"woofer", 1 << SND_MIXER_CHN_WOOFER}, {"woofer", 1 << SND_MIXER_SCHN_WOOFER},
{NULL, 0} {NULL, 0}
}; };
@ -778,15 +818,17 @@ static int sset(unsigned int argc, char *argv[], int roflag)
{ {
int err; int err;
unsigned int idx; unsigned int idx;
snd_mixer_channel_id_t chn; snd_mixer_selem_channel_id_t chn;
unsigned int channels; unsigned int channels;
long min, max; long min, max;
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_t *control; 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_alloca(&control); 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");
@ -800,41 +842,62 @@ static int sset(unsigned int argc, char *argv[], int roflag)
fprintf(stderr, "Specify what you want to set...\n"); fprintf(stderr, "Specify what you want to set...\n");
return 1; return 1;
} }
if ((err = snd_mixer_open(&handle, card)) < 0) { if ((err = snd_mixer_open(&handle)) < 0) {
error("Mixer %s open error: %s\n", card, snd_strerror(err)); error("Mixer %s open error: %s\n", card, snd_strerror(err));
return err; return err;
} }
if ((err = snd_mixer_attach(handle, card)) < 0) {
error("Mixer attach %s error: %s", card, snd_strerror(err));
snd_mixer_close(handle);
return err;
}
if ((err = snd_mixer_selem_register(handle, 0)) < 0) {
error("Mixer register error: %s", snd_strerror(err));
snd_mixer_close(handle);
return err;
}
err = snd_mixer_load(handle);
if (err < 0) {
error("Mixer load error: %s", card, snd_strerror(err));
snd_mixer_close(handle);
return err;
}
elem = snd_mixer_find_selem(handle, sid); elem = snd_mixer_find_selem(handle, sid);
if (!elem) { if (!elem) {
error("Unable to find simple control '%s',%i: %s\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid), snd_strerror(err)); error("Unable to find 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); snd_mixer_close(handle);
return -ENOENT; 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) { 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)); 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); snd_mixer_close(handle);
return err; return err;
} }
min = snd_mixer_selem_get_min(control); min = snd_mixer_selem_info_get_min(info);
max = snd_mixer_selem_get_min(control); max = snd_mixer_selem_info_get_min(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_set_mute_all(control, 1); snd_mixer_selem_value_set_mute_all(control, 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_set_mute_all(control, 0); snd_mixer_selem_value_set_mute_all(control, 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_set_capture_all(control, 1); snd_mixer_selem_value_set_capture_all(control, 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_set_capture_all(control, 0); snd_mixer_selem_value_set_capture_all(control, 0);
continue; continue;
} }
channels = channels_mask(argv[idx]); channels = channels_mask(argv[idx]);
@ -846,14 +909,14 @@ 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_CHN_LAST; snd_enum_incr(chn)) { for (chn = 0; chn <= SND_MIXER_SCHN_LAST; snd_enum_incr(chn)) {
if (!(channels & (1 << chn)) || if (!(channels & (1 << chn)) ||
!snd_mixer_selem_has_channel(control, chn)) !snd_mixer_selem_info_has_channel(info, chn))
continue; continue;
if (! multi) if (! multi)
ptr = argv[idx]; ptr = argv[idx];
snd_mixer_selem_set_volume(control, chn, get_volume_simple(&ptr, min, max, snd_mixer_selem_get_volume(control, chn))); snd_mixer_selem_value_set_volume(control, chn, get_volume_simple(&ptr, min, max, snd_mixer_selem_value_get_volume(control, chn)));
} }
} else { } else {
error("Unknown setup '%s'..\n", argv[idx]); error("Unknown setup '%s'..\n", argv[idx]);
@ -875,12 +938,12 @@ static int sset(unsigned int argc, char *argv[], int roflag)
return 0; return 0;
} }
static void events_change(snd_hctl_elem_t *helem) static void events_info(snd_hctl_elem_t *helem)
{ {
snd_ctl_elem_id_t *id; snd_ctl_elem_id_t *id;
snd_ctl_elem_id_alloca(&id); snd_ctl_elem_id_alloca(&id);
snd_hctl_elem_get_id(helem, id); snd_hctl_elem_get_id(helem, id);
printf("event change: "); printf("event info: ");
show_control_id(id); show_control_id(id);
printf("\n"); printf("\n");
} }
@ -913,8 +976,8 @@ static void events_rebuild()
int element_callback(snd_hctl_elem_t *elem, snd_ctl_event_type_t event) int element_callback(snd_hctl_elem_t *elem, snd_ctl_event_type_t event)
{ {
switch (event) { switch (event) {
case SND_CTL_EVENT_CHANGE: case SND_CTL_EVENT_INFO:
events_change(elem); events_info(elem);
break; break;
case SND_CTL_EVENT_VALUE: case SND_CTL_EVENT_VALUE:
events_value(elem); events_value(elem);
@ -940,8 +1003,7 @@ static void events_add(snd_hctl_elem_t *helem)
snd_hctl_elem_set_callback(helem, element_callback); snd_hctl_elem_set_callback(helem, element_callback);
} }
int ctl_callback(snd_hctl_t *hctl, int ctl_callback(snd_hctl_t *ctl, snd_ctl_event_type_t event,
snd_ctl_event_type_t event,
snd_hctl_elem_t *elem) snd_hctl_elem_t *elem)
{ {
switch (event) { switch (event) {
@ -969,6 +1031,10 @@ static int events(int argc ATTRIBUTE_UNUSED, char *argv[] ATTRIBUTE_UNUSED)
return err; return err;
} }
snd_hctl_set_callback(handle, ctl_callback); snd_hctl_set_callback(handle, ctl_callback);
if ((err = snd_hctl_load(handle)) < 0) {
error("Control %s hbuild error: %s\n", card, snd_strerror(err));
return err;
}
for (helem = snd_hctl_first_elem(handle); helem; helem = snd_hctl_elem_next(helem)) { for (helem = snd_hctl_first_elem(handle); helem; helem = snd_hctl_elem_next(helem)) {
snd_hctl_elem_set_callback(helem, element_callback); snd_hctl_elem_set_callback(helem, element_callback);
} }
@ -981,9 +1047,8 @@ static int events(int argc ATTRIBUTE_UNUSED, char *argv[] ATTRIBUTE_UNUSED)
ctl_poll.revents = 0; ctl_poll.revents = 0;
if ((res = poll(&ctl_poll, 1, -1)) > 0) { if ((res = poll(&ctl_poll, 1, -1)) > 0) {
printf("Poll ok: %i\n", res); printf("Poll ok: %i\n", res);
res = snd_hctl_events(handle); res = snd_hctl_handle_events(handle);
if (res > 0) assert(res > 0);
printf("%i events processed\n", res);
} }
} }
snd_hctl_close(handle); snd_hctl_close(handle);
@ -994,9 +1059,9 @@ static void sevents_value(snd_mixer_selem_id_t *sid)
printf("event value: '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid)); printf("event value: '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid));
} }
static void sevents_change(snd_mixer_selem_id_t *sid) static void sevents_info(snd_mixer_selem_id_t *sid)
{ {
printf("event change: '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid)); printf("event info: '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid));
} }
static void sevents_remove(snd_mixer_selem_id_t *sid) static void sevents_remove(snd_mixer_selem_id_t *sid)
@ -1004,14 +1069,14 @@ static void sevents_remove(snd_mixer_selem_id_t *sid)
printf("event remove: '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid)); printf("event remove: '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid));
} }
int selem_callback(snd_mixer_elem_t *elem, snd_ctl_event_type_t event) int melem_event(snd_mixer_elem_t *elem, snd_ctl_event_type_t event)
{ {
snd_mixer_selem_id_t *sid; snd_mixer_selem_id_t *sid;
snd_mixer_selem_id_alloca(&sid); snd_mixer_selem_id_alloca(&sid);
snd_mixer_selem_get_id(elem, sid); snd_mixer_selem_get_id(elem, sid);
switch (event) { switch (event) {
case SND_CTL_EVENT_CHANGE: case SND_CTL_EVENT_INFO:
sevents_change(sid); sevents_info(sid);
break; break;
case SND_CTL_EVENT_VALUE: case SND_CTL_EVENT_VALUE:
sevents_value(sid); sevents_value(sid);
@ -1037,7 +1102,7 @@ static void sevents_add(snd_mixer_elem_t *elem)
snd_mixer_selem_id_alloca(&sid); snd_mixer_selem_id_alloca(&sid);
snd_mixer_selem_get_id(elem, sid); snd_mixer_selem_get_id(elem, sid);
printf("event add: '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid)); printf("event add: '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid));
snd_mixer_elem_set_callback(elem, selem_callback); snd_mixer_elem_set_callback(elem, melem_event);
} }
int mixer_event(snd_mixer_t *mixer, snd_ctl_event_type_t event, int mixer_event(snd_mixer_t *mixer, snd_ctl_event_type_t event,
@ -1062,14 +1127,24 @@ static int sevents(int argc ATTRIBUTE_UNUSED, char *argv[] ATTRIBUTE_UNUSED)
snd_mixer_t *handle; snd_mixer_t *handle;
int err; int err;
if ((err = snd_mixer_open(&handle, card)) < 0) { if ((err = snd_mixer_open(&handle)) < 0) {
error("Mixer %s open error: %s\n", card, snd_strerror(err)); error("Mixer %s open error: %s", card, snd_strerror(err));
return err;
}
if ((err = snd_mixer_attach(handle, card)) < 0) {
error("Mixer attach %s error: %s", card, snd_strerror(err));
snd_mixer_close(handle);
return err;
}
if ((err = snd_mixer_selem_register(handle, 0)) < 0) {
error("Mixer register error: %s", snd_strerror(err));
snd_mixer_close(handle);
return err; return err;
} }
snd_mixer_set_callback(handle, mixer_event); snd_mixer_set_callback(handle, mixer_event);
err = snd_mixer_simple_build(handle); err = snd_mixer_load(handle);
if (err < 0) { if (err < 0) {
error("Mixer %s build error: %s\n", card, snd_strerror(err)); error("Mixer load error: %s", card, snd_strerror(err));
snd_mixer_close(handle); snd_mixer_close(handle);
return err; return err;
} }
@ -1078,14 +1153,14 @@ static int sevents(int argc ATTRIBUTE_UNUSED, char *argv[] ATTRIBUTE_UNUSED)
while (1) { while (1) {
struct pollfd mixer_poll; struct pollfd mixer_poll;
int res; int res;
mixer_poll.fd = snd_mixer_poll_descriptor(handle); mixer_poll.fd = snd_mixer_poll_descriptor(handle, card);
assert(mixer_poll.fd >= 0);
mixer_poll.events = POLLIN; mixer_poll.events = POLLIN;
mixer_poll.revents = 0; mixer_poll.revents = 0;
if ((res = poll(&mixer_poll, 1, -1)) > 0) { if ((res = poll(&mixer_poll, 1, -1)) > 0) {
printf("Poll ok: %i\n", res); printf("Poll ok: %i\n", res);
res = snd_mixer_events(handle); res = snd_mixer_handle_events(handle);
if (res > 0) assert(res >= 0);
printf("%i events processed\n", res);
} }
} }
snd_mixer_close(handle); snd_mixer_close(handle);

View file

@ -448,16 +448,16 @@ int main(int argc, char *argv[])
} }
if (digtype != SND_CTL_ELEM_TYPE_NONE) { if (digtype != SND_CTL_ELEM_TYPE_NONE) {
snd_ctl_elem_t *ctl; snd_ctl_elem_value_t *ctl;
snd_ctl_t *ctl_handle; snd_ctl_t *ctl_handle;
char ctl_name[12]; char ctl_name[12];
int ctl_card; int ctl_card;
snd_ctl_elem_alloca(&ctl); snd_ctl_elem_value_alloca(&ctl);
snd_ctl_elem_set_interface(ctl, SND_CTL_ELEM_IFACE_PCM); snd_ctl_elem_value_set_interface(ctl, SND_CTL_ELEM_IFACE_PCM);
snd_ctl_elem_set_device(ctl, snd_pcm_info_get_device(info)); snd_ctl_elem_value_set_device(ctl, snd_pcm_info_get_device(info));
snd_ctl_elem_set_subdevice(ctl, snd_pcm_info_get_subdevice(info)); snd_ctl_elem_value_set_subdevice(ctl, snd_pcm_info_get_subdevice(info));
snd_ctl_elem_set_name(ctl, "IEC958 (S/PDIF) Stream"); snd_ctl_elem_value_set_name(ctl, "IEC958 (S/PDIF) Stream");
snd_ctl_elem_set_iec958(ctl, &spdif); snd_ctl_elem_value_set_iec958(ctl, &spdif);
ctl_card = snd_pcm_info_get_card(info); ctl_card = snd_pcm_info_get_card(info);
if (ctl_card < 0) { if (ctl_card < 0) {
error("Unable to setup the IEC958 (S/PDIF) interface - PCM has no assigned card"); error("Unable to setup the IEC958 (S/PDIF) interface - PCM has no assigned card");