Mapping float value to frequency (Hz) or dB

Hello all!

I've been scouring the forums for an answer to this and have stumbled across a few threads mentioning mapping a range to a value but I haven't been successful so far, especially since most answers regard converting values mathematically, which means that I'd have to come up with a new formula for mapping the main bands to 20-20 000, faders to -96-+10 etc.

Case 1: Parametric EQ.

I've got a knob widget with id HPF that is successfully sending and receiving float values to my X32 console's high pass filter frequency. I would now like to create a text widget (id HPF-f) that takes the 0 to 1 float from HPF and maps it so that the text widget displays a value between 20 and 400 Hz, which are the limits in the console.

bild

What code would I need to introduce to map these values? Also, why isn't the text widget displaying the returned value?

Case 2: Fader dB values
I'm fairly certain that this would be answered by a combination of case 1 and the use of the logScale function.

Thanks for this amazing software!

Your JS{{}} block should go in the value property. The script property works differently.

What code would I need to introduce to map these values

Well that really depends on how the X32 maps the value on its side, if the mapping is linear it would look like this:

JS{{
return 20 + @{HPF} * 380 
}}

If it's logarithmic you'll need to use some Math functions.

Case 2: Fader dB values
I'm fairly certain that this would be answered by a combination of case 1 and the use of the logScale function.

The logScale property only change how the values are distributed on the fader's scale, but it won't apply any conversion on the output value.

From the X32 wiki:

The Range, level has 4 ‘linear’ dB ranges:
0.0…0.0625 (-oo, -90…-60 dB),
0.0625…0.25 (-60…-30 dB),
0.25…0.5 (-30…-10dB)
0.5…0.1 (-10…+10dB)

If you just need the fader's scale to be displayed, setting its pips to true and range property as follows wil do: (logScale should be set to false)

{
  "0%": { "-90dB": 0 },
  "12.5%": { "-60dB": 0.0625 },
  "25%": { "-30dB": 0.25 },
  "50%": { "-10dB": 0.5 },
  "75%": { "0dB": 0.75 },
  "100%": { "10dB": 1 }
}

This way the fader will still send values between 0 and 1 but will display the appropriate scale.

1 Like

Oh, @jean-emmanuel, you glorious human being!

I've been working with the wiki's reference document a lot and have thus far had immense success, although a lot of the widgets being created are modified via regex instead of the cloning examples you posted.

I wasn't aware that JS{{}} could go in other properties. Is it possible to do this in OSC addressing as well?

It goes in any property other than script actually :slight_smile:

Well that just shows me, then :slight_smile: .

I found this concerning frequency float conversions on the wiki.

Should I do the same thing as you mentioned regarding fader values for this?

Edit: I mean that my ranges are off, ie. frequency displayed in OStageC != frequency in the X32 EQ

Found a typo, 0.625 should be 0.0625. Resulted in some funny fader movements ^^

{
  "0%": { "-90dB": 0 },
  "12.5%": { "-60dB": 0.0625 },
  "25%": { "-30dB": 0.25 },
  "50%": { "-10dB": 0.5 },
  "75%": { "0dB": 0.75 },
  "100%": { "10dB": 1 }
}

Thanks I edited my post.

Here is the conversion corresponding to that table:

JS{{
return Math.exp(Math.log(20) + (Math.log(20000)-Math.log(20)) * @{fader_id})
}}
2 Likes

You are amazing!

Not trying to go off topic in the same post, but the conversion tables found here concern many more parameters than frequency (see below). I'd like to understand how to create conversions like the one you posted (instead of pestering you and others like a child with a new math problem by the same method that they've obviously not understood).

The X32 documentation mentions these 101, 161, etc. numbers as reference in what parameter maps its values to a given float number, so using these values correctly is critical to give accurate numbers on the control surface.








Well it's actually a "common" math formula, here is a JS implementation example. To make it short this would work for all the tables you posted except the last one:

var out_val = Math.exp(Math.log(out_min) + (Math.log(out_max)-Math.log(out_min)) * in_val)

The last table is not a log scale, as pointed out in the wiki it's a pseudo log scale made of 4 linear segments. That's trickier to implement:

var out_val,
    range_in = [],
    range_out = []

// define ranges depending on input value
if (in_val < 0.0625) {
    range_in = [0,0.0625]
    range_out = [-90,-60]
} else if (in_val < 0.25) {
    range_in = [0.0625,0.25]
    range_out = [-60,-30]
} else if (in_val < 0.5) {
    range_in = [0.25,0.5]
    range_out = [-30,-10]
} else if (in_val < 1) {
    range_in = [0.5,1]
    range_out = [-10,10]
}

// normalize to input range
out_val = (in_val - range_in[0]) / (range_in[1] - range_in[0])

// scale to output range
out_val = out_val * (range_out[1] - range_out[0]) + range_out[0]
1 Like

I appreciate the time and effort to teach. :slight_smile:

Here's the formula I ended up with to avoid floating decimals.
bild

Thanks for this example i have something similar to calculate, unfortunatly this did not work for me.

The values: (output 0.0 to 50, for a value range from 0 16383).

0 -> 0
0.1 -> 254
0.5 -> 1270
1.0 -> 2540
1.2 -> 3048
3.0 -> 6350
7.3 -> 9525
17.9 -> 12700
43.2 -> 25875
50.0 -> 16383

The approach here would be splitting in into several ranges to get close with the formula (and in_val to max 1), but no good results until now. Any thoughts & hints on this ?

Thanks!

Did you follow the link I gave ? There a detailed explanation there. The formula I gave doesn't work for you because your input range is different, you just need to divide the input value by 16383 before applying the formula.

Yeah, i exactly tried that(this is not a freq. related conversion, i got not close enough) -> will have to dig into that again. Thanks!

Actually the logscale formula won't work for you since (since Math.log(0) = -Infinity). The numbers you gave show that the scale is somewhat pseudo-logarithmic anyway (made of linear segments), you should be able to mimic it using the other example I gave.

Look at this post.

i got close till 8.0(linear), but above that it does not seem to work. I maybe need the log function above that(or need to use more after comma digits, 3 so far)