mixer - cleanups for dB scale parsing

This commit is contained in:
Jaroslav Kysela 2006-07-27 10:45:25 +02:00
parent a98fd022fa
commit c4a5efeba3
2 changed files with 36 additions and 33 deletions

View file

@ -798,53 +798,56 @@ static int snd_hctl_elem_decode_tlv_db_gain(unsigned int *tlv, unsigned int tlv_
size = tlv[idx++]; size = tlv[idx++];
tlv_size -= 2 * sizeof(unsigned int); tlv_size -= 2 * sizeof(unsigned int);
if (size > tlv_size) { if (size > tlv_size) {
printf("TLV size error (%i, %i, %i)!\n", type, size, tlv_size); err = -EINVAL;
err=-EINVAL;
goto __exit_decode_db_gain; goto __exit_decode_db_gain;
} }
switch (type) { switch (type) {
case SND_CTL_TLVT_CONTAINER: case SND_CTL_TLVT_CONTAINER:
size += sizeof(unsigned int) -1; size += sizeof(unsigned int) - 1;
size /= sizeof(unsigned int); size /= sizeof(unsigned int);
printf("TLV container!\n");
while (idx < size) { while (idx < size) {
if (tlv[idx+1] > (size - idx) * sizeof(unsigned int)) { if (tlv[idx+1] > (size - idx) * sizeof(unsigned int)) {
printf("TLV size error in compound!\n"); err = -EINVAL;
err=-EINVAL;
goto __exit_decode_db_gain; goto __exit_decode_db_gain;
} }
err = snd_hctl_elem_decode_tlv_db_gain(tlv + idx, tlv[idx+1], volume, db_gain); err = snd_hctl_elem_decode_tlv_db_gain(tlv + idx, tlv[idx+1], volume, db_gain);
if (!err) break; /* db_gain obtained */ if (!err)
break; /* db_gain obtained */
idx += 2 + (tlv[1] + sizeof(unsigned int) - 1) / sizeof(unsigned int); idx += 2 + (tlv[1] + sizeof(unsigned int) - 1) / sizeof(unsigned int);
} }
break; break;
case SND_CTL_TLVT_DB_SCALE: case SND_CTL_TLVT_DB_SCALE:
if (size != 2 * sizeof(unsigned int)) { if (size != 2 * sizeof(unsigned int)) {
#if 0
while (size > 0) { while (size > 0) {
printf("0x%x", tlv[idx++]); printf("0x%x", tlv[idx++]);
size -= sizeof(unsigned int); size -= sizeof(unsigned int);
} }
printf("\n"); printf("\n");
#endif
} else { } else {
int min,step,mute; int min,step,mute;
min = tlv[2]; min = tlv[2];
step = (tlv[3] & 0xffff); step = (tlv[3] & 0xffff);
mute = (tlv[3] >> 16) & 1; mute = (tlv[3] >> 16) & 1;
*db_gain = (volume * step) + min; *db_gain = (volume * step) + min;
if (mute && (volume == 0)) *db_gain = -9999999; if (mute && (volume == 0))
*db_gain = -9999999;
} }
break; break;
default: default:
#if 0
printf("unk-%i-", type); printf("unk-%i-", type);
while (size > 0) { while (size > 0) {
printf("0x%x", tlv[idx++]); printf("0x%x", tlv[idx++]);
size -= sizeof(unsigned int); size -= sizeof(unsigned int);
} }
printf("\n"); printf("\n");
#endif
break; break;
} }
__exit_decode_db_gain: __exit_decode_db_gain:
return err; return err;
} }
@ -859,34 +862,33 @@ int snd_hctl_elem_get_db_gain(snd_hctl_elem_t *elem, long volume, long *db_gain)
{ {
snd_ctl_elem_info_t *info; snd_ctl_elem_info_t *info;
unsigned int *tlv; unsigned int *tlv;
unsigned int tlv_size=4096; unsigned int tlv_size = 4096;
unsigned int type; int err;
unsigned int size;
unsigned int idx = 0;
int err=0;
snd_ctl_elem_info_alloca(&info); snd_ctl_elem_info_alloca(&info);
snd_hctl_elem_info(elem, info); err = snd_hctl_elem_info(elem, info);
if (err < 0)
return err;
if (tlv_size < 2 * sizeof(unsigned int)) { if (tlv_size < 2 * sizeof(unsigned int)) {
printf("TLV size error!\n"); err = -EINVAL;
err=-EINVAL;
goto __exit_db_gain; goto __exit_db_gain;
} }
if (!snd_ctl_elem_info_is_tlv_readable(info)) { if (!snd_ctl_elem_info_is_tlv_readable(info)) {
err=-EINVAL; err = -EINVAL;
goto __exit_db_gain; goto __exit_db_gain;
} }
tlv = malloc(4096); tlv = malloc(tlv_size);
if ((err = snd_hctl_elem_tlv_read(elem, tlv, tlv_size)) < 0) { if (tlv == NULL) {
printf("Control element TLV read error: %s\n", snd_strerror(err)); err = -ENOMEM;
goto __free_exit_db_gain; goto __exit_db_gain;
} }
if ((err = snd_hctl_elem_tlv_read(elem, tlv, tlv_size)) < 0)
goto __free_exit_db_gain;
err = snd_hctl_elem_decode_tlv_db_gain(tlv, tlv_size, volume, db_gain); err = snd_hctl_elem_decode_tlv_db_gain(tlv, tlv_size, volume, db_gain);
__free_exit_db_gain:
__free_exit_db_gain:
free(tlv); free(tlv);
__exit_db_gain: __exit_db_gain:
return err; return err;
} }

View file

@ -980,23 +980,24 @@ static int get_dB_ops(snd_mixer_elem_t *elem,
selem_ctl_t *c; selem_ctl_t *c;
int err = -EINVAL; int err = -EINVAL;
long volume, db_gain; long volume, db_gain;
if (dir == SM_PLAY) { if (dir == SM_PLAY) {
c = &s->ctls[CTL_PLAYBACK_VOLUME]; c = &s->ctls[CTL_PLAYBACK_VOLUME];
if (c->type != 2) { if (c->type != 2)
goto _err; goto _err;
}
} else if (dir == SM_CAPT) { } else if (dir == SM_CAPT) {
c = &s->ctls[CTL_CAPTURE_VOLUME]; c = &s->ctls[CTL_CAPTURE_VOLUME];
if (c->type != 2) { if (c->type != 2)
goto _err; goto _err;
} } else {
} else goto _err;
if (err = get_volume_ops(elem, dir, channel, &volume)) {
goto _err; goto _err;
} }
if ((err = snd_hctl_elem_get_db_gain(c->elem, volume, &db_gain)) < 0) { err = get_volume_ops(elem, dir, channel, &volume);
if (err < 0)
goto _err;
err = snd_hctl_elem_get_db_gain(c->elem, volume, &db_gain);
if (err < 0)
goto _err; goto _err;
}
err = 0; err = 0;
*value = db_gain; *value = db_gain;
_err: _err: