I have a low pass and high pass filter in my program and i have a problem where it is hard to accurately filter lower and mid frequencies. As 10KHz is halfway it means most of the filter is just occurring on the treble. I have noticed in many eq’s (shown below) 10khz is near the end with greater ranges at the lower frequencies. How do I recreate this in my IIR filters as i am currently just using the raw value from the slider.

to get a nice “linear” sounding feel to my filter frequency control I used this :

```
auto freqHz = std::pow(2.71828182846, (frequencyKnob * 5.0) + 4.0);
```

where `frequencyKnob`

value ranges between 0 and 1.

It’s using the “natural logarithm” *e* (2.718…etc), you might want to tweak the `* 5.0`

and `+ 4.0`

to your liking (the multiplier controls the range, the addition controls the offset from 0 Hz, iirc I played about feeding it whitenoise and looking at the results in an analyser to just *see* how it was responding, as I couldn’t be bothered to fully understand the mathematics behind it in order to *know* how it would respond! I really ought not to be so lazy!)

edit: pretty obvious I’ve no idea about the mathematics, or at least misunderstood what *e* is

```
// start - start frequency (typically 20Hz)
// end - end frequency (typically 20000Hz)
// perc - proportion from start to end (range 0 - 1)
float logspace(float start, float end, float prop)
{
return start * std::powf(end / start, prop);
}
```

This spaces powers of ten evenly so there’s an equal step between 20-200, 200-2000, etc. With this function, 10’000Hz is placed ~90% along the logarithmic scale.

```
DBG(logspace(20.f, 20000.f, 0.f)); // 20
DBG(logpsace(20.f, 20000.f, 0.33f)); // ~200
DBG(logspace(20.f, 20000.f, 0.67f)); // ~2000
DBG(logspace(20.f, 20000.f, 1.f)); // 20000
DBG(logpsace(20.f, 20000.f, 0.9f)); // 10000
```

sorry for the late reply, the algorithm worked fine with some changes, this is the code i have to display and read exact values,

some reason

lpKnob->valueFromTextFunction = (const String &text)

{

auto freq = text.removeCharacters(“Hz”).getDoubleValue();

return std::pow(2.71828182846, (1 / ((freq - 4) / 5.903487553f)));

};

lpKnob->textFromValueFunction = (double value)

{

double freq = (value);

return (juce::String(std::pow(2.71828182846, (freq * 5.903487553f) + 4)) + “Hz”);

};

log(2.7182818…)=1, so just use exp(value). It’s going to be faster.

pow(t, p) = exp(p * log(t))

im really not sure how to implement that, whenever i chose a value it either sets it to 20000hz (1) or crashes the program. i want a way to reverse the function (below) for when i type a value it is one between 0 and 1

converting from 0-1 to 0hz-20000hz

return (juce::String(std::pow(2.71828182846, (freq * 5.903487553f) + 4)) + “Hz”);

return (juce::String(std::exp(freq * 5.903487553f + 4)) + “Hz”);

dont think thats entirely correct, prehaps its something wrong on my side but 5 returns 272.99

It is, or you need to show what you mean by not correct:

```
exp(5)
148.4131591025766
pow(2.72, 5)
148.88279736320004
```

i got a perfect formula worked out (one that goes from exactly 20 to 20000 with 500 in the middle.

the second function is its inverse and the slider must have a range of 0 to 1. this is so other people can use it if they need.

```
lpKnob->textFromValueFunction = [](double value)
{
double freq = (value);
return (juce::String(20 * (std::pow(10, (3 * freq)))) + "Hz");
};
lpKnob->valueFromTextFunction = [](const String &text)
{
auto freq = text.removeCharacters("Hz").getDoubleValue();
return ((log10(freq / 20)) / 3);
};
```