I am designing a VST Audio plug-in that requires amplitude data be extracted from the incoming signal to be used for velocity settings in the midi domain.
Essentially, I will be receiving values between 0-1(float) and need to convert them to 0-127 int.
Currently the process will be to multply the float value by 100 to give a whole value of +3 decimal places i.e. 103.4567685 OR 005.6778787282
From here I will then round the floats to ints using the floor() function.
However, this will leave me with value开发者_如何学JAVAs between 0-100; however, I need to scale these to 0-127.
Any suggestions on how this could be made possible would be greatly appreciated.
The proper way to do this is:
int amplitude = 128 * value ;
if (amplitude == 128) amplitude = 127 ;
Range conversion is not that simple. In the case of scaling an integer range [-n; n] to float, using the naive approach of simply multiplying has the effect, that the inverse mapping will likely not map into the original values. Say you've got the set of all numbers in the integer range, and a set of same magnitude in the floating point range, the naive mapping is not bijective.
There's a nice paper about this and example code, for how to implement monotony and ordering preserving mappings at http://kaba.hilvi.org/programming/range/index.htm
Just multiply your value by 127 and cast it to int
. [0,1]*127 => [0,127]
If you take some of the suggestions presented here and multiply by 127, you're going to find that 127 is not very well represented in your output. Maybe this won't be a problem for you, but there's a small change that makes a big difference.
You might think that rounding would help, but it does not. The number of values at 127 will still be only half that of the other values, and now the number of values at 0 will also be half of the average.
The correct formula:
int amplitude = static_cast<int>(value * (128-epsilon)); // where epsilon is a very small floating point value
I think I must be missing something. why not multiply by 127.0 instead of 100?
I use this effective workaround to cover all the values with the help of the round() function.
output = round (ampiezza * 127.5 + 127.5)
ampiezza is a signed float ranging from -1 to +1 output is an 8 bit integer
output range is from 0 to 255 centered between 127 and 128
Hope this can be helpful.
Multiply the resulting value by 1.27 before using floor()
?
精彩评论