| It's more complex than that. Let me explain: Audio is typically passed into a soundcard's digital audio converter (DAC) as integers representing samples of the audio waveform. For example, a full volume sine wave looks something like this[0]. That signal is perfectly safe to play on any hardware. However, if you take that same sine wave and increase the amplitude you end up with values outside the valid range so you have to cap them. You get something that looks like this[1]. Lopping off the tops and bottoms of the waveform is clipping, and the newly created sharp edges in the waveform are what can damage your speaker. They require a ton of energy to play (producing heat) and in some cases can trigger the buildup of high frequency harmonic oscillations in your speaker's voice coil that can eventually crack it. More expensive speakers last longer but virtually all speakers eventually "blow" under such circumstances. The trouble is playing waveforms like that once in a while is totally ok and short bursts of very similar waveforms exist benignly in lots of stuff you listen to every day. And while it's trivial to know if you're creating clipped audio, it's very difficult (read: processor intensive) and error-prone to detect it after the fact. When you do detect it, your solutions are to either drastically lower the global volume so the edges have a lot less energy, or distort the waveform to make those edges more smooth. It's really, really hard to avoid false positives though and not end up "enforcing" against audio data that's natural and perfectly ok in moderation. [0] http://upload.wikimedia.org/wikipedia/commons/thumb/b/bf/Pcm...
[1] http://www.st-andrews.ac.uk/~www_pa/Scots_Guide/audio/clippi... |
If it's a factor of 2, for example, just take the 3dB volume loss and move on.
I don't see why detecting the situation is so hard, though. Build a simplistic model of the amount of energy dumped into the speaker and the amount dissipated, run the audio through that model, and then limit the volume when the amount still in the speaker gets too high. This would let through small amounts and limit large amounts, just like you'd want. For a really simplistic model, run the signal through a high pass filter, integrate the output, then apply a running average to that. When the running average surpasses a value that indicates the speaker is reaching its limit, cut the volume. I take it that this doesn't work?