0

I would like to implement Lattice IIR filter in c, i can't defined the value of gN, i know that x(n) = fN(n), but how to initialize gN ?. you can find the algorithm here : nlattice iir filter

Midou
  • 1
  • 5

3 Answers3

4

assume all of this (except k[0] and the output y[]) gets defined. states g[] are initialized to zero.

int N, NUM_SAMPLES;
float g[N+1], v[N+1], k[N+1];
float x[NUM_SAMPLES], y[NUM_SAMPLES];

then the sample processing would look like this:

int n = 0;
while (n < NUM_SAMPLES)
    {
    float f = x[n];
float acc = 0.0;
int m = N;
while (m &gt; 0)
    {
    f -= k[m]*g[m-1];
    g[m] = k[m]*f + g[m-1];
    acc += v[m]*g[m];
    m--;
    }
g[0] = f;
acc += v[0]*g[0];

y[n] = acc;
n++;
}

that is, i think, the essential C code.

robert bristow-johnson
  • 20,661
  • 4
  • 38
  • 76
2

you have a programming issue here. i have C code for a lattice i did long ago. dunno if i wanna dig it out (i used to sell it for money, but that was long ago). just think this: at the beginning of your sampling instance when $x[n]$ is defined, consider what else is defined and it is the outputs of all of the unit delay blocks (marked $z^{-1}$). those numbers (and the $k_m$ coefficients) are what you know at the beginning.

what must you calculate after that?

first thing is $f_{N-1}[n]$ and $g_N[n]$.

then you can calculate $f_{N-2}[n]$ and $g_{N-1}[n]$.

then you calculate $f_{N-3}[n]$ and $g_{N-2}[n]$.

then you calculate $f_{N-4}[n]$ and $g_{N-3}[n]$.

...

last intermediate state you will calculate is $f_0[n]$ and $g_1[n]$ and finally $g_0[n]=f_0[n]$.

then you can calculate $y[n]$ as a dot-product of all of the $v_m$ coefficients and the intermediate states $g_m[n]$.

then lastly you update your states of the $z^{-1}$ unit delay blocks for the following sample. (this updating can be done naturally with no wasted instruction cycles. when you calculate $g_{N}[n]$ and $f_{N-1}[n]$, you need knowledge of $g_{N-1}[n-1]$ which is the state. but after that calculation, then you will never need $g_{N-1}[n-1]$ again and you can replace it with the calculated value of $g_{N-1}[n]$ in anticipation of the following sample period.)

the state of the block on the right will be $g_0[n]$, the block to the left of that is $g_1[n]$ and finally the the output of the state of the block on the left is $g_{N-1}[n]$.

now you are done with this sample and ready to compute the next sample when its input, $x[n+1]$ comes in.

robert bristow-johnson
  • 20,661
  • 4
  • 38
  • 76
  • thank you for your help Please can you explain more how to calculate is fN−1[n] and gN[n] ? you said that i have to calculate gN[n], but to be able to calculate gN[n], we have define firstly gN-1[n], no ?!! – Midou Jun 29 '17 at 08:18
  • look at your signal flow diagram. and remember the outputs of all of the states (those are the blocks with $z^{-1}$ on them) are known at the beginning of your sample period. so while you do not yet know the input to that block (which is $g_{N-1}[n]$) you know the output of it because it was the input do that block the previous sample, i.e. you do know $g_{N-1}[n-1]$. and the initial value of it is zero (i.e. $g_{N-1}[-1]=0$). – robert bristow-johnson Jun 29 '17 at 16:37
  • ok, it means gN-1[n] = input[n] in the beginning !! – Midou Jun 30 '17 at 12:20
0

this is my code, it works just for one stage, i mean just for fN−1[n] and gN[n], one coefficient. but when i try to calculate the rest it doesn't works

for (i=0;i<block_size;i++)
    {
    f_in[i]=input[i];
    g_in[i]=input[i];
    }

for (j=nb_coefficient;j>0;j--)
    {

        for (i=block_size-1;i>=0;i--)
            {

            g_in[i]=g_in[i-1];

            printf("%f %f %f \n",input[i],f_in[i],g_in[i]);

            output[i] = f_in[i] - parkor_coefficient[j]*g_in[i];
            printf("%f\n",output[i]);

            g_out[i] = output[i]*parkor_coefficient[j] + g_in[i];
            printf("%f\n",g_out[i]);

            }
            for(i=0;i<block_size;i++)
                {
                f_in[i]=output[i];

                    if(j==1)
                    {
                        g_out[i]=output[i]; 
                    } 
                }


    }

}

Midou
  • 1
  • 5