DSPRelated.com
Forums

Winfilter bug?

Started by Roger Bourne March 21, 2006
Hello all,

I think there may be a bug in the Winfilter08 program.
However, the bug which I will state below, is really too obvious so I
am doubting myself.
Anyway, hear goes:


In the C code generation of an IIR filter (lowpass, 8th order,
chebychev, fs=1000Hz, fcut1=250Hz, Ripple=1dB),  I think that there is
an error that gets generated when the fixed point (16 or 8bit) is
chosen.
This was based on the fact that the output should yield
                   (y[n] = a0*x[n] + a1*x[n-1] + a2*x[n-2] - b1*y[n-1]
- b2*y[n-2]),


This is the outputted code:

.....[cut]

    //Calculate the new output
    x[0] = NewSample;
    y[0] = ACoef[0] * x[0];
    for(n=1; n<=NCoef; n++)
        y[0] += ACoef[n] * x[n] - BCoef[n] * y[n];

    y[0] /= BCoef[0];                         ------------   1st
division
    return y[0] / DCgain;                    ------------   2nd
division




I agree with the 1st division. The Bcoef[1 to n] coefficients were all
amplified by the Bcoef[0] value, so a division is necessary to bring
down the coefficients to their original intended values. This had to be
done because of the fixed-point approach.
However, the Acoef[0 to n] coefficients were all amplified by the
Bcoef[0]*DCgain value. In this case, both the division by Bcoef[0] and
by DCgain are necessary.
(In order to assess the factor of amplication of the coefficents, the
fixed-point evaluated coefficients were compared to the floating-point
evaluated coefficients. The floating point evaluated coefficients are
used as a reference.)


However, the last division seen in the C code
                     return y[0] / DCgain;
performs the [divide by DCgain] division on all coefficients, both
Bcoef[1 to n] and Acoef[0 to n]. This should lead to an erroneous
return value.



Is this a correct assumption?

-Roger

No. Your understanding is right till your last statement.

Only the An coefs are scaled by DCgain. It is like scaling the input
signal by DCgain.
Therefore, the output signal must be scaled down "return y[0] /
DCgain".
The preserved y[0] is not scaled down because the y[] values must
retain the system DCgain.

Cheers,
Adrian

Hmmm....

Let's see if I were to insert/draw a DCgain amplification BEFORE the
[input of the IIR filter in the direct form I diagram], then yes I
would need to attenuate by DCgain the [output of the IIR filter in the
direct form I diagram].
Amplifying the input of the IIR filter (by DCgain), OR amplifying only
the corresponding feedforward coefficients by DCgain -from the bloc
diagram perspective- seems like it should have the same effect.

If we were to look at it from the equation point of view:
      (y[n] = a0*(DCgain*x[n])*Bcoef[0] + a1*(DCgain*x[n-1])*Bcoef[0] +
a2*(DCgain*x[n-2])*Bcoef[0] - b1*y[n-1]*Bcoef[0] - b2*y[n-2])*Bcoef[0],


it would imply that the SEEN effective input to the IIR filter would be
x'[n]=DCgain*x[n]
So again, it seems correct. A division by Dcgain would be necessary on
y[n] in order to extract x[n].

So my question is:
Why did we go to all the trouble to amplyfing the input (of the filter)
by DCgain ?
Does it have to do something with boosting up the resolution of the
Acoef[n] ?

-Roger

yes, only Acofs scaling purpose (get more precision with integers).

Adrian