Skip site navigation (1)Skip section navigation (2)
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>