log arguments for gain~

John's icon

I am working on an education patch about gain. I'd like to modify the log increment and scale values of the gain~ object to show various gain ratios/curves/formulae.
Anyone have some hints on how to get started?
I have been trying to create an expr object with arguments that give it the same output as the default gain~ object, but with no success.
An example: how do I limit the number of steps in gain~ to 128 (easy) while limiting the high output [given an input of sig~ 1.] signal to 1.0 (or 0.999999)?
Thanks!

brendan mccloskey's icon

apropos of nothing John...

REALLY intrigued and impressed with your all too brief presentation at imagine/create in Derry two months ago, any links you can share?

Brendan

John's icon

Brendan; you're too kind. Not much to link beyond my site jcrooks.com.
Have a good one!

John's icon
Max Patch
Copy patch and select New From Clipboard in Max.

OK, I almost got expr to emulate the default settings of gain~
The trouble is expr won't give me a zero with a zero input.
Anybody got this? Does it have to do with the approximation of Euler's constant in expr? and, if so, is there a symbol I can use to represent Euler's constant in an expr object?

Roman Thilenius's icon

"The trouble is expr won't give me a zero with a zero input."

it has something to do with the precision, you will always see that
as soon as something like log or exp is involved.

[expr (some formula here)*($f1!=0)] will fix it.

-110

kjg's icon

hey john,

i found this is in the 4.6 manual:
"The gain~ Inspector lets you set four parameters—the Range, the second is
the Base Value, and the Increment. In the following expression that
calculates the output scale factor based on the input value (the same as the
linedrive object), the range is a, the base value is b, the increment is c, the
input is x, e is the base of the natural logarithm (approx. 2.718282) and the
output is y.

y = b e-a log c ex log c

For more information about these parameters, see the linedrive object."

then, using the more complete formula from linedrive reference, y = b e^{-a log c} e^{x log c}, it sort of works.

hth,
klaas-jan

Max Patch
Copy patch and select New From Clipboard in Max.

John's icon

Thanks a lot Roman!
That really worked.
Stay tuned as I try to apply this stuff to gain~ (or some combo of objects) to create various gain algorithms for educational use...

kjg's icon

well, yeah, there is a slight accuracy problem. 0 does not give 0 output, and 128 does not give 1 either.
the limits of 32 bit, i guess.

looking forward to the educational patches!

John's icon
Max Patch
Copy patch and select New From Clipboard in Max.

kjg, I found the linedrive formula also; that's how I did it. Regarding
"0 does not give 0 output, and 128 does not give 1 either.
the limits of 32 bit, i guess."
Roman's fix works, at least here:

kjg's icon

hey john,

yeah, i saw your post after i posted : )
you need 158 instead of 157 for the range, btw, if i am not mistaken.

regarding the $f1!=0, that works to force 0 input to be 0 output, but 128 does still not produce 1 output exactly.
you could hack that too, of course, and it is not a big deal for most uses in the first place.
the error is still noteworthy, imo, especially when you are teaching.

best,
klaas-jan

John's icon

>>the error is still noteworthy, imo, especially when you are teaching.<<
Yes! I will figure out whether discussion of the 32 bit (or whatever) issue is pertinent to this class.
I wonder how cycling74 dealt with this...
By the way, I do not get 1.0 for 128 (even after turning 158 into 157), but maxMSP gets 0.999999, I get 0.999996. That's a small difference.

kjg's icon

i guess the base could be tweaked a little to line up the '1.0' for different ranges. this outputs 1.0 for 128.

expr 7.94322 * pow(2.718282,-158*ln(1.071519)) * pow(2.718282,$i1*ln(1.071519)) * ($i1!=0)

Luke Hall's icon
Max Patch
Copy patch and select New From Clipboard in Max.

Here's the equations I've always used, maybe they'll be useful to you:

John's icon

Thanks Luke, I came up with some similar things but do like how you have the arguments to expr as variables and bang them in; saves time!
Also, mine were using an approximation of the root of the natural log and "pow", yours use "exp;" that's better!

Roman Thilenius's icon

just add single points with comparison operators for more than one "extra" value (i.e. when
zero or nonzero is not enough):

[expr ((some formula here) * (($f1!=0)($f1!=128)) ) + ( 0 * ($f1==0) ) + ( 128 * ($f1==1) )]

read:
if $f1 is not 0 and not 128 then use "some formula", if $f1 is 0 then 0, if $f1 is 128, then 1.

-110

John's icon

Thanks Roman; I'll definitely use that at some point.