Mercurial > hg > aim92
diff wdf/fir.c @ 0:5242703e91d3 tip
Initial checkin for AIM92 aimR8.2 (last updated May 1997).
author | tomwalters |
---|---|
date | Fri, 20 May 2011 15:19:45 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wdf/fir.c Fri May 20 15:19:45 2011 +0100 @@ -0,0 +1,188 @@ +/* + Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989 + =========================================================================== + + Permission to use, copy, modify, and distribute this software without fee + is hereby granted for research purposes, provided that this copyright + notice appears in all copies and in all supporting documentation, and that + the software is not redistributed for any fee (except for a nominal shipping + charge). Anyone wanting to incorporate all or part of this software in a + commercial product must obtain a license from the Medical Research Council. + + The MRC makes no representations about the suitability of this + software for any purpose. It is provided "as is" without express or implied + warranty. + + THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE + A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +/* + Acknowledgment: + ============== + + The source code provided in this file was originally developed by + Christian Giguere as part of a Ph.D degree at the Department of + Engineering of the University of Cambridge from April 1990 to + November 1993. The code was subsequently adapted under a grant + from the Hearing Research Trust for full compatibility with + AIM Release 6.15. + + Christian Giguere 25/03/94 + +*/ + +/* + =========================================================== + fir.c + =========================================================== + + Finite Impulse Response (FIR) filtering module. + + Author : Christian Giguere + First written : 12th November, 1990 + Last edited : 22nd September, 1991 + + Reference: + (1) A.V.Oppenheim and R.W.Schafer (1975). Digital Signal + Processing (Prentice-Hall), Sections 4.5.5 and 5.5. + =========================================================== +*/ + + +/***** includes *****/ + +#include <math.h> +#include <stdio.h> +#include "stitch.h" +#include "calc.h" +#include "calc_tl.h" +#include "fir.h" + + +/***** defines *****/ + +#define NUMBER_OF_COEFFS ( 51 ) /* odd order */ +#define NUMBER_OF_STATES ( NUMBER_OF_COEFFS ) + + +/***** functions *****/ + +/******************************************************************************* +* name: function: +* +* NewLpFIRfilter() Design of LowPass FIR filter using windowing technique +* (Hamming window). It generates the multiplier coefficients +* and initializes the states of the filter. It returns a +* pointer to a structure containing all relevant information +* for the realisation of the filter. +* +* DoFIRfilter() Direct form realisation for FIR filter of odd order linear +* phase. It is called by function ``upsample_callback()'' +* in file ``upsample.c'' once for a specified number of input +* points. It computes the filter output for each input point +* and keeps track of the filter states. +* +* CloseFIRfilter() Deletes all private data structures and arrays of the FIR +* filter upon comletion of filtering. It is called by function +* ``upsample_callback()'' in file ``upsample.c''. +********************************************************************************/ + + +/************************* NewLpFIRfilter() *******************************/ + +FIRfilterState *NewLpFIRfilter( wc, upsample_factor, delay ) + double wc ; + int upsample_factor, *delay ; +{ + DeclareNew( FIRfilterState *, filter_state ) ; + CoeffType *hn ; + double filterGain, hamming() ; + int n ; + + /***** generate and store FIR filter coefficients (linear phase, odd order, window desing technique) *****/ + filter_state->number_of_coeffs = ( NUMBER_OF_COEFFS + 1 ) / 2 ; + filter_state->coeffs = ( char * ) NewArray( CoeffType, filter_state->number_of_coeffs, "fir.c for coefficients\n" ) ; + + *delay = ( NUMBER_OF_COEFFS - 1 ) / 2 ; + hn = ( CoeffType * ) filter_state->coeffs ; + filterGain = ( double ) upsample_factor ; + + for( n = 0 ; n < filter_state->number_of_coeffs - 1 ; n++ ) + *hn++ = sin( wc * ( n - *delay ) ) / ( Pi * ( n - *delay ) ) * hamming( n, NUMBER_OF_COEFFS ) * filterGain ; + *hn = wc / Pi * filterGain ; + + + /***** initialise filter states *****/ + filter_state->number_of_states = NUMBER_OF_STATES ; + filter_state->states = ( char * ) NewZeroedArray( StateType, NUMBER_OF_STATES, "fir.c for filter states\n" ) ; + + + /***** return *****/ + return( filter_state ) ; +} + + +/****************************** DoFIRfilter() *******************************/ + +void DoFIRfilter( filter_state, inoutput, points ) + FIRfilterState *filter_state ; + DataType *inoutput ; + int points ; +{ + register StateType *st = ( StateType * ) filter_state->states ; + register CoeffType *cf = ( CoeffType * ) filter_state->coeffs ; + register DataType *inout_ptr = inoutput ; + register double acc ; + register int n, Ns = filter_state->number_of_states ; + register int Nc = filter_state->number_of_coeffs ; + + /***** for all points *****/ + for( ; points > 0 ; points-- ) { + acc = 0. ; + + /*** shift the states ***/ + for( n = Ns - 1 ; n > 0 ; n-- ) + st[n] = st[n-1] ; + st[0] = *inout_ptr ; + + /*** filter current point ***/ + for( n = 0 ; n < Nc - 1 ; n++ ) + acc += cf[n] * ( st[n] + st[Ns-1-n] ) ; + acc += cf[n] * st[n] ; + + /*** store output point ***/ + *inout_ptr++ = acc ; + } + + /***** return *****/ + return ; + +} + +/************************* CloseFIRfilter() *******************************/ + +void CloseFIRfilter( filter_state ) + FIRfilterState *filter_state ; +{ + Delete( filter_state->states ) ; + Delete( filter_state->coeffs ) ; + Delete( filter_state ) ; + + return ; + +} + + +/*********************** low level functions ***********************/ + +double hamming( n, N ) + int n, N ; +{ + return ( 0.54 - 0.46 * cos( TwoPi * n / ( N - 1. ) ) ) ; +} +