Loudness

From Unify Community Wiki
Revision as of 03:26, 9 April 2009 by Jessy (Talk | contribs)

Jump to: navigation, search

Author: Jessy

Description

Unity's standard volume control uses a "linear taper", which does not correspond with human hearing. "Loudness", unlike the Audio Source's "Volume", will yield perceptually equivalent loudness changes for equivalent value changes. (Changing the Loudness from 0.2 to 0.3 will yield a similar difference in loudness between 0.7 to 0.8, etc.)

JavaScript - Loudness.js

<javascript> var loudness : float = 1; private var sqrtOf10 = Mathf.Sqrt(10);

// I would not leave this in Update() for a release. // Put it wherever you need it, to change the volume in-game.

function Update () { audio.volume = Mathf.Pow(sqrtOf10, Mathf.Log(loudness, 2)); } </javascript>

Why this works

To simplify things a bit, a volume control is a multiplier for amplitude of audio waveforms. It makes intuitive sense for a volume control to output...


exactly what is input, for a value of 1,

half of the input, for a value of .5,

one fourth of the input, for a value of .25,

etc.


Unity's volume control does exactly this (see below for exceptions). The problem is that amplitude of a waveform does not correlate directly with human perception of loudness. Loudness perception is complex, but "experimentally it was found that a 10 dB increase in sound level corresponds approximately to a perceived doubling of loudness.". Therefore, it makes sense for a volume control to yield an amplitude that is...


exactly what is input, for a value of 1,

10 decibels below the input, for a value of .5,

20 decibels above the input, for a value of .25,

etc.


Amplitudinal difference, as a multiplicative factor, based on a difference in decibels, can be found with the equation 10^(dB / 20). Inputting the value of 10 dB into this equation results in 10^(10/20), which the sqrtOf10 variable in the code represents.


Raising this value to a base 2 logarithm gives exactly the behavior we want for a volume control.


  • AudioSource.volume only responds to values of 1 or less. There is the potential to easily induce digital distortion if non-clipped waveforms can be amplified, so apparently the choice was made to disallow this. Boosting the level of audio clips can only be done outside Unity at the moment. My conversion script will continue to function properly, above values of 1, if the restriction is ever dropped.
  • Values of less than zero, for either this loudness script, or audio.volume, both equate to multiplying the audio amplitude by zero. It is possible, that if Unity ever allows us the ability to invert the phase of a signal, that negative values could be useful, but this script would not account for that as is. I will update it if necessary, but hopefully, by the time Unity allows for phase inversion, this script will be obsolete.  ;-)
Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox