/****************************************************************** iLBC Speech Coder ANSI-C Source Code filter.c Copyright (C) The Internet Society (2004). All Rights Reserved. ******************************************************************/ #include "iLBC_define.h" /*----------------------------------------------------------------* * all-pole filter *---------------------------------------------------------------*/ void AllPoleFilter( float *InOut, /* (i/o) on entrance InOut[-orderCoef] to InOut[-1] contain the state of the filter (delayed samples). InOut[0] to InOut[lengthInOut-1] contain the filter input, on en exit InOut[-orderCoef] to InOut[-1] is unchanged and InOut[0] to InOut[lengthInOut-1] contain filtered samples */ float *Coef,/* (i) filter coefficients, Coef[0] is assumed to be 1.0 */ int lengthInOut,/* (i) number of input/output samples */ int orderCoef /* (i) number of filter coefficients */ ){ int n,k; for(n=0;n<lengthInOut;n++){ for(k=1;k<=orderCoef;k++){ *InOut -= Coef[k]*InOut[-k]; } InOut++; } } /*----------------------------------------------------------------* * all-zero filter *---------------------------------------------------------------*/ void AllZeroFilter( float *In, /* (i) In[0] to In[lengthInOut-1] contain filter input samples */ float *Coef,/* (i) filter coefficients (Coef[0] is assumed to be 1.0) */ int lengthInOut,/* (i) number of input/output samples */ int orderCoef, /* (i) number of filter coefficients */ float *Out /* (i/o) on entrance Out[-orderCoef] to Out[-1] contain the filter state, on exit Out[0] to Out[lengthInOut-1] contain filtered samples */ ){ int n,k; for(n=0;n<lengthInOut;n++){ *Out = Coef[0]*In[0]; for(k=1;k<=orderCoef;k++){ *Out += Coef[k]*In[-k]; } Out++; In++; } } /*----------------------------------------------------------------* * pole-zero filter *---------------------------------------------------------------*/ void ZeroPoleFilter( float *In, /* (i) In[0] to In[lengthInOut-1] contain filter input samples In[-orderCoef] to In[-1] contain state of all-zero section */ float *ZeroCoef,/* (i) filter coefficients for all-zero section (ZeroCoef[0] is assumed to be 1.0) */ float *PoleCoef,/* (i) filter coefficients for all-pole section (ZeroCoef[0] is assumed to be 1.0) */ int lengthInOut,/* (i) number of input/output samples */ int orderCoef, /* (i) number of filter coefficients */ float *Out /* (i/o) on entrance Out[-orderCoef] to Out[-1] contain state of all-pole section. On exit Out[0] to Out[lengthInOut-1] contain filtered samples */ ){ AllZeroFilter(In,ZeroCoef,lengthInOut,orderCoef,Out); AllPoleFilter(Out,PoleCoef,lengthInOut,orderCoef); } /*----------------------------------------------------------------* * downsample (LP filter and decimation) *---------------------------------------------------------------*/ void DownSample ( float *In, /* (i) input samples */ float *Coef, /* (i) filter coefficients */ int lengthIn, /* (i) number of input samples */ float *state, /* (i) filter state */ float *Out /* (o) downsampled output */ ){ float o; float *Out_ptr = Out; float *Coef_ptr, *In_ptr; float *state_ptr; int i, j, stop; /* LP filter and decimate at the same time */ for (i = DELAY_DS; i < lengthIn; i+=FACTOR_DS) { Coef_ptr = &Coef[0]; In_ptr = &In[i]; state_ptr = &state[FILTERORDER_DS-2]; o = (float)0.0; stop = (i < FILTERORDER_DS) ? i + 1 : FILTERORDER_DS; for (j = 0; j < stop; j++) { o += *Coef_ptr++ * (*In_ptr--); } for (j = i + 1; j < FILTERORDER_DS; j++) { o += *Coef_ptr++ * (*state_ptr--); } *Out_ptr++ = o; } /* Get the last part (use zeros as input for the future) */ for (i=(lengthIn+FACTOR_DS); i<(lengthIn+DELAY_DS); i+=FACTOR_DS) { o=(float)0.0; if (i<lengthIn) { Coef_ptr = &Coef[0]; In_ptr = &In[i]; for (j=0; j<FILTERORDER_DS; j++) { o += *Coef_ptr++ * (*Out_ptr--); } } else { Coef_ptr = &Coef[i-lengthIn]; In_ptr = &In[lengthIn-1]; for (j=0; j<FILTERORDER_DS-(i-lengthIn); j++) { o += *Coef_ptr++ * (*In_ptr--); } } *Out_ptr++ = o; } }