Mercurial > hg > aim92
comparison filter/recurse.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 ================================================ | |
26 recurse.c - start-up code for recursive filter | |
27 ================================================ | |
28 | |
29 | |
30 Copyright (c), 1989 The Medical Research Council, Applied Psychology Unit. | |
31 | |
32 | |
33 Author : John Holdsworth | |
34 Written : 22th March, 1989. | |
35 | |
36 Edited : | |
37 | |
38 */ | |
39 | |
40 | |
41 #include <math.h> | |
42 | |
43 #ifndef _STITCH_H_ | |
44 #include "stitch.h" | |
45 #endif | |
46 | |
47 #ifndef _RECURSE_H_ | |
48 #include "recurse.h" | |
49 #endif | |
50 | |
51 #define Pi ( 3.1415926535 ) | |
52 #define TwoPi ( 2*Pi ) | |
53 | |
54 #ifndef lint | |
55 static char *sccs_id = "@(#)recurse.c 1.8 John Holdsworth (MRC-APU) 11/8/90" ; | |
56 #endif | |
57 | |
58 static void generateSineTable() ; | |
59 static double factorial() ; | |
60 | |
61 #ifdef DSP32 | |
62 int filterSineTableBits = 8 ; | |
63 int filterSineTableShift = 0 ; | |
64 #else | |
65 int filterSineTableBits = 12 ; | |
66 int filterSineTableShift = 14 ; | |
67 #endif | |
68 unsigned long filterSineTableSize, filterSineTableMask ; | |
69 Table filterSineTable, filterCosineTable ; | |
70 | |
71 char *bstart, *bend ; | |
72 | |
73 | |
74 RecursiveFilterState *NewRecursiveFilter( samplerate, center_frequency, bandwidth, output_scale, order, phase_compensation, input_bits, sample_delay ) | |
75 double samplerate, center_frequency, bandwidth, output_scale ; | |
76 int order, phase_compensation, input_bits ; | |
77 double *sample_delay ; | |
78 { | |
79 DeclareNew( RecursiveFilterState *, filter_state ) ; | |
80 double omega ; | |
81 | |
82 if( filterSineTableSize != 1 << filterSineTableBits ) | |
83 generateSineTable() ; | |
84 | |
85 filter_state->order = order ; | |
86 filter_state->input_bits = input_bits ; | |
87 | |
88 /* compensation for nominal 6dB loss in filter */ | |
89 | |
90 filter_state->output_scale = output_scale * 2. ; | |
91 | |
92 omega = TwoPi * bandwidth / bandwidth_normalisation( filter_state->order ) ; | |
93 | |
94 /* delta phi of carrier between sample ticks */ | |
95 | |
96 filter_state->output_delta_phi = center_frequency / samplerate * ( filterSineTableSize << 16 ) + 0.5 ; | |
97 filter_state->delta_phi = filter_state->output_delta_phi ; | |
98 | |
99 /* initialise phases to give rounding */ | |
100 | |
101 ALL( filter_state->phi ) = ALL( filter_state->output_phi ) = 1l << 15 ; | |
102 | |
103 /* calculate time delay required for phase compensation selected */ | |
104 /* time advance is currently implemented as delay of */ | |
105 /* maximum advance minus desired advance */ | |
106 | |
107 if( center_frequency < samplerate / 4 ) | |
108 filter_state->over_sample = 1 ; | |
109 else { | |
110 /* if center frequency is over half the nyquist rate filtering process */ | |
111 /* is performed at twice the sampling rate to avoid aliases */ | |
112 | |
113 filter_state->over_sample = 2 ; | |
114 | |
115 ALL( filter_state->phi ) -= filter_state->delta_phi / 4 ; | |
116 #ifndef DSP32 | |
117 ALL( filter_state->phi ) &= filterSineTableMask ; | |
118 #endif | |
119 filter_state->delta_phi /= 2 ; | |
120 | |
121 /* must amplitude compensate for attenuation of high frequencies introduced by over sampling */ | |
122 | |
123 filter_state->output_scale /= ( filter_state->over_sample * cos( TwoPi * center_frequency / samplerate / 4 ) ) ; | |
124 } | |
125 | |
126 filter_state->k = ( double ) 1. - exp( -omega / samplerate / filter_state->over_sample ) ; | |
127 | |
128 /* fiddle delay time to take into acount half sample */ | |
129 /* interval advance introduced by difference equation */ | |
130 | |
131 #if 0 /* not needed any more as alternate forward and backward differences */ | |
132 | |
133 *sample_delay += filter_state->order / filter_state->over_sample / 2 ; | |
134 | |
135 /* compensate carrier phase for delay introduced above */ | |
136 | |
137 ALL( filter_state->output_phi ) += filter_state->order / filter_state->over_sample / 2 * | |
138 filter_state->delta_phi * filter_state->over_sample ; | |
139 #ifndef DSP32 | |
140 ALL( filter_state->output_phi ) &= filterSineTableMask ; | |
141 #endif | |
142 #endif | |
143 | |
144 /* munge to sin phase gammatone for mfsais */ | |
145 | |
146 ALL( filter_state->output_phi ) += 3 * filterSineTableMask / 4 ; | |
147 | |
148 /* perform required phase compensation */ | |
149 | |
150 if( phase_compensation > 0 ) | |
151 *sample_delay -= phase_compensation / center_frequency * samplerate ; | |
152 else if( phase_compensation < 0 ) | |
153 *sample_delay -= ( filter_state->order - 1. ) / omega * samplerate ; | |
154 | |
155 /* if phase compensation of type -2 or -4 is asked for the carrier phase */ | |
156 /* is shifted to be aligned with the envelope maxima */ | |
157 | |
158 if( phase_compensation == FINE_ALIGNMENT || phase_compensation <= ACUASAL + FINE_ALIGNMENT ) { | |
159 ALL( filter_state->phi ) += ( filter_state->order - 1. ) / omega * center_frequency * ( filterSineTableSize << 16 ) + 0.5 ; | |
160 #ifndef DSP32 | |
161 ALL( filter_state->phi ) &= filterSineTableMask ; | |
162 #endif | |
163 } | |
164 | |
165 /* new recurse filter coefts */ | |
166 | |
167 filter_state->gain = pow( 2 * omega / samplerate, (double) order ) * output_scale ; | |
168 filter_state->k1 = exp( -omega / samplerate ) * cos( TwoPi * center_frequency / samplerate ) ; | |
169 filter_state->k2 = exp( -2 * omega / samplerate ) ; | |
170 | |
171 /* flag channel not fully initialised */ | |
172 /* leave filter specific initialisation to specific filter code */ | |
173 | |
174 filter_state->states = ( char * ) 0 ; | |
175 | |
176 /* generate sin lookup table if necessary */ | |
177 | |
178 return ( filter_state ) ; | |
179 } | |
180 | |
181 double bandwidth_normalisation( order ) | |
182 int order ; | |
183 { | |
184 return( Pi * factorial( 2*order - 2 ) / factorial( order - 1 ) / factorial( order - 1 ) / ( 1 << ( 2 * order - 2 ) ) ) ; | |
185 } | |
186 | |
187 static double factorial( n ) | |
188 int n ; | |
189 { | |
190 double fact ; | |
191 int i ; | |
192 | |
193 fact = 1. ; | |
194 | |
195 for( i = n ; i > 1 ; i-- ) | |
196 fact *= i ; | |
197 | |
198 return( fact ) ; | |
199 } | |
200 | |
201 | |
202 static void generateSineTable() | |
203 { | |
204 static double filterTwoPi ; | |
205 register int i ; | |
206 | |
207 if( filterSineTableSize != 1 << filterSineTableBits ) | |
208 { | |
209 if( filterSineTable != ( Table ) 0 ) | |
210 stitch_free( ( Pointer ) filterSineTable ) ; | |
211 | |
212 if( filterTwoPi == 0. ) | |
213 filterTwoPi = atan( 1. ) * 8. ; | |
214 | |
215 filterSineTableSize = 1l << filterSineTableBits ; | |
216 filterSineTableMask = ( filterSineTableSize << 16 ) - 1 ; | |
217 | |
218 /* sin table 5/4 times larger than required for cosine values */ | |
219 | |
220 filterSineTable = ( Table ) stitch_malloc( ( unsigned ) ( filterSineTableSize * 5 / 4 + 1 ) * sizeof( *filterSineTable ), "recurse.c for log table" ) ; | |
221 | |
222 for( i=0 ; i <= filterSineTableSize/4 ; i++ ) { | |
223 filterSineTable[ i ] = sin( filterTwoPi * i / filterSineTableSize ) * ( 1<<filterSineTableShift ) ; | |
224 filterSineTable[ filterSineTableSize/2 - i ] = filterSineTable[ i ] ; | |
225 filterSineTable[ filterSineTableSize/2 + i ] = -filterSineTable[ i ] ; | |
226 filterSineTable[ filterSineTableSize - i ] = -filterSineTable[ i ] ; | |
227 filterSineTable[ filterSineTableSize + i ] = filterSineTable[ i ] ; | |
228 } | |
229 | |
230 filterCosineTable = filterSineTable + filterSineTableSize / 4 ; | |
231 } | |
232 | |
233 return ; | |
234 } | |
235 |