Developers, fix your volume sliders!

Weighing in as an audio engineer, the guy is indeed correct that volume scales are far easier to control logarithmically, others are correct that it's because human perception of loudness is logarithmic.

Let's have a look at it in some better detail:

Decibels are a measure of a logarithmic change of 10 times base 10. What does this mean? It means that for an increase of x db (say, 10) you divide x by 10 (which for 10 is 1) and then take 10 to the power of this number (10 ^ 1 = 10). This means that we can then multiply our quantity by 10, knowing it is a change of 10db.

This is a relative scale. If we increased by 10db again, we would have done a total increase of 20db, but actually increased the value by a factor of 100.

When working with audio, we use Decibels to measure the change in power. This means the actual amount of electrical power (Watts). If I have an amp and speaker playing a 1W sound signal, and then increase it to 100W, that will be an increase of 20db.

This is great for power, but power and amplitude are different things. Amplitude is the height of the peaks and troughs of a wave, whereas power is the area under a wave. The power is the amplitude squared: P = A2 . Therefore an increase of 10 times (10db) in power would only be an increase of sqr(10) times in amplitude (approximately 3.16 times). An increase of 20db would mean 10 times the amplitude.

When working with digital sound, we are looking at digitally represented amplitude samples of a wave. Each sample is a fixed distance apart and measures the height of the wave at that point. This means that a computer is working with amplitude and not power. Game engine code reflects this, and it means that the number we plug into our volume control for the sound API (normally a float from 0 to 1) represents our amplitude gain.

There is, however, a third and different useful quantity that isn't physical: perceived loudness (it's a psychoacoustic thing if you like buzzwords.) The best rule to describe this is that an increase of 10db to power will double perceived loudness. 20db would double loudness twice, meaning it would sound 4 times as loud. We can assume from this that, like the relationship between power and amplitude, amplitude and loudness are related by a square law (an increase of 10db to power would multiply loudness by 1.995, sounds close enough).

So what does this mean for our volume slider? Well ideally a volume slider would sound half as loud at the halfway position, right? Unfortunately, if you just plug the slider 0-1 float into Sound.Volume(), you won't get this result. Halving the amplitude will only divide the loudness by sqr(2) (1.41...) and you'll end up with something that sounds just louder than 2/3 of the original signal. For a human, it sounds wrong.

How can we fix this? Just square the slider value. Remember how we assume that amplitude and loudness are related by a square law? A = L2 . In this case, our L is our slider value (the loudness that the listener wants) and A is the input of our game engine.

tl;dr; the actual fix is to just square the slider value.

Except it doesn't end there. You can actually go one further and use a completely logarithmic scale for loudness too. This way the perceived loudness change is absolutely independent of the position of the slider. This is very useful as it offers the same level of fidelity all the way across the slider however it will sound very weird in most applications as it completely defies user expectations. I'm not going to go into the maths of that one right now.

/r/gamedev Thread