padoumba
padoumba

Reputation: 1

Digital filter algorithm

I just found a fir algorithm on wikipedia

http://en.wikipedia.org/wiki/Digital_filter

// if the size of NB_COEF = 2^n use a bit mask instead of the modulo (%)
// %=NB_COEF => &=(NB_COEF-1)
// pipe is a circular buffer

#define NB_COEF 16  // numbers of coefficients of the filter
double x_buffer[NB_COEF]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
double coef[NB_COEF]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int ptr_x_buffer=0;

double FiltreFIR(double x)
// x: Signal d'entrée
// y: Signal de sortie
{
  int n, y=0;
  x_buffer[ptr_x_buffer++] = x;
  ptr_x_buffer %= NB_COEF;

  for( n = (NB_COEF-1) ; n >= 0 ; n-- )
  {
    y += coef[n] * x_buffer[ptr_x_buffer++];
    ptr_x_buffer %= NB_COEF;
  }
  return(y);
}

-Can anybody tell me why do we need constantly to do this expression

ptr_x_buffer%= NB_COEFF.

Because for me it would mean the variable ptr_x_buffer always take the value 0 ?! And it seems to me far from logic?!

And also can somebody explain to me the first comment about bit masking and modulo.

thank you in advance :)

Upvotes: 0

Views: 2075

Answers (3)

NPE
NPE

Reputation: 500427

Quite simply, x_buffer is a circular buffer; ptr_x_buffer points to the current location in the buffer:

  • ptr_x_buffer++ increments ptr_x_buffer;
  • ptr_x_buffer %= NB_COEF resets ptr_x_buffer to zero as soon as it reaches NB_COEF.

The comment suggests a modification of the code for certain values of NB_COEF. Whoever wrote that comments appears to have considered the suggested modification to be a performance improvement. However, it is highly doubtful that the change would lead to better performance and, therefore, the remark can be ignored.

Upvotes: 2

Howard
Howard

Reputation: 39197

The expression ptr_x_buffer%=NB_COEFF means that ptr_x_buffer is resetted modulo NB_COEFF. Therefore it is not "always 0" but the modulus with respect to division by 16. Therefore it is guaranteed that the array access x_buffer[ptr_x_buffer] always lies within the bounds 0..NB_COEFF-1.

For powers of 2 the modulo operation can be replaced by a bitwise and with a mask of 2^n-1 (or N-1) where n is the log2 of your modulus.

Upvotes: 0

x4u
x4u

Reputation: 14077

It is used to ensure that the ptr_x_buffer is always a valid index inside the x_buffer array which is used as a cyclic buffer. Whenever ptr_x_buffer would overflow the array size it gets reset to 0.

ptr_x_buffer gets incremented with each invocation of the function and on each iteration of the loop in x_buffer[ptr_x_buffer++].

You could also replace the lines ptr_x_buffer %= NB_COEF; with this:

 if( ptr_x_buffer == NB_COEF )
     ptr_x_buffer = 0;

Or if you are sure that NB_COEF is a power of 2 you could mask them with a bitmask if as is stated in the comment already: ptr_x_buffer &= NB_COEF-1;.

Upvotes: 4

Related Questions