Computational routine
eng


com_filter

File content


/* Modnumlib Scicos interfacing function
 * Copyright (C) 2009-2011 Alan Layec
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
 
/* com_filter Scicos Communication FIR filter block
 * Type 4 simulation function ver 1.0 - scilab-4.1
 * 17 Avril 2007 - INRIA - Author : A.Layec
 */

/* REVISION HISTORY :
 * $Log$
 */

#include <scicos/scicos_block.h>
#include "modnum_lib.h"

/* This computational routines realize a FIR
 * (bench of filters) in time domain.
 *
 * Regular inputs :
 *   - input vectors.
 *
 * Regular outputs :
 *   - output vectors.
 *
 * Event input :
 *   - input frequency sampling.
 *
 * Integer parameters :
 *   - ipar[0] : nfir : number of filters,
 *   - ipar[1] : nrep : number of impulse response,
 *   - ipar[2..2+nrep-1] : ne : vector of type of FIR,
 *   - ipar[2+nrep..2+2*nrep-1] : ne : vector of number sample per symbol,
 *   - ipar[2+2*nrep..2+3*nrep-1] : nbcoef : vector of number of coefficent,
 *   - ipar[2+3*nrep..2+3*nrep+nfir-1] : sz : vector of size of input vectors.
 *
 * Real parameters :
 *   - rpar[0..nrep-1] : roll-off : vector of roll-off,
 *   - rpar[nrep..2*nrep-1] : gain : vector of output gain.
 *
 * Work :
 *    - coef[0..cumsum(nbcoef)-1] : vector of coefficients of filter.
 *
 *   if nrep==1 then
 *    - z__[0..nfir*nbcoef-1] :
 *             vector of discrete state of filters,
 *   else
 *    - z__[0..cumsum(nbcoef)-1] :
 *             vector of discrete state of filters.
 */

/*work structure of that block*/
typedef struct work_st {
  double *coef;   /* impulse response vector   */
  double *z__;    /* discrete state of filters */
} work_struct;

