- 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