// gainDb: makeup gain in dB (0..~36)
// R: compression ratio (e.g. 4)
// W: knee width in dB (e.g. 6)
// refDb: input level that should map to itself at the output (0 for full scale,
// -3 to leave 3 dB of headroom, etc.)
// Returns the threshold in dB.
float thresholdFromGain(float gainDb, float R, float W, float refDb)
{
float k = R / (R - 1.f);
float gKnee = W / (2.f * k); // gain at which refDb leaves the knee region
float t;
if (gainDb > gKnee)
t = -gainDb * k; // refDb above the knee: linear
else
t = W * 0.5f - sqrtf(2.f * W * gainDb * k); // refDb inside the knee: quadratic
return t + refDb;
}