From nobody@FreeBSD.org  Tue Nov 10 21:10:42 2009
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 857331065670
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 10 Nov 2009 21:10:42 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 6A8F38FC1F
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 10 Nov 2009 21:10:42 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id nAALAgBq019995
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 10 Nov 2009 21:10:42 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id nAALAfRP019954;
	Tue, 10 Nov 2009 21:10:42 GMT
	(envelope-from nobody)
Message-Id: <200911102110.nAALAfRP019954@www.freebsd.org>
Date: Tue, 10 Nov 2009 21:10:42 GMT
From: Marcin Wisnicki <mwisnicki+freebsd@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [sound] No sound inside Virtualbox on 50% volume
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         140453
>Category:       kern
>Synopsis:       [sound] [vbox] No sound inside Virtualbox on 50% volume
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    vbox
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Nov 10 21:20:01 UTC 2009
>Closed-Date:    
>Last-Modified:  Sun Oct 16 22:58:44 UTC 2011
>Originator:     Marcin Wisnicki
>Release:        8.0-RC2
>Organization:
>Environment:
FreeBSD vm2.pnet.one.pl 8.0-RC2 FreeBSD 8.0-RC2 #0: Sun Oct 25 08:55:51 UTC 2009     root@almeida.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  i386
>Description:
Using VirtualBox 3.0.8 on WindowsXP I don't have the sound in the FreeBSD
guest on default volume of 50. Changing it to 49 or 100 gives maximum volume.
Turns out it wraps on 50 - ie. any $vol>49 is the same as $vol-50.
Similar thing occurs on "pcm" control.

# sysctl hw.snd.verbose=4
# cat /dev/sndstat
FreeBSD Audio Driver (newpcm: 32bit 2009061500/i386)
Installed devices:
pcm0: <Intel ICH (82801AA)> at io 0xd100, 0xd200 irq 9 bufsz 16384 kld snd_ich [MPSAFE] (1p:3v/1r:1v channels duplex default)
        snddev flags=0x2e2<AUTOVCHAN,BUSY,MPSAFE,REGISTERED,VPC>
        [pcm0:play:dsp0.p0]: spd 48000, fmt 0x00200010, flags 0x00002100, 0x00000004
        interrupts 5309, underruns 0, feed 5309, ready 0 [b:4096/2048/2|bs:4096/2048/2]
        channel flags=0x2100<BUSY,HAS_VCHAN>
        {userland} -> feeder_mixer(0x00200010) -> {hardware}
        pcm0:play:dsp0.p0[pcm0:virtual:dsp0.vp0]: spd 8000/48000, fmt 0x00100008/0x00200010, flags 0x10000000, 0x0000006b
        interrupts 0, underruns 0, feed 0, ready 0 [b:0/0/0|bs:4096/128/32]
        channel flags=0x10000000<VIRTUAL>
        {userland} -> feeder_root(0x00100008) -> feeder_format(0x00100008 -> 0x00100010) -> feeder_rate(0x00100010 q:1 8000 -> 48000) -> feeder_matrix(1.0 -> 2.0) -> feeder_volume(0x00200010) -> {hardware}
        pcm0:play:dsp0.p0[pcm0:virtual:dsp0.vp1]: spd 8000/48000, fmt 0x00100008/0x00200010, flags 0x10000000, 0x0000006b
        interrupts 0, underruns 0, feed 0, ready 0 [b:0/0/0|bs:4096/128/32]
        channel flags=0x10000000<VIRTUAL>
        {userland} -> feeder_root(0x00100008) -> feeder_format(0x00100008 -> 0x00100010) -> feeder_rate(0x00100010 q:1 8000 -> 48000) -> feeder_matrix(1.0 -> 2.0) -> feeder_volume(0x00200010) -> {hardware}
        pcm0:play:dsp0.p0[pcm0:virtual:dsp0.vp2]: spd 44100/48000, fmt 0x00200010, flags 0x10000000, 0x00000029
        interrupts 0, underruns 0, feed 0, ready 0 [b:0/0/0|bs:65536/2048/32]
        channel flags=0x10000000<VIRTUAL>
        {userland} -> feeder_root(0x00200010) -> feeder_volume(0x00200010) -> feeder_rate(0x00200010 q:1 44100 -> 48000) -> {hardware}
        [pcm0:record:dsp0.r0]: spd 48000, fmt 0x00200010, flags 0x00002100, 0x00000005
        interrupts 0, overruns 0, feed 0, hfree 4096, sfree 4096 [b:4096/2048/2|bs:4096/2048/2]
        channel flags=0x2100<BUSY,HAS_VCHAN>
        {hardware} -> feeder_root(0x00200010) -> feeder_mixer(0x00200010) -> {userland}
        pcm0:record:dsp0.r0[pcm0:virtual:dsp0.vr0]: spd 44100/48000, fmt 0x00200010, flags 0x10000000, 0x00000029
        interrupts 0, overruns 0, feed 0, hfree 0, sfree 65536 [b:0/0/0|bs:65536/2048/32]
        channel flags=0x10000000<VIRTUAL>
        {hardware} -> feeder_root(0x00200010) -> feeder_rate(0x00200010 q:1 48000 -> 44100) -> feeder_volume(0x00200010) -> {userland}

>How-To-Repeat:
1. install VirtualBox 3.0.8
2. install FreeBSD 8.0-RC2 i386 as guest
3. kldload snd_ich
4. mixer pcm 50 (default)
5. try playing something
>Fix:
Adjust volume to 100.

>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-multimedia 
Responsible-Changed-By: remko 
Responsible-Changed-When: Wed Nov 11 08:42:46 UTC 2009 
Responsible-Changed-Why:  
reassign to multimedia team 

http://www.freebsd.org/cgi/query-pr.cgi?pr=140453 

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--

From: Marcin Wisnicki <mwisnicki+freebsd@gmail.com>
To: Ariff Abdullah <ariff@freebsd.org>
Cc: bug-followup@freebsd.org
Subject: Re: kern/140453: [sound] No sound inside Virtualbox on 50% volume
Date: Wed, 16 Dec 2009 17:03:12 +0100

 On Wed, Dec 16, 2009 at 02:57, Ariff Abdullah <ariff@freebsd.org> wrote:
 > 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).
 >
 
 Good to hear it's a known problem. Is there any reason why this patch
 was not submitted to virtualbox (at least I couldn't find a ticket
 there) ?
 I don't really care about it since workaround is so simple, but it
 would be nice to have it working correctly out of the box.
 
 > or
 >
 > 2) "Fix" FreeBSD ac97 volume resolution calibration by
 >   accepting certain lower bits magic marker, ignoring the high bit.
 >
 >
Responsible-Changed-From-To: freebsd-multimedia->vbox 
Responsible-Changed-By: eadler 
Responsible-Changed-When: Sun Oct 16 22:58:23 UTC 2011 
Responsible-Changed-Why:  
over to (correct) maintainer 

http://www.freebsd.org/cgi/query-pr.cgi?pr=140453 
>Unformatted:
