com_filter
/* 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],¶m[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],¶m[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);
}
}