Mercurial > hg > aim92
comparison 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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:5242703e91d3 |
---|---|
1 /* | |
2 Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989 | |
3 =========================================================================== | |
4 | |
5 Permission to use, copy, modify, and distribute this software without fee | |
6 is hereby granted for research purposes, provided that this copyright | |
7 notice appears in all copies and in all supporting documentation, and that | |
8 the software is not redistributed for any fee (except for a nominal shipping | |
9 charge). Anyone wanting to incorporate all or part of this software in a | |
10 commercial product must obtain a license from the Medical Research Council. | |
11 | |
12 The MRC makes no representations about the suitability of this | |
13 software for any purpose. It is provided "as is" without express or implied | |
14 warranty. | |
15 | |
16 THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING | |
17 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE | |
18 A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY | |
19 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | |
20 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
21 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
22 */ | |
23 | |
24 /* | |
25 Acknowledgment: | |
26 ============== | |
27 | |
28 The source code provided in this file was originally developed by | |
29 Christian Giguere as part of a Ph.D degree at the Department of | |
30 Engineering of the University of Cambridge from April 1990 to | |
31 November 1993. The code was subsequently adapted under a grant | |
32 from the Hearing Research Trust for full compatibility with | |
33 AIM Release 6.15. | |
34 | |
35 Christian Giguere 25/03/94 | |
36 | |
37 */ | |
38 | |
39 /* | |
40 =========================================================== | |
41 fir.c | |
42 =========================================================== | |
43 | |
44 Finite Impulse Response (FIR) filtering module. | |
45 | |
46 Author : Christian Giguere | |
47 First written : 12th November, 1990 | |
48 Last edited : 22nd September, 1991 | |
49 | |
50 Reference: | |
51 (1) A.V.Oppenheim and R.W.Schafer (1975). Digital Signal | |
52 Processing (Prentice-Hall), Sections 4.5.5 and 5.5. | |
53 =========================================================== | |
54 */ | |
55 | |
56 | |
57 /***** includes *****/ | |
58 | |
59 #include <math.h> | |
60 #include <stdio.h> | |
61 #include "stitch.h" | |
62 #include "calc.h" | |
63 #include "calc_tl.h" | |
64 #include "fir.h" | |
65 | |
66 | |
67 /***** defines *****/ | |
68 | |
69 #define NUMBER_OF_COEFFS ( 51 ) /* odd order */ | |
70 #define NUMBER_OF_STATES ( NUMBER_OF_COEFFS ) | |
71 | |
72 | |
73 /***** functions *****/ | |
74 | |
75 /******************************************************************************* | |
76 * name: function: | |
77 * | |
78 * NewLpFIRfilter() Design of LowPass FIR filter using windowing technique | |
79 * (Hamming window). It generates the multiplier coefficients | |
80 * and initializes the states of the filter. It returns a | |
81 * pointer to a structure containing all relevant information | |
82 * for the realisation of the filter. | |
83 * | |
84 * DoFIRfilter() Direct form realisation for FIR filter of odd order linear | |
85 * phase. It is called by function ``upsample_callback()'' | |
86 * in file ``upsample.c'' once for a specified number of input | |
87 * points. It computes the filter output for each input point | |
88 * and keeps track of the filter states. | |
89 * | |
90 * CloseFIRfilter() Deletes all private data structures and arrays of the FIR | |
91 * filter upon comletion of filtering. It is called by function | |
92 * ``upsample_callback()'' in file ``upsample.c''. | |
93 ********************************************************************************/ | |
94 | |
95 | |
96 /************************* NewLpFIRfilter() *******************************/ | |
97 | |
98 FIRfilterState *NewLpFIRfilter( wc, upsample_factor, delay ) | |
99 double wc ; | |
100 int upsample_factor, *delay ; | |
101 { | |
102 DeclareNew( FIRfilterState *, filter_state ) ; | |
103 CoeffType *hn ; | |
104 double filterGain, hamming() ; | |
105 int n ; | |
106 | |
107 /***** generate and store FIR filter coefficients (linear phase, odd order, window desing technique) *****/ | |
108 filter_state->number_of_coeffs = ( NUMBER_OF_COEFFS + 1 ) / 2 ; | |
109 filter_state->coeffs = ( char * ) NewArray( CoeffType, filter_state->number_of_coeffs, "fir.c for coefficients\n" ) ; | |
110 | |
111 *delay = ( NUMBER_OF_COEFFS - 1 ) / 2 ; | |
112 hn = ( CoeffType * ) filter_state->coeffs ; | |
113 filterGain = ( double ) upsample_factor ; | |
114 | |
115 for( n = 0 ; n < filter_state->number_of_coeffs - 1 ; n++ ) | |
116 *hn++ = sin( wc * ( n - *delay ) ) / ( Pi * ( n - *delay ) ) * hamming( n, NUMBER_OF_COEFFS ) * filterGain ; | |
117 *hn = wc / Pi * filterGain ; | |
118 | |
119 | |
120 /***** initialise filter states *****/ | |
121 filter_state->number_of_states = NUMBER_OF_STATES ; | |
122 filter_state->states = ( char * ) NewZeroedArray( StateType, NUMBER_OF_STATES, "fir.c for filter states\n" ) ; | |
123 | |
124 | |
125 /***** return *****/ | |
126 return( filter_state ) ; | |
127 } | |
128 | |
129 | |
130 /****************************** DoFIRfilter() *******************************/ | |
131 | |
132 void DoFIRfilter( filter_state, inoutput, points ) | |
133 FIRfilterState *filter_state ; | |
134 DataType *inoutput ; | |
135 int points ; | |
136 { | |
137 register StateType *st = ( StateType * ) filter_state->states ; | |
138 register CoeffType *cf = ( CoeffType * ) filter_state->coeffs ; | |
139 register DataType *inout_ptr = inoutput ; | |
140 register double acc ; | |
141 register int n, Ns = filter_state->number_of_states ; | |
142 register int Nc = filter_state->number_of_coeffs ; | |
143 | |
144 /***** for all points *****/ | |
145 for( ; points > 0 ; points-- ) { | |
146 acc = 0. ; | |
147 | |
148 /*** shift the states ***/ | |
149 for( n = Ns - 1 ; n > 0 ; n-- ) | |
150 st[n] = st[n-1] ; | |
151 st[0] = *inout_ptr ; | |
152 | |
153 /*** filter current point ***/ | |
154 for( n = 0 ; n < Nc - 1 ; n++ ) | |
155 acc += cf[n] * ( st[n] + st[Ns-1-n] ) ; | |
156 acc += cf[n] * st[n] ; | |
157 | |
158 /*** store output point ***/ | |
159 *inout_ptr++ = acc ; | |
160 } | |
161 | |
162 /***** return *****/ | |
163 return ; | |
164 | |
165 } | |
166 | |
167 /************************* CloseFIRfilter() *******************************/ | |
168 | |
169 void CloseFIRfilter( filter_state ) | |
170 FIRfilterState *filter_state ; | |
171 { | |
172 Delete( filter_state->states ) ; | |
173 Delete( filter_state->coeffs ) ; | |
174 Delete( filter_state ) ; | |
175 | |
176 return ; | |
177 | |
178 } | |
179 | |
180 | |
181 /*********************** low level functions ***********************/ | |
182 | |
183 double hamming( n, N ) | |
184 int n, N ; | |
185 { | |
186 return ( 0.54 - 0.46 * cos( TwoPi * n / ( N - 1. ) ) ) ; | |
187 } | |
188 |