Curvy Volumes

Silly story.

Way back when I first joined the audio team, Steve Ball (the PM for the team) showed up for work one day with his SPL meter.  It seems he'd gone home and used his SPL meter to measure the output of the speakers.  Much to his surprise, the volume curve generated by the volume control wasn't linear.  It was almost worse than that - on some devices it was exponential, on others it was logarithmic.

The problem ended up being buried deep inside the XP audio stack, and was ultimately caused by an impedance mismatch between the various audio APIs.  Some of them expressed volume in 1/65535th of a dB, others expressed volume in unspecified units between 0 and 65535, still others represented volume as unspecified units between 0 and 255.

In this case, the volume control used by the UX was using the mixer APIs, which represented volume as a number between 0 and 65535 (with no indication of scaling).  The audio stack converted that number to a dB value, but it was doing the correction inaccurately, resulting in a logarithmic volume curve - the volume control was very hot (active) at the bottom of the volume scale, but cold (inactive) at the top of the scale - basically you got a lot of volume change at the bottom of the curve, and very little at the top. 

Making matters worse, some audio drivers decided that even though they were being told a specific attenuation value (in dB), they would ignore that value and interpret the dB value as if it represented a linear volume (remember that dB is a logarithmic scale - a 6dB reduction in volume represents a 50% reduction in signal amplitude).  I actually have a set of USB speakers in my office that has an exponential(!) volume curve - it's flat at the bottom and active at the top.

For XP SP2, we added the ability for an OEM to provide a volume curve that can be used to control the curve that was used for the various audio APIs, that helped a great deal.

For Vista, we decided to fix this for once and for all.  First off, we declared the units associated with all of our volume APIs - the stream volume, simple volume, and channel volume all represent volume as a floating point amplitude scalar ranging from 0.0 to 1.0.  Since amplitude scalars map directly to dB (dB=20*log10(scalar), scalar=10^(dB/20)), this essentially means that the stream, simple and channel volumes represent volume in dB.

For the endpoint volume APIs, there are two variants of each of the APIs - there's a dB version which takes input in dB, and there's a "scalar" version which takes a linear floating point value between 0.0 and 1.0[1].  The "scalar" version is intended for applications that want to implement a master volume control because it provides a linear function that maps nicely to a position slider.  The other nice thing about the "scalar" version of the endpoint volume APIs is that it provides a volume taper that gives a linear volume experience for audio devices that correctly handle volume dB. 

You can see the effect of this taper in Vista.  Start the sounds control panel.  On the sounds control panel, select properties on your default playback device, then select the "levels" tab.  Right click on the number in the volume control (the top slider), and select "decibels".  That instructs the volume control to represent the slider position in dB.  Now start the volume mixer.  Go to the master volume and set the slider position to 50% (there's a convenient tick in the slider at that location).  You'll notice that the slider in the speakers properties page is somewhat below the 50% value[2]. 

 

Btw, if you're into audio geeky fun, it can be interesting playing with the volume sliders for various applications seeing if their volume control implements a linear or a logarithmic curve.  Now that I'm aware of the issue, I find it fascinating to see how many applications get this "wrong".

 

[1] For audio geeks out there, yeah, we know this looks stupid - the API indicates that it takes an amplitude scalar but it actually takes a slider position, we know that :(.

[2] This won't work on some machines - if your machine doesn't have a hardware volume control, then you won't have a volume control on the speakers property page (my laptop is a good example of this - it doesn't have a hardware volume control).