Anti-clip, limiter, compressing, quick wins?

Well my first attempt at an anti-clip "works", but it's not great. Need work.

How do I know I have or will clip? I am processing 16 or 24 bit audio in a 32bit word. Therefore if the value won't fit back into it's 16bit or 24bit word it will clip.

What can I do about it?

My first attempt was... decrement the "pre gain" value by 10% and cut the offending sample by a factor of 0.75.
The pre-gain value is then increased when there are no clips by a factor of about 0.00001 per sample.

I mean it's a bit of a butchers attempt at a limiter.

In practice what it does do very well is stop the ultimate blasting "fart" sound caused by bass clipping digitally. Instead I get a subtle clicking.

Trying to tune it reveals the clicking is most likely caused by the sample scaling factor. If it's too small, the clip happens at least the first time, "Click", if it's too large, it effectively inserts a bogus corrupt (too low magnitude) sample in it's place "click".

An expensive approach is to do the clip calculation in a while loop...

while( stillClipped() ) {
gain -= 0.01;
recalculateSample();
}

But I don't have that kind of time/luxury, I need an instant response.

Putting compression asides. What I really want is a HARD limiter. In my experience of using various audio and video software packages on PC which almost always come with some form of hard limiter plug in. However I don't think I've met one that worked perfectly. You can always blow through them, particular with EQ.

Putting it in here... "Don't drive it that hard. If it clips at 0db, aim for a meter level of -6db and occasional transients are then -3db. Yes, yes, yes I know. I have no GUI on my EQ, so to tweak settings I have to edit code and rebuild, so it's "scrappy". I'm hitting the clip a lot.

Not many people get this approach, but I tend to "keep my baggage" when developing/engineering. If a problem manifests during development don't just jump to fix the root cause, instead use it as an opportunity, for some negative testing, to make the project, adaptive, accommodating or at least protect itself and others from the mistake and do something sensible.

In that regard the clicking is just a nice reminder to fix the gain structure and stop being lazy. However, while I could flash a red LED and move on from here.... I want to spend some time trying to get the "Anti-Clip", "Hard last-resort limiter" a little better first.

Any suggestions or articles to read on techniques?
 
Another thought was to keep a historic buffer of say, 10ms and periodically run an "energy" scan on it. Pick and/or tune up a threshold for energy such that it will ... based on what has happened in the last 10ms... already reduce the gain before it clips. This would be more compression maybe?

EDIT: Again though, as my experience in audio software suggests, 10ms is not enough response time to stop a bass drop or a cymbal busting through your peak.
 
In practice what it does do very well is stop the ultimate blasting "fart" sound caused by bass clipping digitally.
The fart you describe is not clipping but binary overflow. If it is the result of your signal modification, use saturating arithmetic. Otherwise, use replay gain. Manipulating the overall gain usually highlights the problem rather than hiding it.
 
What I really want is a HARD limiter. In my experience of using various audio and video software packages on PC which almost always come with some form of hard limiter plug in. However I don't think I've met one that worked perfectly. You can always blow through them, particular with EQ.
Of course. That's because the limiter is not the last thing in your signal processing chain.
 
Manipulating the overall gain usually highlights the problem rather than hiding it.
I agree. As I tried to put it, this is not the normal operating conditions, this is a negative test. The gain through mixing or EQ has or will cause an overflow. If I was to do a standard "clipping" pattern it would look like:

if( sample > limit )
sample = limit;

But that creates almost as much distortion. not quite and maybe at least the distortion it creates is "natural" to our ears, sounding like an amp overloaded rather than monstrosity of digital overflows.
 
A contrived analogy with a mixing desk would be...

You have a stereo channel and you look and see your EQ gains are all sitting at the 1 o'clock position and your input gain is sitting at the 11 o'clock position. The two net to 0 effect. So you should just zero them all.

Similarly here, if the EQ output is overflowing, there is either too much gain the EQ or the input is running too hot.

There is what a mastering engineer would do.
There is what a studio engineer would do.
There is what a live engineer would do.
Then there are drunk DJs and parties.

Especially with the later, it's not uncommon to be adding more than your headroom in EQ. You can have a flat 0db gain structure across the board with a 6db hard limit and end up adding way more than 6db EQ, something has to give, like your input "pre-gain".

This has to survive them all. I am not going to run it like that. There will be a very bright red light when this occurs, I just want to save my hearing (on headphones) and those listening if it's on speakers from the onslaught resulting from a full, unprotected digital overload. It's not only unpleasant, but can be be dangerous to hearing and damage equipment.

"last resort"
 
Can you process audio as floats or doubles instead of as N bits? Internally at least under Linux the maximum signal level is between -1.0 and 1.0 in those representations and this is assumed to correspond to 1111111...1

The advantage of using floating point representation is that internal headroom is nearly infinite and overflow impossible.

A hard clip is simply done like this: if value>1 value=1 elseif value<-1 value=-1 endif
You can implement limiting very easily as well...