Date: Wed, 16 Dec 2009 02:00:14 GMT From: Ariff Abdullah <ariff@FreeBSD.org> To: freebsd-multimedia@FreeBSD.org Subject: Re: kern/140453: [sound] No sound inside Virtualbox on 50% volume Message-ID: <200912160200.nBG20EsT050165@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/140453; it has been noted by GNATS. From: Ariff Abdullah <ariff@FreeBSD.org> To: bug-followup@FreeBSD.org, mwisnicki+freebsd@gmail.com Cc: Subject: Re: kern/140453: [sound] No sound inside Virtualbox on 50% volume Date: Wed, 16 Dec 2009 09:57:24 +0800 This is a multi-part message in MIME format. --Multipart=_Wed__16_Dec_2009_09_57_24_+0800_XVlF0XJkEv9TFzl7 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Virtualbox (QEMU too) default to 5bit volume resolution, but it appears through the volume resolution calibration process as 6bit. Clearly, it is a "hardware" bug. Virtualbox doing slightly a better job by "clamping" the results (the lower bits written as '1') whenever there is a write attempt on 5th (or 13th) bit, but _without_ resetting those high bit. As such, it appears as a full 6-bit resolution result on the next codec read. FreeBSD try to be honest here by doing supposed to be correct calibration process and see/measure the result as is. Others <insert whatever..> probably have their own static mapping (think about vendor specific driver) or depends on whatever magic marker, etc. You have two choices: 1) Fix virtualbox ac97 codec emulation (probably not for you given the fact that your vbox runs on Windows). or 2) "Fix" FreeBSD ac97 volume resolution calibration by accepting certain lower bits magic marker, ignoring the high bit. -- Ariff Abdullah FreeBSD ... Recording in stereo is obviously too advanced and confusing for us idiot ***** users :P ........ ... Going with the standard and orthodox is the death of intellect .............. --Multipart=_Wed__16_Dec_2009_09_57_24_+0800_XVlF0XJkEv9TFzl7 Content-Type: text/x-diff; name="vbox-patch-xzz.diff" Content-Disposition: attachment; filename="vbox-patch-xzz.diff" Content-Transfer-Encoding: 7bit --- src/VBox/Devices/Audio/DevIchAc97.cpp.orig 2009-12-16 09:13:05.930459951 +0800 +++ src/VBox/Devices/Audio/DevIchAc97.cpp 2009-12-16 09:18:13.404715106 +0800 @@ -490,23 +490,8 @@ static void set_volume (AC97LinkState *s, int index, audmixerctl_t mt, uint32_t val) { - int mute = (val >> MUTE_SHIFT) & 1; - uint8_t rvol = VOL_MASK - (val & VOL_MASK); - uint8_t lvol = VOL_MASK - ((val >> 8) & VOL_MASK); - rvol = 255 * rvol / VOL_MASK; - lvol = 255 * lvol / VOL_MASK; - -# ifdef SOFT_VOLUME - if (index == AC97_Master_Volume_Mute) - AUD_set_volume_out (s->voice_po, mute, lvol, rvol); - else - AUD_set_volume (mt, &mute, &lvol, &rvol); -# else - AUD_set_volume (mt, &mute, &lvol, &rvol); -# endif - - rvol = VOL_MASK - ((VOL_MASK * rvol) / 255); - lvol = VOL_MASK - ((VOL_MASK * lvol) / 255); + int mute; + uint8_t rvol, lvol; /* * From AC'97 SoundMax Codec AD1981A: "Because AC '97 defines 6-bit volume registers, to @@ -521,6 +506,24 @@ if (val & RT_BIT(13)) val |= RT_BIT(12) | RT_BIT(11) | RT_BIT(10) | RT_BIT(9) | RT_BIT(8); + /* + * 5-bit volume, behave like one. + */ + val &= ~(RT_BIT(5) | RT_BIT(13)); + + mute = (val >> MUTE_SHIFT) & 1; + rvol = (255 * (VOL_MASK - (val & VOL_MASK))) / VOL_MASK; + lvol = (255 * (VOL_MASK - ((val >> 8) & VOL_MASK))) / VOL_MASK; + +# ifdef SOFT_VOLUME + if (index == AC97_Master_Volume_Mute) + AUD_set_volume_out (s->voice_po, mute, lvol, rvol); + else + AUD_set_volume (mt, &mute, &lvol, &rvol); +# else + AUD_set_volume (mt, &mute, &lvol, &rvol); +# endif + mixer_store (s, index, val); } --Multipart=_Wed__16_Dec_2009_09_57_24_+0800_XVlF0XJkEv9TFzl7 Content-Type: text/x-diff; name="ac97_due_to_buggy_codec.diff" Content-Disposition: attachment; filename="ac97_due_to_buggy_codec.diff" Content-Transfer-Encoding: 7bit --- sys/dev/sound/pcm/ac97.c.orig (revision 200510) +++ sys/dev/sound/pcm/ac97.c (working copy) @@ -715,8 +715,27 @@ ac97_initmixer(struct ac97_info *codec) * (ac97 2.3). */ bit = codec->mix[i].bits; - if (bit == 5) - bit++; + if (bit == 5) { + /* + * Test for possible 6bit control by + * turning on 5th (or 13th) and detect + * possible clamped values on the lower + * bits, which might be possible for + * 5bit control. + * + * XXX Emulators (QEMU, Virtualbox, + * etc..) does not reset the + * high bit, making it looks like + * a 6bit control. Consider that + * as "buggy codec". + */ + j = 1 << (5 + codec->mix[i].ofs); + ac97_wrcd(codec, reg, j); + k = ac97_rdcd(codec, reg); + k >>= codec->mix[i].ofs; + if ((k & 0x1f) != 0x1f) + bit++; + } j = ((1 << bit) - 1) << codec->mix[i].ofs; ac97_wrcd(codec, reg, j | (codec->mix[i].mute ? 0x8000 : 0)); --Multipart=_Wed__16_Dec_2009_09_57_24_+0800_XVlF0XJkEv9TFzl7--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200912160200.nBG20EsT050165>