/*prototype*/
void com_filter(scicos_block *block,int flag)
{
 double *u;  /*vector of inputs*/
 double *y;  /*vector of outputs*/

 int nfir;    /*number of filter*/
 int nrep;    /*number of impulse response*/

 int *typ;    /*vector of type of FIR*/
 int *ne;     /*vector of sample per symbol*/
 int *nbcoef; /*vector of number of coefficient*/
 int *sz;     /*vector of inputs size*/
 int sz2;     /*vector of inputs size 2 -not yet used-*/

 double *param; /*vector of parameters*/
 double *gain;  /*vector of gain of outputs*/

 int ptr_in;
 int ptr_coef;

 int i,j;
 double zero=0.0;

 work_struct *work; /*ptr of the struct of that block*/

 /*get the struct of that block*/
 work   = (work_struct*) *block->work;

 /*get input/output ptr*/
 y      = (double *)block->outptr[0];
 u      = (double *)block->inptr[0];

 /*get scalar nfir/nrep*/
 nfir   = block->ipar[0];
 nrep   = block->ipar[1];

 /*get ptr of ne/nbcoef/sz*/
 typ    = &block->ipar[2];
 ne     = &block->ipar[2+nrep];
 nbcoef = &block->ipar[2+2*nrep];
 sz     = &block->ipar[2+3*nrep];
 sz2    = 1;

 /*get ptr of param/gain*/
 param  = &block->rpar[0];
 gain   = &block->rpar[nrep];

 if(flag==4) { /*flag 4 : init*/
  /*allocation*/
  if ((work=(work_struct*) /*my_st*/
        scicos_malloc(sizeof(work_struct))) == NULL) {
         set_block_error(-16); return;
  }
  /*compute cumsum of nbcoef vector for coef*/
  j = 0;
  for(i=0;i<nrep;i++) {
    j += nbcoef[i];
  }
  if ((work->coef=(double*) /*array of coefficients*/
        scicos_malloc(sizeof(double)*j)) == NULL) {
         set_block_error(-16); return;
  }
  /*(re)compute cumsum of nbcoef vector for z__*/
  j = 0;
  if(nrep==1) {
    j = nfir * nbcoef[0];
  }
  else {
    for(i=0;i<nrep;i++) {
      j += nbcoef[i];
    }
  }
  if ((work->z__=(double*) /*array of discrete states of filters*/
        scicos_malloc(sizeof(double)*j)) == NULL) {
         set_block_error(-16); return;
  }
  /*init z__*/
  setd_c(&j,&zero,work->z__);

  /*compute coef*/
  if(nrep==1) {
    /*call filter_tap*/
    filter_tap_c(&nbcoef[0],&typ[0],&ne[0],&param[0],&work->coef[0]);
    /*adjust coef with gain*/
    for(j=0;j<nbcoef[0];j++) {
      work->coef[j] = work->coef[j] * gain[0];
    }
  }
  else {
    ptr_coef=0;
    for(i=0;i<nrep;i++) {
      /*call filter_tap*/
      filter_tap_c(&nbcoef[i],&typ[i],&ne[i],&param[i],&work->coef[ptr_coef]);
      /*adjust coef with gain*/
      for(j=0;j<nbcoef[i];j++) {
        work->coef[ptr_coef+j] = work->coef[ptr_coef+j] * gain[i];
      }
      /*adjust ptr*/
      ptr_coef += nbcoef[i];
    }
  }

  /*store my_st in block->work*/
  *block->work=(void *)work; /*store my_st in *block->work*/
 }

 else if(flag==1) { /*flag 1 : output computation*/
  /*int ptr in/coef*/
  ptr_in   = 0;
  ptr_coef = 0;

  if(nrep>1) { /*many impulse responses*/
    for (i=0;i<nfir;i++) {
      /*call nfiltery*/
      nfiltery_c(&sz[i],&sz2,&nbcoef[i],&u[ptr_in],&work->coef[ptr_coef], \
                  &y[ptr_in],&work->z__[ptr_coef]);
      /*adjust ptr*/
      ptr_in=sz[i];
      ptr_coef += nbcoef[i];
    }
  }
  else { /*only one impulse response*/
    for (i=0;i<nfir;i++) {
      /*call nfiltery*/
      nfiltery_c(&sz[i],&sz2,&nbcoef[0],&u[ptr_in],&work->coef[0], \
                  &y[ptr_in],&work->z__[ptr_coef]);
      /*adjust ptr*/
      ptr_in=sz[i];
      ptr_coef += nbcoef[0];
    }
  }
 }

 else if(flag==2) { /*flag 2 : discrete state computation*/
  /*int ptr in/coef*/
  ptr_in   = 0;
  ptr_coef = 0;

  if(nrep>1) { /*many impulse responses*/
    for (i=0;i<nfir;i++) {
      /*call nfilterz*/
      nfilterz_c(&sz[i],&sz2,&nbcoef[i],&u[ptr_in],&work->coef[ptr_coef], \
                  &y[ptr_in],&work->z__[ptr_coef]);
      /*adjust ptr*/
      ptr_in=sz[i];
      ptr_coef += nbcoef[i];
    }
  }
  else { /*only one impulse response*/
    for (i=0;i<nfir;i++) {
      /*call nfilterz*/
      nfilterz_c(&sz[i],&sz2,&nbcoef[0],&u[ptr_in],&work->coef[0], \
                  &y[ptr_in],&work->z__[ptr_coef]);
      /*adjust ptr*/
      ptr_in=sz[i];
      ptr_coef += nbcoef[0];
    }
  }
 }

 else if (flag==5) { /*flag 5*/
  /*free fields of the struct of that block*/
  if (work!=NULL) {
    scicos_free(work->coef);
    scicos_free(work->z__);
  }
  scicos_free(work);
 }
}