can you explain why the pitch midpoint is calculated this way? and skew factor?
This remapping function is freakin brilliant. Where did this come from? Did you derive it? I can see that it works but am trying to get a better intuition for how to come up with something like this.
The log’s argument is a linear map from start…end to 1…2^k, so the log is 0…k, and 1/k normalises it. As you increase k, you take a longer part of the log’s domain, which increases the skew. At k=10 it’s pretty close to a freq->pitch map for the usual range (~20…20k Hz). For other ranges it may need other values of k.
By the way, the skew formula I posted above is a bad idea. ValueRemapFunction had gone over my head, so I tried to approximate with a skew factor. Now I’m using something similar to JussiNeuralDSP’s code.
NormalisableRange<float> frequencyRange (float min, float max, float interval)
{
auto logMin{ std::log(min) }, logRange{ std::log(max) - logMin },
logRangeRec{ 1.0f / logRange }, intervalRec{ 1.0f / interval };
return
{
min, max,
[=](float, float, float normalised) { return std::exp (normalised * logRange + logMin); },
[=](float, float, float unnormalised) { return (std::log (unnormalised) - logMin) * logRangeRec; },
[=](float start, float end, float value)
{
return std::clamp (std::round ((value - start) * intervalRec) * interval + start, start, end);
}
};
}
Awesome yeah I was wondering about the value of 10, and if that was something specific to the derivation or just sort of “as close as we can get.” Thanks!
I did a deep dive on this a couple months ago and appreciated this thread.
In case it’s useful to future visitors here’s my version with Catch2 tests and a desmos link to the math. It lets you specify how exponential you want the curve: