Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: FIR filter gain determination (Read 21209 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

FIR filter gain determination

I would like to be able to determine the best gain value for a FIR filter, so that if you apply it to a signal (ie, by convolution) in the [-1,1] range, you get a signal in the [-1,1] range.  (Assume that the signal is music.)

There seem to be several possible approaches:

Peak gain:

If the FIR coefficients are h0, h1, h2, ..., hN-1  then the sum of the absolute values of the coefficients will give an upper bound of applying the filter to [-1,1], so scaling the input by it's reciprocal should keep you within limits.  It is, however, a very conservative limit.

DC gain:

If the input signal is a constant 1, then the DC gain is just the sum of the coefficients.  Seems to be of limited application.

"AC gain":

If you take the Fourier Transform of the FIR to get a set of (complex) coefficients (Hi) then the maximum absolute value of the real part of the Hi (ie, the amplitude, as opposed to the complex part, which corresponds to phase) produces another limit.  What are the circumstances under which this is determines a useful gain limit?

"Gain to noise:"

SUM( hi^2) / N


"RMS gain":

This limit is just SQRT(SUM( Re(Hi)^2 + Im(Hi)^2)).  Again, under what circumstances is does this determine a useful limit?

"White Noise gain":

Applying the FIR filter to some White Noise and using maximum of the output as an indicator.  I don't know what the theory behind this is, but presumably it is based on the observation that white noise contains signals of a wide range of frequencies.  Does it matter whether the noise is generated from a uniform [-1,1] distribution or does it have to be gaussian/normal?


Can anyone provide any pointers to which methods work best under what circumstances?  Thanks

FIR filter gain determination

Reply #1
The gain will always be the sum of the absolute value of the coefficients.  It is best to normalize the FIR to a 0dB gain (coefficients sum to 1) to prevent anything unexpected.

You won't ever know the "realized gain" because it highly dependent on what your input signal is.  If your signal has frequencies where your poles are, you'll see much higher gain (for example) then one without any frequencies there at all.  So it all depends on the application and your expected input.

FIR filter gain determination

Reply #2
Thanks.  I feared that this might be the case.

What if I know the sample rate (eg, 44.1kHz) or the max and min frequency (20Hz-20kHz, say) will that provide me with a more accurate fix on the maximum gain?

FIR filter gain determination

Reply #3
Quote
The gain will always be the sum of the absolute value of the coefficients.   It is best to normalize the FIR to a 0dB gain (coefficients sum to 1) to prevent anything unexpected.

You won't ever know the "realized gain" because it highly dependent on what your input signal is.  If your signal has frequencies where your poles are, you'll see much higher gain (for example) then one without any frequencies there at all.  So it all depends on the application and your expected input.
[a href="index.php?act=findpost&pid=377889"][{POST_SNAPBACK}][/a]



Oeeerrr. If you have "poles" in your FIR filters, ....

Obviously the biggest value you can get out of the FIR filter is the sum of the absolute values of the coef's. That corresponds to a signal that is +- 1 using the same sign as the coef's.

This may be a very unusual sort of signal, though. Very few signals can be created like that inside a sampled system, except synthetically.  Consider what the input to the anti-aliasing filter would have to be to make that happen, eh?
-----
J. D. (jj) Johnston

FIR filter gain determination

Reply #4
Yes. That is really why I am asking whether there are other ways of calculating the gain that might provide more realistic limits.

FIR filter gain determination

Reply #5
Quote
Yes. That is really why I am asking whether there are other ways of calculating the gain that might provide more realistic limits.
[a href="index.php?act=findpost&pid=378665"][{POST_SNAPBACK}][/a]



Well, for a constant-delay filter (symmetric, antisymmetric for HP) you might consider the implications of constant-delay and an FFT that never goes above '1', yes, say even when analysed on a much finer grid than the length of the filter?
-----
J. D. (jj) Johnston

FIR filter gain determination

Reply #6
Sorry. Don't understand. HP?

Suppose I am just using room impulse response filters, or high/low pass filters, eg?

FIR filter gain determination

Reply #7
You could "normalize" the impulse response by scaling it so that the sum of the squared impulse response's samples equals one. AFAIK this is what the convolver plugin for Foobar optionally does. It also lets you adjust the gain by a slider since the "normalizing" approach might produce clipping.

Instead of applying the filter on white noise you could do a little math. If the samples of your noise generator are IID (independant and identically distributed => white) and the distribution is known you can easily derive a PDF for the convoluted signal's samples and calculate for a given probability p a certain level so that a sample exceeds this level with a probability of p. Your "peak gain" approach is a special case of this (p=0, full scale noise). To be less paranoid set p to, say, 0.05 ...

One might want to do this with pink noise since it better matches signal properties of natural audio. But the whole computation gets trickier because the pink noise signal is correlated.

Try this: Generate some pink noise (say, one second) apply the filter and compute the samples' standard deviation. Use a certain multiple of this standard deviation as an approximation of a "peak". Assuming that the convoluted signal's samples are approximately gaussian distributed (not 100% correct) you can choose a factor of 3 to get a level that is not exceeded with a probability of 99.6% (on a per sample basis) for example.

edit: I just realized this can be done quite efficiently If you work solely in the frequency domain. Multiply the filter's amplitude response A:frequency->amplitude with a curve P:frequency->amplitude that matches the spectral envelope of pink noise: R(f) = A(f)*P(f) and compute sqrt(int(R^2(f), f=0..pi)). Multiplied with a certain factor you have to choose this will give you your "peak". (Easy implementation: Start with an FFT on the impulse response to get a frequency discrete amplitude response and integrate by accumulating the squares after weighting.)

HTH,
Sebi

 

FIR filter gain determination

Reply #8
Quote
(Easy implementation: Start with an FFT on the impulse response to get a frequency discrete amplitude response and integrate by accumulating the squares after weighting.)
[a href="index.php?act=findpost&pid=378879"][{POST_SNAPBACK}][/a]


Let's see if I have understood this correctly:

If the FFT of the hi (real) are Hi (complex)

then the convolution scaling factor should X / (sum (Re Hi^2))

How does X relate to the degree of certainty that I am looking for?  Or have I got the wrong end of the stick?

FIR filter gain determination

Reply #9
The FFT without the weighting step is of no use. Also don't forget the square root. This is what I meant:

Suppose hi is the time domain impulse response, Hi = fft(hi,fftSize) (zeropadding to fftSize samples) and weights is a weighting vector of the same dimension fftSize. Then your scaling would be:

max_value_allowed/(X*std_dev_estimated)  where  std_dev_estimated := sqrt( sum( (abs(Hi).*weights).^2 ) ) / fftSize

(Matlab notation, ".*" and ".^" are "component-wise" operators)
If I'm correct with all the scaling involved (not sure!) std_dev_estimated will be an estimate for the convolved signal's samples deviation from zero (a.k.a. the the square root of the distribution's 2nd moment). Assuming a gaussian sample value distribution X can be chosen so that the probability of a sample value not exceeding a certain level is your desired certainty. For example:
X=1 => probability of a abs(some_sample)<max_value_allowed is around 66 %
X=2 => probability of a abs(some_sample)<max_value_allowed is around 95 %
X=3 => probability of a abs(some_sample)<max_value_allowed is around 99.6 %
(certainty can be computed via integrating a zero-mean & unit-deviation gaussian PDF from -X to X)

The weights should reflect the sound's level and coloration you work with (like pink for example). They can be attained for example by computing sqrt(2).*|fft(hann_windowing(fftSize samples of pink noise))|.

HTH,
Sebi

FIR filter gain determination

Reply #10
The mists are clearing:

I assume that

std_dev_estimated := sqrt( 2 * sum( (Re(Hi)^2 + Im(Hi)^2).* weightsi^2) ) ) / fftSize

Turning to the calculation of the weights:

I need to calculate a [hanning] window of fftSize using something like

void clDSPOp::WinHanning (float *fpDest, long fftSize )
{
    long lLoopCntr;

    for (lLoopCntr = 0L; lLoopCntr < fftSize ; lLoopCntr++)
    {
        fpDest[lLoopCntr] = 0.5F -
            0.5F * cos((2.0F * fPI * (float) lLoopCntr) / (float) fftSize );
    }
}

multiply fpDest by the relevant random samples, take the FFT and sqrt(Re^2 + Im^2) to get the real weights.

Is that right?  Thanks for bearing with me.