I need to be able to convert a value within a given range to an exponential value within the same range. I made an abstraction "autoscale" which remap the highest and lowest received values to a given range.

If incoming is 0.3 and the lowest value so far been 0.2, the highest so far has been 1.2, and the range is set to 3 and 7 the output will be 4.

I would like to be able modify the output value to an exponential or logarithmic curve where you can set the curve steepness.

What options would there be to solve this? Could I have a function within an expression object? Or use an array? Please show me.

Once I got that going I need to be able to set the curve so that a given value will end up as the exact half of the scaled range. Using the values in the example above incoming value 0.3 should then output 5 after the exponential curve has been set.

Cheers!

]]>I need to be able to convert a value within a given range to an exponential value within the same range. I made an abstraction "autoscale" which remap the highest and lowest received values to a given range.

If incoming is 0.3 and the lowest value so far been 0.2, the highest so far has been 1.2, and the range is set to 3 and 7 the output will be 4.

I would like to be able modify the output value to an exponential or logarithmic curve where you can set the curve steepness.

What options would there be to solve this? Could I have a function within an expression object? Or use an array? Please show me.

Once I got that going I need to be able to set the curve so that a given value will end up as the exact half of the scaled range. Using the values in the example above incoming value 0.3 should then output 5 after the exponential curve has been set.

Cheers!

]]>Edit; I went ahead and fixed it up a bit. Here it is without the input timing stuff. Just send it a message of target value, duration and a power 0.5 for log, 2 for expo and anything between or further to the extreme for steeper or gentler curves. [1 1000 2( would give an expo curve ramping too 1 over 1 second. Remembered that I did not use [vline~] because still need to time the curve value and scaling.

curver~.pd

Edit, fixed some silliness, probably still some more in there.

I would like to be able modify the output value to an exponential or logarithmic curve where you can set the curve steepness.

[pow] needs an incoming range between 0 and 1 for this.

You could cascade mapping/scaling:

input

map from input range to 0 till 1

[pow]

map from 0 till 1 to output range

output

Or use an array?

Would be similar:

draw an array with a transfer-function

input

map to x-size of array

[tabread4]

map from y-range

output

You have a base value. This could be one end of the range, or the center of the range.

You have some input data -- could be LFO, envelope, or external data.

Normalize the input -- if the base value is the end of the output range, then your normalized input would be 0 .. 1. If it's the center, then the normalized input is -1 .. +1.

Then *linear* mapping is `base + ((range_end - base) * normalized_value)`

. I write it in this order because... then...

Exponential ("log") mapping only promotes the operators up one level: `base * ((range_end / base) ** normalized_value)`

where `**`

is "pow" in Pd. (Note that range_end / base needs to be positive and nonzero.)

You can translate from any input range to any output range this way.

For variable-curvature mapping, I translated the formula from SuperCollider in my abstraction library, the [lincurve] and [lincurve~] objects.

hjh

]]>I would actually prefer to just use the equation inside an expression object

Without testing, I believe the SC lincurve formula could be written into expr as:

```
if(abs($f6) < 0.001, ($f1 - $f2) / ($f3 - $f2) * ($f5 - $f4) + $f4, $f4 + (($f5 - $f4) / (1.0 - exp($f6))) - ((($f5 - $f4) / (1.0 - exp($f6))) * pow(exp($f6), ($f1 - $f2) / ($f3 - $f2))))
```

Where:

$f1 = input

$f2 = input lower bound

$f3 = input upper bound

$f4 = output lower bound

$f5 = output upper bound

$f6 = curve

YMMV.

hjh

]]>1.) map it down to range 0-1,

2.) for log, do log(($f1)* ($f2-1)+1)/log($f2)

3.) then map it back to its original range.

for exp, use (exp($f1*log($f2))-1)/($f2-1),

to turn the curve upside down, invert the range to 1-0 and so on.

]]>