- Home /
how to normalize a value to a range between 0 and 1
Hi - I'm doing an audio experiment where recording the sound coming out of my speakers gives me a number between around 0 and 20. I want to convert this number to something between 0 and 1, so that I can translate the volume level gets translated to the scale of an object. How do I do this? My basic setup is:
 var audioVal:float = audio.GetOutPutData(...); //gives the audio in decibels
 var scaleVal:float; //this value will give a scale between 0 and 1;
 scaleVal = Mathf.Clamp(audioVal,0,1); //this doesn't seem to work. The value always ends up being at the maximum or minimum end of the scale.
Answer by Eric5h5 · Jun 27, 2012 at 07:25 PM
Just divide by 20, or you can use Mathf.InverseLerp for arbitrary ranges. Clamp won't work because it just clamps numbers, it doesn't try to scale anything.
http://answers.unity3d.com/questions/1012209/algorithm-help.html
Similar question, answered with Clamp.
Answer by hideouswill · Jun 27, 2012 at 08:40 PM
Mathf.Clamp() does not scale a value; it restricts the value to the range. For example, if you clamp between (0, 1), any value greater than 1 will yield a clamped value of 1, and any value less than zero will yield zero; for a value inside the clamp range, the value will be unchanged.
To scale, you need to divide your raw value by the total range, and account for an offset if min != 0. For a range of (min, max):
 scaledValue = (rawValue - min) / (max - min);
For the common case where min == 0:
 scaledValue = rawValue / max;
In a case where max could be theoretically infinite, should I just use an arbitrary big number as a max value?
@TechSupportInco$$anonymous$$g1:
It makes no sense to map an unbounded value to a bounded range. If "1.0" should represent infinity and "0.0" represent "0", then all values would mathematically map to "0.0".
Think about a real world example: temperature. The temperature has a lower bound of 0 kelvin (-273.15 °C) but is unbounded at the top. Why would you want to map an arbitrary temperature into the range of [0.0, 1.0]. All commonly used temperatures would be zero or extremely close to zero. So even temperatures around 1 million kelvin would result to be almost 0.
In such cases you might use a non linear mapping like (1/x) or log():
 v1 = 1f - 1f / (1f+t);
That's the mapping of the first values:
 t       v1        v2
 -----------------------------
 0       0         0
 1       0.5       0.00990
 2       0.66666   0.01960
 3       0.75      0.02912
 4       0.8       0.03846
 5       0.83333   0,04761
 6       0.85714   0.05660
 42      0.97674   0.29577
 100     0.99009   0.5
 333     0.99699   0.76905
 1234    0.99919   0.92503
 +inf    1.0       1.0
As you can see the values between 0 - 1 are mapped to 0-0.5 and the values between 1 - infinity is mapped to 0.5-1.0. If you need a better resolution for values around 100 you can either divide t by 100 beforehead or use 100f ins$$anonymous$$d of 1f:
 v2 = 1f - 100f / (100f+t)
This will make 100 to map to 0.5
Here's a google link to that formula. You should see a graph at the top. make sure you zoom appropriately.
It makes no sense to map an unbounded value to a bounded range
(You might need to in a shader)
@Bunny83 thanks for the elaborate and scientific answer :)
Answer by AnotherYeti · Jun 27, 2012 at 08:40 PM
If the range you're getting is exactly between 0 and 20, then replace your third line with:
 scaleVal = audioVal / 20.0;
The code you're using isn't working because Mathf.Clamp merely restricts values to the range given, rather than doing a transformation from one space to another.
Answer by Split3 · Aug 12, 2019 at 04:32 PM
Just in case you want to stop at some point, this code works just perfectly for that!!!
 var scaledValue = Mathf.Clamp(value / maxValue, minValue, maxValue);
Enjoy
This makes no sense. Since "value" is supposed between $$anonymous$$Value and maxValue, dividing value by maxValue gives you a range of 0-1. Clamping that range between $$anonymous$$ and max makes no sense. Also your lower bound would be wrong. You don't seem to be interested in a 0-1 range but in a $$anonymous$$Value to maxValue range which was not asked in the question. Scaling by maxValue makes no sense at all. There are cases where something like this is wanted:
 $$anonymous$$athf.Clamp(value * scale, $$anonymous$$Value, maxValue);
where scale controls the scaling and clamp just limits the outcome to a certain range. However as I said this has nothing to do with the question that was asked.
Your answer
 
 
             Follow this Question
Related Questions
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
Clarification on how RangeAttribute works 1 Answer
A problem with intersection detection 1 Answer
getting a sum from two scripts 1 Answer
On Button press Move Value toward 2 Answers
 koobas.hobune.stream
koobas.hobune.stream 
                       
               
 
			 
                