At Mon, 19 Jul 2010 10:14:05 +0300, Peter Ujfalusi wrote: > > When converting from dB to raw value, and DB_RANGE is > used with non overlapping map, dB value in between the > sub ranges will be not found. > > For example, if the control has the following: > 0: -10dB > 1: -5dB > 2: 0dB > 3: 2dB > 4: 4dB > > static const unsigned int nonoverlapping_tlv[] = { > TLV_DB_RANGE_HEAD(2), > 0, 2, TLV_DB_SCALE_ITEM(-1000, 500, 0), > 3, 4, TLV_DB_SCALE_ITEM(200, 200, 0), > }; > > Range 1: -10 .. 0dB > Range 2: 2 .. 4dB > > If user asks for 1dB the snd_tlv_convert_from_dB will not find > the raw value, since the 1dB is not part of either range. In the case above, can't you set like TLV_DB_RANGE_HEAD(2), 0, 2, TLV_DB_SCALE_ITEM(-1000, 500, 0), 2, 4, TLV_DB_SCALE_ITEM(0, 200, 0) ?? Takashi > static const unsigned int nonoverlapping_tlv[] = { > TLV_DB_RANGE_HEAD(2), > 0, 2, TLV_DB_SCALE_ITEM(-1000, 500, 0), > 3, 4, TLV_DB_SCALE_ITEM(200, 200, 0), > }; > To fix this, we will store the previous non maching range's > maximum raw value. If the dB value is not found in the next range, > we will check, if the requested dB value is in between the current > and the previous range, and if it is than pick the apropriate raw > value based on the xdir (up or down rounding). > > Signed-off-by: Peter Ujfalusi <peter.ujfalusi@xxxxxxxxx> > --- > src/control/tlv.c | 8 +++++++- > 1 files changed, 7 insertions(+), 1 deletions(-) > > diff --git a/src/control/tlv.c b/src/control/tlv.c > index d09766a..1767118 100644 > --- a/src/control/tlv.c > +++ b/src/control/tlv.c > @@ -285,7 +285,7 @@ int snd_tlv_convert_from_dB(unsigned int *tlv, long rangemin, long rangemax, > { > switch (tlv[0]) { > case SND_CTL_TLVT_DB_RANGE: { > - long dbmin, dbmax; > + long dbmin, dbmax, prev_rangemax; > unsigned int pos, len; > len = int_index(tlv[1]); > if (len > MAX_TLV_RANGE_SIZE) > @@ -298,6 +298,7 @@ int snd_tlv_convert_from_dB(unsigned int *tlv, long rangemin, long rangemax, > return 0; > } > pos = 2; > + prev_rangemax = 0; > while (pos + 4 <= len) { > rangemin = (int)tlv[pos]; > rangemax = (int)tlv[pos + 1]; > @@ -308,6 +309,11 @@ int snd_tlv_convert_from_dB(unsigned int *tlv, long rangemin, long rangemax, > return snd_tlv_convert_from_dB(tlv + pos + 2, > rangemin, rangemax, > db_gain, value, xdir); > + else if (db_gain < dbmin) { > + *value = xdir ? rangemin : prev_rangemax; > + return 0; > + } > + prev_rangemax = rangemax; > pos += int_index(tlv[pos + 3]) + 4; > } > return -EINVAL; > -- > 1.7.1.1 > _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel