Tuesday, 1 December 2015

DC blocking IIR filter clipping?


I'm processing audio data for voice input from a mic. The data arrives in 32 bit floats [-1 ~ +1].


My first filter is to remove DC:



// x = new input value, y = filtered output value
m_x += ( 0.01 * ( x - m_x ) );
y = ( x - m_x );

When I feed it audio that is close to clipping (but not actually hitting -1 or +1), I'll get values back that actually do go above the [-1 ~ +1] limit - sometimes way above. I find this behavior curious.


Can anyone explain why this happens?


Also, what's the best way to "fix" this? Do a simple clamp for the returned y value? Pre-scale the input down via (x * 0.7071) first?


Thanks!



Answer



Your DC blocker transfer function is



$H(z) = (1-a)\frac{1-z^{-1}}{1-(1-a)z^{-1}}$


and an alternative (equivalent) difference equation is


$y_n = (1-a)(x_n - x_{n-1}+y_{n-1})$


Although this filter provides no gain it is possible to find inputs that exceed +1. For instance this input [1 -1 -1 -1 1].


Because you seem to work with a floating point realization you should not need to scale down before filtering.


Edit: The output of your filter is bounded this way: $|y_n|<2(1-a)$. So an input gain of 0.5 guarantees that the output of the filter can't exceed +1 if the input is bounded between -1 and +1. Can you come up with an input that produces an output value that exceeds +1.5 or an input that produces an output values that is less than -1.5?


Edit2: Filters can provide amplification as well as attenuation, otherwise they wouldn't be that interesting. Your filter does not provide amplification in the sense that a sinusoid passing through your filter will not have an increased amplitude. You can see that by plotting the amplitude/frequency response of your filter. However, for more complex inputs the non-linear phase response of your filter can cause 'overshoots' in the output. An allpass filter for instance, even though it has a completely flat amplitude response can also provide 'overshoots' for fullscale inputs.


How to deal with the spikes depends very much on what the other modules in your signal path are doing. Maybe some of the modules create headroom maybe some of them consume headroom. I don't know. Considering your DC blocker in isolation then you can apply a headroom gain of say 0.7 or 0.8 and then saturate your output. Although this setting is likely to perform some saturations my guess is that they will be completely inaudible. You will have to confirm this by experiment.


No comments:

Post a Comment

readings - Appending 内 to a company name is read ない or うち?

For example, if I say マイクロソフト内のパートナーシップは強いです, is the 内 here read as うち or ない? Answer 「内」 in the form: 「Proper Noun + 内」 is always read 「ない...