/* 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); } }