How to Logarithmically Scale 0-1 For FFT Analysis?

ComfortableInClouds's icon

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.

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

Roman Thilenius's icon

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.

Roth's icon

I think this is more like what you are after:

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

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):

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

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

ComfortableInClouds's icon

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?

Roman Thilenius's icon

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

.

Roman Thilenius's icon

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

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

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.

_
johan

Roth's icon

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

Here is a corrected version for 0 to 1:

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

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

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

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

Roman Thilenius's icon

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

ComfortableInClouds's icon

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