amixer - added basic TLV support (read only) for 'amixer controls'

This commit is contained in:
Jaroslav Kysela 2006-07-05 17:46:10 +02:00
parent 7bae1b0a5b
commit 33319eb4ed
2 changed files with 85 additions and 3 deletions

View file

@ -154,6 +154,9 @@ static const char *control_access(snd_ctl_elem_info_t *info)
*res++ = snd_ctl_elem_info_is_inactive(info) ? 'i' : '-'; *res++ = snd_ctl_elem_info_is_inactive(info) ? 'i' : '-';
*res++ = snd_ctl_elem_info_is_volatile(info) ? 'v' : '-'; *res++ = snd_ctl_elem_info_is_volatile(info) ? 'v' : '-';
*res++ = snd_ctl_elem_info_is_locked(info) ? 'l' : '-'; *res++ = snd_ctl_elem_info_is_locked(info) ? 'l' : '-';
*res++ = snd_ctl_elem_info_is_tlv_readable(info) ? 'R' : '-';
*res++ = snd_ctl_elem_info_is_tlv_writable(info) ? 'W' : '-';
*res++ = snd_ctl_elem_info_is_tlv_commandable(info) ? 'C' : '-';
*res++ = '\0'; *res++ = '\0';
return result; return result;
} }
@ -378,12 +381,80 @@ static void show_control_id(snd_ctl_elem_id_t *id)
printf(",subdevice=%i", subdevice); printf(",subdevice=%i", subdevice);
} }
static void print_spaces(unsigned int spaces)
{
while (spaces-- > 0)
putc(' ', stdout);
}
static void print_dB(int dB)
{
printf("%i.%02idB", dB / 100, dB % 100);
}
static void decode_tlv(unsigned int spaces, unsigned int *tlv, unsigned int tlv_size)
{
unsigned int type = tlv[0];
unsigned int size;
unsigned int idx = 0;
if (tlv_size < 2 * sizeof(unsigned int)) {
printf("TLV size error!\n");
return;
}
print_spaces(spaces);
printf("| ");
type = tlv[idx++];
size = tlv[idx++];
tlv_size -= 2 * sizeof(unsigned int);
if (size > tlv_size) {
printf("TLV size error (%i, %i, %i)!\n", type, size, tlv_size);
return;
}
switch (type) {
case SND_CTL_TLVT_CONTAINER:
size += sizeof(unsigned int) -1;
size /= sizeof(unsigned int);
while (idx < size) {
if (tlv[idx+1] > (size - idx) * sizeof(unsigned int)) {
printf("TLV size error in compound!\n");
return;
}
decode_tlv(spaces + 2, tlv + idx, tlv[idx+1]);
idx += 2 + (tlv[1] + sizeof(unsigned int) - 1) / sizeof(unsigned int);
}
break;
case SND_CTL_TLVT_DB_SCALE:
printf("dBscale-");
if (size != 2 * sizeof(unsigned int)) {
while (size > 0) {
printf("0x%x", tlv[idx++]);
size -= sizeof(unsigned int);
}
} else {
printf("min=");
print_dB(tlv[2]);
printf(",step=");
print_dB(tlv[3] & 0xffff);
printf(",mute=%i", (tlv[3] >> 16) & 1);
}
break;
default:
printf("unk-%i-", type);
while (size > 0) {
printf("0x%x", tlv[idx++]);
size -= sizeof(unsigned int);
}
break;
}
putc('\n', stdout);
}
static int show_control(const char *space, snd_hctl_elem_t *elem, static int show_control(const char *space, snd_hctl_elem_t *elem,
int level) int level)
{ {
int err; int err;
unsigned int item, idx; unsigned int item, idx, count, *tlv;
unsigned int count;
snd_ctl_elem_type_t type; snd_ctl_elem_type_t type;
snd_ctl_elem_id_t *id; snd_ctl_elem_id_t *id;
snd_ctl_elem_info_t *info; snd_ctl_elem_info_t *info;
@ -465,7 +536,18 @@ static int show_control(const char *space, snd_hctl_elem_t *elem,
} }
} }
printf("\n"); printf("\n");
if (!snd_ctl_elem_info_is_tlv_readable(info))
goto __skip_tlv;
tlv = malloc(4096);
if ((err = snd_hctl_elem_tlv_read(elem, tlv, 4096)) < 0) {
error("Control %s element TLV read error: %s\n", card, snd_strerror(err));
free(tlv);
return err;
} }
decode_tlv(strlen(space), tlv, 4096);
free(tlv);
}
__skip_tlv:
return 0; return 0;
} }

View file

@ -27,7 +27,7 @@ AC_PROG_CC
dnl AC_PROG_CXX dnl AC_PROG_CXX
AC_PROG_INSTALL AC_PROG_INSTALL
AC_PROG_LN_S AC_PROG_LN_S
AM_PATH_ALSA(1.0.9) AM_PATH_ALSA(1.0.12)
AC_ARG_ENABLE(alsamixer, AC_ARG_ENABLE(alsamixer,
[ --disable-alsamixer Disable alsamixer compilation], [ --disable-alsamixer Disable alsamixer compilation],