Forums > MaxMSP

How to Logarithmically Scale 0-1 For FFT Analysis?

December 15, 2009 | 6:48 pm

Hi, I am creating a patch that analyzes the power in groups of frequency bins. I approach this by using fftin~ bin index to determine the outlet for a gate~ object, with the power coming from fftin~’s left inlet being routed into this gate. Each of the gate’s outputs leads to a leaky integrator. Right now, there are 16 groups of bins. I would like to be able to include more frequency bins for the higher groups, and less for the lower groups, to try and get an equal spread of power through out these groups. I assume this is possible with log~ but it’s been years since calculus, and i am unsure of what arguments to use or what other alternatives there might be. any help would be much appreciated. thanks.

– Pasted Max Patch, click to expand. –

December 15, 2009 | 7:16 pm

in case i get the situation right (without looking at the patch):

it _should give correct results to perform the scaling in floating
point and then round the result to int again.

/ 1024.
expr log whatever
* 1024.
+ 0.5
i

or as oneliner: [expr int(((log((float($i)/1024),90.))*1024.+0.5))]

just guessing here, cant test it myself now.


December 15, 2009 | 8:17 pm

I think this is more like what you are after:

– Pasted Max Patch, click to expand. –

I imagine you want 0 to 1 to scale it back up to 0 to (n/2-1). In that case, try this one (changes highlighted in red):

– Pasted Max Patch, click to expand. –

NOTE: both of these are not really tested, but as far as I know, the math should work out.


December 15, 2009 | 10:14 pm

thanks for the replies.

roth, your patch seemed to give me a ramp going up to 2.8?

roman, you’re correct in your assumption, the system you put out is what im looking for. But what’s a good log value to use in order to convert a linear ramp (going from 0 – 1) into something that has a greater slope the closer it is to zero, and a lesser slope the closer it is to 1?


December 16, 2009 | 1:08 am

i dont know if you know of have those formulas i use in my "make" abstractions.

they have basic formulas with the (eventually not academic correct) names
"makelog" and "makeexp" and each of them in normal and "reversed" mode.

the reversed modes are just made by reversing the 0. 1. input to the actual
distortion expression.

i only have a runtime here and my webserver is also down.

but i can write it by hand from the max runtime. :)

[110.makelog] :

expr ((exp((($f1-$f2)/($f3-$f2))*log($f4))-1)/($f4-1)*($f3-$f2))+$f2

arguments are:

input, range min, range max (like in a scaling object), and log() operator.

for example 0 1023 20 in your case.

well, and to turn the log function upside down just integrate some
serious "* -1; + 1" into the right place:

expr ((((exp((((($f1-$f1)/($f3-$f2))*-1)+1)*log($f4))-1)/($f4-1)*-1)+1)*($f3-$f2))+$f2

hopefully there is no typo in it …

-110

.


December 16, 2009 | 1:09 am

p.s. you should try "standard" values such as 10, 20, 90 or 100 for your log() and see if you like the curve.


December 16, 2009 | 8:20 am

Another approach would be to use ftom~ to generate a pitch scale, which I understand is what you’re after. First bins need to be converted to frequency.

– Pasted Max Patch, click to expand. –

_
johan


December 16, 2009 | 4:13 pm

Oops, for some reason I thought the default for [log~] was base 2.

Here is a corrected version for 0 to 1:

– Pasted Max Patch, click to expand. –

And to to a log scale for from 0 to n-1 use this one (note I added rounding to this version also):

– Pasted Max Patch, click to expand. –

I like jvkr’s idea too, that may be a little more efficient, but I can’t be sure without taking a closer look.


December 17, 2009 | 12:14 am

thats true, mtof~ and ftom~ could work fine, too.


December 17, 2009 | 8:02 pm

ftom~ is a clever solution, thanks. roth, your patches look good, too. thanks for the help.


Viewing 10 posts - 1 through 10 (of 10 total)