# peak limiting/audio compression formula needed

I'm looking for a formula to effectively compress an audio waveform to limit peaks. This isn't an "automatic volume control" application where one would control amplifier gain to maintain a volume level, but rather I want to limit ("soft" truncate) individual peaks.

My formula so far is:

factor = (10 * average / level) + exp(-sqrt(0.1 * level / average))


Where level is the instantaneous sound level, average is the historical average, and factor is a multiplier used to produce the "adjusted" level (factor times level).

Further, this multiplier is only applied if it computes to a value less than 1. Otherwise level is left unadjusted.

The intent is to limit the adjusted level to some multiple (about 15x with this formula) of the historical average. This formula is sorta what I need, but exhibits a "dip" as the numbers get larger. That is, the adjusted level (ie, factor times level) increases up to a point with increasing unadjusted level but then, rather than going asymptotic, begins to actually get smaller. (In fact, the first factor was added primarily to prevent the formula from going to zero with extremely high values.)

So, can anyone suggest something better? (It seems that asymptotic behavior is easy to produce when you don't want it, but hard when you do.)

-
This should probably go in dsp.stackexchange.com. – Ben Crowell Feb 9 '12 at 21:13
If $x$ represents the "level / average" ratio, then your formula corresponds to a "(factor * level) / average" given by $10+xe^{-\sqrt{0.1x}}$ plotted here (Wolframalpha plot), whose maximum is $10+40e^{-2}\approx 15.4$. If you change it to $A(1-e^{-\sqrt{0.1x}}$, you get this plot for $A=10+40e^{-2}$. – Américo Tavares Feb 10 '12 at 19:34
Put that in an answer and I'll give you the check. Though I went over to DSP and got a suggestion of new_level = 10 * average * tanh(level/(10 * average)), which works pretty well. – Daniel R Hicks Feb 10 '12 at 23:04

If $x$ represents the "level / average" ratio, then your formula corresponds to a "(factor * level) / average" given by $10+xe^{-\sqrt{0.1x}}$ plotted here (Wolframalpha plot), whose maximum is $10+40e^{-2}\approx 15.4$. If you change it to $A(1-e^{-\sqrt{0.1x}})$, you get this plot for $A=10+40e^{-2}$.
Added: You might add a constant: $C+A(1-e^{-\sqrt{0.1x}})$.