DSPRelated.com
Forums

Re: Q-format ???

Started by piet...@yahoo.com July 18, 2011
hi all,
i have a 2nd order IIR filter code for TMSC6x but there is some ambiguity while understanding this code. please help me to understand this code, which is given as
to implement : y[n]*x[n]+b1*x[n-1]+b2*x[n-2]+a1 *y[n-1]+a2*y[n-2]

% (Double precision)
void iir_2nd_d(Shortword
input[],Shortword den[],Shortword num[],
Shortword output[],Shortword delin[],Shortword delout_hi[],

Shortword delout_lo[],Shortword npts)
{
Shortword i,temp;
Longword accum;
//////////////// ist 5 line of for loop expanation required
for (i = 0; i < npts; i++) {
accum = L_mult(delout_lo[0],den[1]); %%what is delout_lo & delout_hi ??purpose?
accum = L_mac(accum,delout_lo[1],den[2]);
accum = L_shr(accum,14); // why this shift ??? logic ??
accum = L_mac(accum,delout_hi[0],den[1]);
accum = L_mac(accum,delout_hi[1],den[2]);

accum = L_mac(accum,shr(input[i],1),num[0]);
accum =L_mac(accum,delin[0],num[1]);
accum = L_mac(accum,delin[1],num[2]);

/* shift result to correct Q value */
accum = L_shl(accum,2); /* assume coefficients in Q13 */ logic???

/* update input delay buffer */
delin[1] = delin[0]; data_move();
delin[0] = shr(input[i],1); data_move();

/* update output delay buffer */
delout_hi[1] = delout_hi[0]; data_move();
delout_lo[1] = delout_lo[0]; data_move();

delout_hi[0] = extract_h(accum);
temp = shr(extract_l(accum),2);
delout_lo[0] = temp & (Shortword)0x3FFF; logic();

/* round off result */
accum = L_shl(accum,1);
output[i] = round(accum);
}
}
Regards

_____________________________________
Hey Pieter,

Humbly, I can only offer the following (you may already know quite a
bit, so please forgive me if I cover too much):

(1). An IIR (infinite impulse response) filter is a bit different than a
FIR (finite impulse response) filter, in that while the FIR filters
function purely with an input signal (x[n]), the IIR filters works with
both input signal (x[n]) AND feedback from the output signal (y[n]).

(2). As far as the code source goes, without seeing the documentation, I
can only guess the "delin" refers to input signal (x[n]), while the
"delout" must refer to the output signal (y[n]).

(3). The term "Q format" is used in conjunction with fixed-point
arithmetic as opposed to floating-point arithmetic. Fixed-point DSPs are
cheaper than Floating-point DSPs, hence the reason why they are used.
You will see certain operations, such as shift right and left, used
frequently in order to accomplish the fixed-point operations.

There are some really good entries in Wikipedia for IIR and Q format
fixed-point arithmetic - they might be of help to you.

Hopefully, this helps a bit, and maybe others can shine more light on
this as well (Corrections welcome).

BTW, this IIR filter looks vaguely like an older C6x implementation for
a MELP codec - if that's the case, maybe you might want to check the TI
website too.

Cheers,
g.

On 7/18/2011 12:05 AM, p...@yahoo.com wrote:
>
> hi all,
> i have a 2nd order IIR filter code for TMSC6x but there is some
> ambiguity while understanding this code. please help me to understand
> this code, which is given as
> to implement : y[n]*x[n]+b1*x[n-1]+b2*x[n-2]+a1 *y[n-1]+a2*y[n-2]
>
> % (Double precision)
> void iir_2nd_d(Shortword
> input[],Shortword den[],Shortword num[],
> Shortword output[],Shortword delin[],Shortword delout_hi[],
>
> Shortword delout_lo[],Shortword npts)
> {
> Shortword i,temp;
> Longword accum;
> //////////////// ist 5 line of for loop expanation required
> for (i = 0; i < npts; i++) {
> accum = L_mult(delout_lo[0],den[1]); %%what is delout_lo & delout_hi
> ??purpose?
> accum = L_mac(accum,delout_lo[1],den[2]);
> accum = L_shr(accum,14); // why this shift ??? logic ??
> accum = L_mac(accum,delout_hi[0],den[1]);
> accum = L_mac(accum,delout_hi[1],den[2]);
>
> accum = L_mac(accum,shr(input[i],1),num[0]);
> accum =L_mac(accum,delin[0],num[1]);
> accum = L_mac(accum,delin[1],num[2]);
>
> /* shift result to correct Q value */
> accum = L_shl(accum,2); /* assume coefficients in Q13 */ logic???
>
> /* update input delay buffer */
> delin[1] = delin[0]; data_move();
> delin[0] = shr(input[i],1); data_move();
>
> /* update output delay buffer */
> delout_hi[1] = delout_hi[0]; data_move();
> delout_lo[1] = delout_lo[0]; data_move();
>
> delout_hi[0] = extract_h(accum);
> temp = shr(extract_l(accum),2);
> delout_lo[0] = temp & (Shortword)0x3FFF; logic();
>
> /* round off result */
> accum = L_shl(accum,1);
> output[i] = round(accum);
> }
> }
> Regards