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. ) ) ) ;
+}
+