[alsa-devel] [PATCH 2/2] tlv: fix returned dB information for min-is-mute controls

Clemens Ladisch clemens at ladisch.de
Fri Oct 15 10:33:20 CEST 2010


For TLV information that indicates that the minimum value is actually
muted, the returned range used the wrong minimum dB value, and
converting dB values to raw control values did not round up correctly
near the minimum.

Signed-off-by: Clemens Ladisch <clemens at ladisch.de>

--- alsa-lib/src/control/tlv.c
+++ alsa-lib/src/control/tlv.c
@@ -167,17 +167,23 @@ int snd_tlv_get_dB_range(unsigned int *t
 	}
 	case SND_CTL_TLVT_DB_SCALE: {
 		int step;
-		*min = (int)tlv[2];
+		if (tlv[3] & 0x10000)
+			*min = SND_CTL_TLV_DB_GAIN_MUTE;
+		else
+			*min = (int)tlv[2];
 		step = (tlv[3] & 0xffff);
-		*max = *min + (long)(step * (rangemax - rangemin));
+		*max = (int)tlv[2] + step * (rangemax - rangemin);
 		return 0;
 	}
 	case SND_CTL_TLVT_DB_MINMAX:
-	case SND_CTL_TLVT_DB_MINMAX_MUTE:
 	case SND_CTL_TLVT_DB_LINEAR:
 		*min = (int)tlv[2];
 		*max = (int)tlv[3];
 		return 0;
+	case SND_CTL_TLVT_DB_MINMAX_MUTE:
+		*min = SND_CTL_TLV_DB_GAIN_MUTE;
+		*max = (int)tlv[3];
+		return 0;
 	}
 	return -EINVAL;
 }
@@ -217,7 +223,7 @@ int snd_tlv_convert_to_dB(unsigned int *
 		min = tlv[2];
 		step = (tlv[3] & 0xffff);
 		mute = (tlv[3] >> 16) & 1;
-		if (mute && volume == rangemin)
+		if (mute && volume <= rangemin)
 			*db_gain = SND_CTL_TLV_DB_GAIN_MUTE;
 		else
 			*db_gain = (volume - rangemin) * step + min;
@@ -327,7 +333,11 @@ int snd_tlv_convert_from_dB(unsigned int
 		step = (tlv[3] & 0xffff);
 		max = min + (int)(step * (rangemax - rangemin));
 		if (db_gain <= min)
-			*value = rangemin;
+			if (db_gain > SND_CTL_TLV_DB_GAIN_MUTE && xdir > 0 &&
+			    (tlv[3] & 0x10000))
+				*value = rangemin + 1;
+			else
+				*value = rangemin;
 		else if (db_gain >= max)
 			*value = rangemax;
 		else {
@@ -345,7 +355,11 @@ int snd_tlv_convert_from_dB(unsigned int
 		min = tlv[2];
 		max = tlv[3];
 		if (db_gain <= min)
-			*value = rangemin;
+			if (db_gain > SND_CTL_TLV_DB_GAIN_MUTE && xdir > 0 &&
+			    tlv[0] == SND_CTL_TLVT_DB_MINMAX_MUTE)
+				*value = rangemin + 1;
+			else
+				*value = rangemin;
 		else if (db_gain >= max)
 			*value = rangemax;
 		else {


More information about the Alsa-devel mailing list