[Added Colin to Cc]
At Thu, 21 Oct 2010 16:29:17 -0400, Valdis.Kletnieks@vt.edu wrote:
On Thu, 21 Oct 2010 21:40:08 +0200, Takashi Iwai said:
commit de8c85f7840e5e29629de95f5af24297fb325e0b ALSA: HDA: Sigmatel: work around incorrect master muting
Reverting this one helps.
The latter one?
Yeah. Otherwise I would write it to the former :).
Confirming - reverting that one commit fixes sound on my Dell laptop as well.
This might be a user-space issue, then.
That would be icky, if we have to lockstep a 2.6.37 kernel upgrade to an alsa-lib upgrade. Stuff like udev and perf having to lockstep is bad enough...
Yeah, if this is really the culprit, we should think of reverting the commit, at least until the use-space fix is more populated.
Could you try once the latest alsa-lib? If you are using SUSE packages, the snapshot rpms are available on OBS multimedia:audio:snapshot/alsa repo. (The version number of the package is still 1.0.22, but don't care; I just forgot to change the spec file.
Hmm... on my laptop, Fedora Rawhide is showing:
% rpm -qi alsa-lib Name : alsa-lib Relocations: (not relocatable) Version : 1.0.23 Vendor: Fedora Project Release : 1.fc14 Build Date: Fri 16 Apr 2010 07:48:17 AM EDT Install Date: Sun 18 Apr 2010 03:22:04 PM EDT Build Host: x86-02.phx2.fedoraproject.org Group : System Environment/Libraries Source RPM: alsa-lib-1.0.23-1.fc14.src.rpm Size : 1188301 License: LGPLv2+ Signature : (none) Packager : Fedora Project URL : http://www.alsa-project.org/ Summary : The Advanced Linux Sound Architecture (ALSA) library Description : The Advanced Linux Sound Architecture (ALSA) provides audio and MIDI functionality to the Linux operating system.
Is that "recent enough", or do I need to find something newer?
Well, this doesn't tell much... The fix patch for alsa-lib is pretty recent. Attached below.
thanks,
Takashi
--- commit 2f6206da0c1ff88235e6eca0077343f22a4b43ee Author: Clemens Ladisch clemens@ladisch.de Date: Fri Oct 15 10:33:20 2010 +0200
tlv: fix returned dB information for min-is-mute controls
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@ladisch.de Signed-off-by: Takashi Iwai tiwai@suse.de
diff --git a/src/control/tlv.c b/src/control/tlv.c index ba52752..f7c9976 100644 --- a/src/control/tlv.c +++ b/src/control/tlv.c @@ -167,17 +167,23 @@ int snd_tlv_get_dB_range(unsigned int *tlv, long rangemin, long rangemax, } 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 *tlv, long rangemin, long rangemax, 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 *tlv, long rangemin, long rangemax, 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 *tlv, long rangemin, long rangemax, 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 {