views:

800

answers:

7

Let's say I have a slider that can go between 0 and 1. The SoundTransform.volume also ranges between 0 (silent) and 1 (full volume), but if I use a linear function, let's say SoundTransform.volume = slider.volume, the result is rather not pleasing.

I really haven't studied the human ear, but I overheard once that human perception is logarithmic, or something similar. What algorithms should I use for setting the SoundTransform.volume?

A: 

I think linear would be the best. At 50, you have 50% of volume, sound logical.

2nd would be sin() : it grows up fast, so at 30 you have ~50% volume, then adjust easily between 50% and 100%, using 70 offset on your slider.

Clement Herreman
The problem with a linear scale is that the human ear is not linear, but logarithmic. So a linear scale seems over sensitive at the low volume levels, and without any noticable effect with small adjustments at high volume levels.
Jan Aagaard
That's the kind of thing really usefull but fairly unknown ! Thank you =)
Clement Herreman
+2  A: 

Yes, human perception is logarithmic. Considering this, you should adjust a volume exponentially, so that the percieved increase becomes linear. See decibel on Wikipedia

Tamás Szelei
+5  A: 

Human hearing is logarithmic, so you want an exponential function (the inverse) to apply to the linear output of your slider. I don't know if human hearing is closer to ln or log:

For Ln:

e^x

For Log:

10^x

You could experiment with other bases too. You will then need to scale your output so that it covers the available range of values.

Update

After a bit of research it seems that base 2 would be appropriate since the power is related to the square of the pressure. If anyone knows better, please correct me.

I think what you want is:

v' = 2^v.a^v - 1
a  = ( 2^(log2(m+1)/n) )/2

v is your linear input value ranging from 0..n v' is your logarithmic value ranging from 0..m

The -1 in the first equation is to give you an output range from 0 instead of 1 (since k^0=1).

The m+1 is to compensate for this so you get 0..m not 0..m+1

You can of course get tweak this to suit your requirements.

Draemon
e^x and 10^x will essentially scale the same way. They are in fact just a constant factor away. Just play with a scaling factor and ignore the base.
ReaperUnreal
They're not a constant factor away: e^x = (e/10)^x . 10^x
Draemon
the idea of bringing in the 2 from the square seems very interesting to me, but the causality seems a little weak ... it would mean, that when a sound source with constant volume moves towards you, with linear speed, the resulting change perceived by you is also linear ... i personally think, i don't perceive it like that, but that may be due to the doppler effect ... also, there are rarely sources with constant volume, in nature, so i don't see, why evolution would chose this particular exponent ... but who knows ^^
back2dos
+6  A: 

human perception in general is logarithmic, also when it comes to things as luminosity, etc. ... this enables us to register small changes to small "input signals" of our environement, or to put it another way: to always percieve a change of a perceivable physical quantity in relation to its value ...

thus, you should modify the volume to grow exponentially, like this:

y = (Math.exp(x)-1)/(Math.E-1)

you can try other bases as well:

y = (Math.pow(base,x)-1)/(base-1)

the bigger the value of base is, the stronger the effect, the slower volume starts growing in the beginning and the faster it grows in the end ...

a slighty simpler approach, giving you similar results (you are only in the interval between 0 and 1, so approximations are quite simple, actually), is to exponantiate the original value, as

y = Math.pow(x, exp);

for exp bigger than 1, the effect is, that the output (i.e. the volume in you case) first goes up slower, and then faster towards the end ... this is very similar to exponential functions ... the bigger exp, the stronger the effect ...

back2dos
+3  A: 

Hearing is complicated, the perceived loudness varies according to frequency, the duration of the sample, and from person to person. So this cannot be solved mathematically but by trying a variety of functions for the control and picking the one which 'feels' the best.

Do you find at the moment that varying the control at the low end of the range has little effect on the apparent volume, but that the volume increases rapidly at the upper end of the range? Or do you hear the reverse, the volume varies too quickly at the low end and not enough at the high end? Or would you like finer control over the volume at medium levels?

Increased low-volume sensitivity:

SoundTransform.volume = Math.sin(x * Math.PI / 2);

Increased high-volume sensitivity:

SoundTransform.volume = (Math.pow(base,x) - 1)/(base-1);

or

SoundTransform.volume = Math.pow(x, base);

Where base > 1, try different values and see how it feels. Or more drastically, a 90 degree circular arc:

SoundTransform.volume = 1 - Math.sqrt(1-(x * x));

Where x is slider.volume and is between 0 and 1.

Please do let us know how you get on!

Matt Howells
A: 

The human ear indeed perceives sounds on a logarithmic scale of increasing intensity, and because of that, the unit generally used to measure acoustic intensity is the decibel (which is actually used for all sorts of intensities and powers, not just those of sound, and also happens to be a dimensionless unit). The reference level, 0 dB, is usually set to the lower bound of human hearing, and every ten-decibel increase above that is equivalent to an increase in power by a factor of 10.

Note, however, that you should first check with other people and see what they think, just in case; what sounds odd to you may not sound odd to others. If they agree with you, then go right ahead and do it exponentially, but if you're in the minority, then it might just be your own ears that are the problem.

EDIT: Ignore my previous third paragraph. Refer to back2dos's answer if you decide to do it exponentially.

JAB
There are many types of function where f(0) = 0 and f(1) = 1.
Matt Howells
Indeed, and if I had actually worked it out then (using f(x) = a * 10^x - b, with f(0) = 0 and f(1) = 1), I would have realized that. Instead I was careless and didn't even try calculating it out.
JAB
+1  A: 

A 3db increase means you are doubling the volume, but the human ear requires ~6db increase to perceive a doubling in volume.

However, a strictly logarithmic curve, while accurately modeling the human perception of volume, has a usability problem.

When people want a loud volume, the knob becomes too sensitive at the upper end, making it difficult to find the "right" volume.

You've probably had this problem before... 7 is too soft, 8 is too loud, meanwhile 1-3 are inaudible over background noise.

So, I recommend a logarithmic scale, but with a floor at the low end and a soft knee at the top to allow a more linear response, especially in the "loud" part of the knob.

Oh, and make sure the knob goes up to 11. ;)

richardtallent