tomwalters@0
|
1 /*
|
tomwalters@0
|
2 Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989
|
tomwalters@0
|
3 ===========================================================================
|
tomwalters@0
|
4
|
tomwalters@0
|
5 Permission to use, copy, modify, and distribute this software without fee
|
tomwalters@0
|
6 is hereby granted for research purposes, provided that this copyright
|
tomwalters@0
|
7 notice appears in all copies and in all supporting documentation, and that
|
tomwalters@0
|
8 the software is not redistributed for any fee (except for a nominal shipping
|
tomwalters@0
|
9 charge). Anyone wanting to incorporate all or part of this software in a
|
tomwalters@0
|
10 commercial product must obtain a license from the Medical Research Council.
|
tomwalters@0
|
11
|
tomwalters@0
|
12 The MRC makes no representations about the suitability of this
|
tomwalters@0
|
13 software for any purpose. It is provided "as is" without express or implied
|
tomwalters@0
|
14 warranty.
|
tomwalters@0
|
15
|
tomwalters@0
|
16 */
|
tomwalters@0
|
17
|
tomwalters@0
|
18 /*
|
tomwalters@0
|
19 ========================================================
|
tomwalters@0
|
20 generic.c generic C code for recursive filter section.
|
tomwalters@0
|
21 ========================================================
|
tomwalters@0
|
22
|
tomwalters@0
|
23
|
tomwalters@0
|
24 J. Holdsworth - 23rd February 1988.
|
tomwalters@0
|
25
|
tomwalters@0
|
26
|
tomwalters@0
|
27 Copywright (c) Applied Psychology Unit, Medical Research Council. 1988.
|
tomwalters@0
|
28 =======================================================================
|
tomwalters@0
|
29
|
tomwalters@0
|
30
|
tomwalters@0
|
31 Release 2: 5th July 1988.
|
tomwalters@0
|
32 Rewrite : 21st Jan 1989.
|
tomwalters@0
|
33
|
tomwalters@0
|
34 */
|
tomwalters@0
|
35
|
tomwalters@0
|
36 #ifndef _MATH_H_
|
tomwalters@0
|
37 #include <math.h>
|
tomwalters@0
|
38 #define _MATH_H_
|
tomwalters@0
|
39 #endif
|
tomwalters@0
|
40
|
tomwalters@0
|
41 #ifndef _STITCH_H_
|
tomwalters@0
|
42 #include "stitch.h"
|
tomwalters@0
|
43 #endif
|
tomwalters@0
|
44 #ifndef _RECURSE_H_
|
tomwalters@0
|
45 #include "recurse.h"
|
tomwalters@0
|
46 #endif
|
tomwalters@0
|
47 #ifndef _PHASE_H_
|
tomwalters@0
|
48 #include "phase.h"
|
tomwalters@0
|
49 #endif
|
tomwalters@0
|
50 #ifndef _GAMMA_TONE_H_
|
tomwalters@0
|
51 #include "gamma_tone.h"
|
tomwalters@0
|
52 #endif
|
tomwalters@0
|
53
|
tomwalters@0
|
54 #ifndef FLOAT
|
tomwalters@0
|
55
|
tomwalters@0
|
56 #define STATE_TYPE long
|
tomwalters@0
|
57
|
tomwalters@0
|
58 #define I_SHIFT( _number ) ( ( _number ) << i_shift )
|
tomwalters@0
|
59
|
tomwalters@0
|
60 #ifdef vax
|
tomwalters@0
|
61 #define K_SHIFT( _number ) ( ( _number ) << k_shift )
|
tomwalters@0
|
62 #define S_SHIFT( _number ) ( ( _number ) << s_shift )
|
tomwalters@0
|
63 #else
|
tomwalters@0
|
64 #define K_SHIFT( _number ) ( ( _number ) >> k_shift )
|
tomwalters@0
|
65 #define S_SHIFT( _number ) ( ( _number ) >> s_shift )
|
tomwalters@0
|
66 #endif
|
tomwalters@0
|
67
|
tomwalters@0
|
68 #else
|
tomwalters@0
|
69
|
tomwalters@0
|
70 #define STATE_TYPE FLOAT
|
tomwalters@0
|
71
|
tomwalters@0
|
72 #define I_SHIFT( _number ) ( _number )
|
tomwalters@0
|
73 #define K_SHIFT( _number ) ( _number )
|
tomwalters@0
|
74 #define S_SHIFT( _number ) ( _number )
|
tomwalters@0
|
75
|
tomwalters@0
|
76 #endif
|
tomwalters@0
|
77
|
tomwalters@0
|
78 #ifndef INPUT_TYPE
|
tomwalters@0
|
79 #define INPUT_TYPE short
|
tomwalters@0
|
80 #endif
|
tomwalters@0
|
81
|
tomwalters@0
|
82 #ifndef OUTPUT_TYPE
|
tomwalters@0
|
83 #define OUTPUT_TYPE INPUT_TYPE
|
tomwalters@0
|
84 #endif
|
tomwalters@0
|
85
|
tomwalters@0
|
86 #ifndef MODULE_NAME
|
tomwalters@0
|
87 #define MODULE_NAME DoFilterShortDataArray
|
tomwalters@0
|
88 #define FILTER_NAME FilterShortDataArray
|
tomwalters@0
|
89 #endif
|
tomwalters@0
|
90
|
tomwalters@0
|
91 #ifdef DSP32
|
tomwalters@0
|
92
|
tomwalters@0
|
93 #define SIN( _PHI ) ( *( (float *) ( (char *) sin_table + istore ) ) )
|
tomwalters@0
|
94 #define COS( _PHI ) ( *( (float *) ( (char *) cos_table + istore ) ) )
|
tomwalters@0
|
95
|
tomwalters@0
|
96 #else
|
tomwalters@0
|
97
|
tomwalters@0
|
98 #define SIN( _PHI ) ( sin_table[ HI( _PHI ) ] )
|
tomwalters@0
|
99 #define COS( _PHI ) ( cos_table[ HI( _PHI ) ] )
|
tomwalters@0
|
100
|
tomwalters@0
|
101 #endif
|
tomwalters@0
|
102
|
tomwalters@0
|
103 /* Code that performs the actual filtering */
|
tomwalters@0
|
104
|
tomwalters@0
|
105 PointCount MODULE_NAME( filter_states, delays, input, output, points, channels )
|
tomwalters@0
|
106 RecursiveFilterState **filter_states ;
|
tomwalters@0
|
107 int *delays ;
|
tomwalters@0
|
108 INPUT_TYPE *input ;
|
tomwalters@0
|
109 OUTPUT_TYPE *output ;
|
tomwalters@0
|
110 int points, channels ;
|
tomwalters@0
|
111 {
|
tomwalters@0
|
112 extern char *bstart, *bend ;
|
tomwalters@0
|
113 #ifdef DSP32
|
tomwalters@0
|
114 /* do not change the order of these definitions - the "asm()" calls depend on it */
|
tomwalters@0
|
115 register STATE_TYPE k, *states_ptr, *states_out, *states_end, *ptr ;
|
tomwalters@0
|
116 #else
|
tomwalters@0
|
117 register STATE_TYPE *states_ptr, *states_end, store, rstore, istore, k ;
|
tomwalters@0
|
118 #endif
|
tomwalters@0
|
119 register RecursiveFilterState *filter_state ;
|
tomwalters@0
|
120 #ifndef FLOAT
|
tomwalters@0
|
121 register int k_shift, s_shift, i_shift ;
|
tomwalters@0
|
122 #endif
|
tomwalters@0
|
123 #ifdef DSP32
|
tomwalters@0
|
124 register int istore ;
|
tomwalters@0
|
125 #endif
|
tomwalters@0
|
126 register Table sin_table, cos_table ;
|
tomwalters@0
|
127 register STATE_TYPE output_store, input_store ;
|
tomwalters@0
|
128 #ifdef COMPLEX
|
tomwalters@0
|
129 register STATE_TYPE ioutput_store ;
|
tomwalters@0
|
130 #endif
|
tomwalters@0
|
131 register OUTPUT_TYPE *output_ptr, *end ;
|
tomwalters@0
|
132 register INPUT_TYPE *input_ptr ;
|
tomwalters@0
|
133 int loop_count, channel ;
|
tomwalters@0
|
134 #ifdef DSP32
|
tomwalters@0
|
135 #ifndef ASM
|
tomwalters@0
|
136 STATE_TYPE a0, a1 ;
|
tomwalters@0
|
137 #endif
|
tomwalters@0
|
138 #endif
|
tomwalters@0
|
139 /* set up register pointers for speed of inner loop */
|
tomwalters@0
|
140
|
tomwalters@0
|
141 sin_table = filterSineTable ;
|
tomwalters@0
|
142 cos_table = filterCosineTable ;
|
tomwalters@0
|
143
|
tomwalters@0
|
144 end = output + points * channels ;
|
tomwalters@0
|
145
|
tomwalters@0
|
146 /* for all channels */
|
tomwalters@0
|
147
|
tomwalters@0
|
148 for( channel=0 ; channel < channels ; channel++ ) {
|
tomwalters@0
|
149
|
tomwalters@0
|
150 filter_state = filter_states[ channel ] ;
|
tomwalters@0
|
151
|
tomwalters@0
|
152 #ifndef FLOAT
|
tomwalters@0
|
153 i_shift = 16 - filter_state->input_bits ;
|
tomwalters@0
|
154 k_shift = 16 - 2 ;
|
tomwalters@0
|
155
|
tomwalters@0
|
156 s_shift = filterSineTableShift ;
|
tomwalters@0
|
157 #endif
|
tomwalters@0
|
158
|
tomwalters@0
|
159 /* if first time then perform implementation specific initialisation */
|
tomwalters@0
|
160
|
tomwalters@0
|
161 if( filter_state->states == (Pointer) 0 ) {
|
tomwalters@0
|
162
|
tomwalters@0
|
163 filter_state->states = stitch_ralloc( (unsigned) ( filter_state->order + 1 ) * 2 * sizeof ( STATE_TYPE ), "generic.c for filter states" ) ;
|
tomwalters@0
|
164
|
tomwalters@0
|
165 /* filter state stored in form of complex phasor for each cascade of filter */
|
tomwalters@0
|
166 /* real and imaginary state values interleaved in state array */
|
tomwalters@0
|
167
|
tomwalters@0
|
168 filter_state->states_end = (Pointer) ( (STATE_TYPE *) filter_state->states + ( filter_state->order + 1 ) * 2 ) ;
|
tomwalters@0
|
169
|
tomwalters@0
|
170 stitch_bzero( filter_state->states, (int) ( filter_state->states_end - filter_state->states ) ) ;
|
tomwalters@0
|
171
|
tomwalters@0
|
172 #ifdef FLOAT
|
tomwalters@0
|
173 filter_state->output_scale /= ( 1l << filterSineTableShift ) ;
|
tomwalters@0
|
174 #ifdef ENVELOPE
|
tomwalters@0
|
175 filter_state->post_log = -log10( filter_state->output_scale ) * 2000. ;
|
tomwalters@0
|
176 #else
|
tomwalters@0
|
177 filter_state->output_scale /= ( 1l << filterSineTableShift ) ;
|
tomwalters@0
|
178 #endif
|
tomwalters@0
|
179 #else
|
tomwalters@0
|
180 filter_state->ik = filter_state->k * ( 1l << k_shift ) + 0.5 ;
|
tomwalters@0
|
181 filter_state->post_divisor = ( 1l << ( filterSineTableShift + i_shift ) ) / filter_state->output_scale + 0.5 ;
|
tomwalters@0
|
182 #ifdef ENVELOPE
|
tomwalters@0
|
183 filter_state->post_log = imB( (long) filter_state->post_divisor ) - imB( 1l << filterSineTableShift ) ;
|
tomwalters@0
|
184 #endif
|
tomwalters@0
|
185 #endif
|
tomwalters@0
|
186 #ifdef ENVELOPE
|
tomwalters@0
|
187 filter_state->post_log -= ( filter_state->over_sample - 1 ) * imB( 2l ) / 2 ;
|
tomwalters@0
|
188 #endif
|
tomwalters@0
|
189 }
|
tomwalters@0
|
190
|
tomwalters@0
|
191 #ifdef FLOAT
|
tomwalters@0
|
192 k = filter_state->k ;
|
tomwalters@0
|
193 #else
|
tomwalters@0
|
194 k = filter_state->ik ;
|
tomwalters@0
|
195 #ifdef vax
|
tomwalters@0
|
196 k_shift = -k_shift ;
|
tomwalters@0
|
197 s_shift = -s_shift ;
|
tomwalters@0
|
198 #endif
|
tomwalters@0
|
199 #endif
|
tomwalters@0
|
200
|
tomwalters@0
|
201
|
tomwalters@0
|
202 /* Eurgh - the price of compatability */
|
tomwalters@0
|
203
|
tomwalters@0
|
204 if( input == (INPUT_TYPE *) 0 ) {
|
tomwalters@0
|
205 input_ptr = (INPUT_TYPE *) output ;
|
tomwalters@0
|
206
|
tomwalters@0
|
207 stitch_bzero( input_ptr, ( end - output ) / channels * sizeof ( *input_ptr ) ) ;
|
tomwalters@0
|
208 }
|
tomwalters@0
|
209 else
|
tomwalters@0
|
210 input_ptr = input - delays[ channel ] ;
|
tomwalters@0
|
211
|
tomwalters@0
|
212 /* not required to test bank.c any more
|
tomwalters@0
|
213 if( (char *) input_ptr < bstart || (char *) ( input_ptr + points ) > bend )
|
tomwalters@0
|
214 printf( "Filter bank error!! %x %x %x\n", bstart, input_ptr, bend ) ;
|
tomwalters@0
|
215 */
|
tomwalters@0
|
216 states_end = (STATE_TYPE *) filter_state->states_end ;
|
tomwalters@0
|
217
|
tomwalters@0
|
218 #ifdef DSP32
|
tomwalters@0
|
219 /* this section is optimised for DSP32 processor with more registers than instructions */
|
tomwalters@0
|
220
|
tomwalters@0
|
221 for( output_ptr = output + channel ; output_ptr < end ; output_ptr += channels ) {
|
tomwalters@0
|
222
|
tomwalters@0
|
223 input_store = I_SHIFT( *input_ptr++ ) ;
|
tomwalters@0
|
224 output_store = 0 ;
|
tomwalters@0
|
225 #ifdef COMPLEX
|
tomwalters@0
|
226 ioutput_store = 0 ;
|
tomwalters@0
|
227 #endif
|
tomwalters@0
|
228
|
tomwalters@0
|
229 loop_count = filter_state->over_sample ;
|
tomwalters@0
|
230
|
tomwalters@0
|
231 do
|
tomwalters@0
|
232 {
|
tomwalters@0
|
233 /* multipy by complex phasor */
|
tomwalters@0
|
234
|
tomwalters@0
|
235 ptr = &input_store ;
|
tomwalters@0
|
236
|
tomwalters@0
|
237 istore = HI( filter_state->phi ) << 1 << 1 ;
|
tomwalters@0
|
238
|
tomwalters@0
|
239 #ifdef ASM
|
tomwalters@0
|
240 asm( "r1e = r6 + r8" ) ;
|
tomwalters@0
|
241 asm( "a0 = *r10 * *r1" ) ;
|
tomwalters@0
|
242 asm( "r2e = r7 + r8" ) ;
|
tomwalters@0
|
243 asm( "a1 = *r10 * *r2" ) ;
|
tomwalters@0
|
244 #else
|
tomwalters@0
|
245 a0 = *ptr * COS( filter_state->phi ) ;
|
tomwalters@0
|
246 a1 = *ptr * SIN( filter_state->phi ) ;
|
tomwalters@0
|
247 #endif
|
tomwalters@0
|
248
|
tomwalters@0
|
249 /* low pass filter by simple alfa decay difference equation */
|
tomwalters@0
|
250
|
tomwalters@0
|
251 states_ptr = (STATE_TYPE *) filter_state->states ;
|
tomwalters@0
|
252 states_out = states_ptr ;
|
tomwalters@0
|
253
|
tomwalters@0
|
254 #ifdef ASM
|
tomwalters@0
|
255 asm( "LOOP:" ) ;
|
tomwalters@0
|
256 asm( "a0 = a0 - *r13++" ) ;
|
tomwalters@0
|
257 asm( "a1 = a1 - *r13++" ) ;
|
tomwalters@0
|
258 asm( "nop" ) ;
|
tomwalters@0
|
259 asm( "*r12++ = a0 = *r12 + a3 * a0" ) ;
|
tomwalters@0
|
260 asm( "r13e - r11" ) ;
|
tomwalters@0
|
261 asm( "if(cc) goto EXIT" );
|
tomwalters@0
|
262 asm( "*r12++ = a1 = *r12 + a3 * a1" ) ;
|
tomwalters@0
|
263
|
tomwalters@0
|
264 asm( " a2 = a0 - *r13++ " ) ;
|
tomwalters@0
|
265 asm( " a1 = a1 - *r13++ " ) ;
|
tomwalters@0
|
266 asm( " a0 = *r12 " ) ;
|
tomwalters@0
|
267 asm( "*r12++ = a2 = *r12 + a3 * a2" ) ;
|
tomwalters@0
|
268 asm( " a2 = a1 " ) ;
|
tomwalters@0
|
269 asm( " a1 = *r12 " ) ;
|
tomwalters@0
|
270 asm( "r13e - r11" ) ;
|
tomwalters@0
|
271 asm( "if(cs) goto LOOP" );
|
tomwalters@0
|
272 asm( "*r12++ = a2 = *r12 + a3 * a2" ) ;
|
tomwalters@0
|
273 asm( "EXIT:" ) ;
|
tomwalters@0
|
274 #else
|
tomwalters@0
|
275 do
|
tomwalters@0
|
276 {
|
tomwalters@0
|
277 a0 = a0 - *states_ptr++ ;
|
tomwalters@0
|
278 a1 = a1 - *states_ptr++ ;
|
tomwalters@0
|
279 a0 = *states_out++ += k * a0 ;
|
tomwalters@0
|
280 a1 = *states_out++ += k * a1 ;
|
tomwalters@0
|
281 }
|
tomwalters@0
|
282 while( states_ptr < states_end ) ;
|
tomwalters@0
|
283 /* multiply back up to carrier frequency */
|
tomwalters@0
|
284 #endif
|
tomwalters@0
|
285 istore = HI( filter_state->output_phi ) << 1 << 1 ;
|
tomwalters@0
|
286
|
tomwalters@0
|
287 #ifndef ENVELOPE
|
tomwalters@0
|
288 #ifdef ASM
|
tomwalters@0
|
289 asm( "r1e = r6 + r8" ) ;
|
tomwalters@0
|
290 asm( "a2 = a2 + a0 * *r1" ) ;
|
tomwalters@0
|
291 asm( "r2e = r7 + r8" ) ;
|
tomwalters@0
|
292 asm( "a2 = a2 + a1 * *r2" ) ;
|
tomwalters@0
|
293 #else
|
tomwalters@0
|
294 output_store += a0 * COS( filter_state->output_phi ) ;
|
tomwalters@0
|
295 output_store += a1 * SIN( filter_state->output_phi ) ;
|
tomwalters@0
|
296 #endif
|
tomwalters@0
|
297 #ifdef COMPLEX
|
tomwalters@0
|
298 ptr = &ioutput_store ;
|
tomwalters@0
|
299 #ifdef ASM
|
tomwalters@0
|
300 asm( " a0 = *r10 + a0 * *r2" ) ;
|
tomwalters@0
|
301 asm( "*r10 = a0 = a0 - a1 * *r1" ) ;
|
tomwalters@0
|
302 #else
|
tomwalters@0
|
303 ioutput_store += a0 * SIN( filter_state->output_phi ) ;
|
tomwalters@0
|
304 ioutput_store -= a1 * COS( filter_state->output_phi ) ;
|
tomwalters@0
|
305 #endif
|
tomwalters@0
|
306 #endif
|
tomwalters@0
|
307 #else ENVELOPE
|
tomwalters@0
|
308 #ifdef ASM
|
tomwalters@0
|
309 asm( "a2 = a2 + a1 * a1" ) ;
|
tomwalters@0
|
310 asm( "a2 = a2 + a0 * a0" ) ;
|
tomwalters@0
|
311 #else
|
tomwalters@0
|
312 output_store += a0 * a0 ;
|
tomwalters@0
|
313 output_store += a1 * a1 ;
|
tomwalters@0
|
314 #endif
|
tomwalters@0
|
315 #endif ENVELOPE
|
tomwalters@0
|
316
|
tomwalters@0
|
317 ALL( filter_state->phi ) += filter_state->delta_phi ;
|
tomwalters@0
|
318 }
|
tomwalters@0
|
319 while( --loop_count > 0 ) ;
|
tomwalters@0
|
320 /* do it again if over sampling */
|
tomwalters@0
|
321
|
tomwalters@0
|
322 #else
|
tomwalters@0
|
323 /* this section optimised for generall purpose processor e.g. vax or 68000 */
|
tomwalters@0
|
324
|
tomwalters@0
|
325 for( output_ptr = output + channel ; output_ptr < end ; output_ptr += channels ) {
|
tomwalters@0
|
326
|
tomwalters@0
|
327 input_store = I_SHIFT( *input_ptr++ ) ;
|
tomwalters@0
|
328
|
tomwalters@0
|
329 output_store = 0 ;
|
tomwalters@0
|
330 #ifdef COMPLEX
|
tomwalters@0
|
331 ioutput_store = 0 ;
|
tomwalters@0
|
332 #endif
|
tomwalters@0
|
333 loop_count = filter_state->over_sample ;
|
tomwalters@0
|
334
|
tomwalters@0
|
335 do
|
tomwalters@0
|
336 {
|
tomwalters@0
|
337 /* multipy by complex phasor */
|
tomwalters@0
|
338
|
tomwalters@0
|
339 states_ptr = (STATE_TYPE *) filter_state->states + 2 ;
|
tomwalters@0
|
340
|
tomwalters@0
|
341 rstore = input_store * COS( filter_state->phi ) ;
|
tomwalters@0
|
342 istore = input_store * SIN( filter_state->phi ) ;
|
tomwalters@0
|
343
|
tomwalters@0
|
344 do
|
tomwalters@0
|
345 {
|
tomwalters@0
|
346 rstore = *states_ptr + k * K_SHIFT( rstore - *states_ptr ) ;
|
tomwalters@0
|
347 *states_ptr++ = rstore ;
|
tomwalters@0
|
348
|
tomwalters@0
|
349 istore = *states_ptr + k * K_SHIFT( istore - *states_ptr ) ;
|
tomwalters@0
|
350 *states_ptr++ = istore ;
|
tomwalters@0
|
351
|
tomwalters@0
|
352 if( states_ptr < states_end ) {
|
tomwalters@0
|
353 store = k * K_SHIFT( rstore - *states_ptr ) ;
|
tomwalters@0
|
354 rstore = *states_ptr ;
|
tomwalters@0
|
355 *states_ptr++ = rstore + store ;
|
tomwalters@0
|
356
|
tomwalters@0
|
357 store = k * K_SHIFT( istore - *states_ptr ) ;
|
tomwalters@0
|
358 istore = *states_ptr ;
|
tomwalters@0
|
359 *states_ptr++ = istore + store ;
|
tomwalters@0
|
360 }
|
tomwalters@0
|
361 }
|
tomwalters@0
|
362 while( states_ptr < states_end ) ;
|
tomwalters@0
|
363 /*
|
tomwalters@0
|
364 *states_ptr++ = input_store * COS( filter_state->phi ) ;
|
tomwalters@0
|
365 *states_ptr++ = input_store * SIN( filter_state->phi ) ;
|
tomwalters@0
|
366
|
tomwalters@0
|
367 do
|
tomwalters@0
|
368 {
|
tomwalters@0
|
369 store = k * K_SHIFT( states_ptr[ -2 ] - *states_ptr ) ;
|
tomwalters@0
|
370 *states_ptr++ += store ;
|
tomwalters@0
|
371 store = k * K_SHIFT( states_ptr[ -2 ] - *states_ptr ) ;
|
tomwalters@0
|
372 *states_ptr++ += store ;
|
tomwalters@0
|
373 }
|
tomwalters@0
|
374 while( states_ptr < states_end ) ;
|
tomwalters@0
|
375 */
|
tomwalters@0
|
376 /* multiply back up to carrier frequency */
|
tomwalters@0
|
377
|
tomwalters@0
|
378 #ifdef ENVELOPE
|
tomwalters@0
|
379 istore = S_SHIFT( istore ) ;
|
tomwalters@0
|
380 output_store += istore * istore ;
|
tomwalters@0
|
381 rstore = S_SHIFT( rstore ) ;
|
tomwalters@0
|
382 output_store += rstore * rstore ;
|
tomwalters@0
|
383 #else
|
tomwalters@0
|
384 output_store += S_SHIFT( istore ) * SIN( filter_state->output_phi ) ;
|
tomwalters@0
|
385 output_store += S_SHIFT( rstore ) * COS( filter_state->output_phi ) ;
|
tomwalters@0
|
386 #ifdef COMPLEX
|
tomwalters@0
|
387 ioutput_store -= S_SHIFT( istore ) * COS( filter_state->output_phi ) ;
|
tomwalters@0
|
388 ioutput_store += S_SHIFT( rstore ) * SIN( filter_state->output_phi ) ;
|
tomwalters@0
|
389 #endif
|
tomwalters@0
|
390 #endif
|
tomwalters@0
|
391 ALL( filter_state->phi ) += filter_state->delta_phi ;
|
tomwalters@0
|
392 ALL( filter_state->phi ) &= filterSineTableMask ;
|
tomwalters@0
|
393 }
|
tomwalters@0
|
394 while( --loop_count > 0 ) ;
|
tomwalters@0
|
395 /* do it again if over sampling */
|
tomwalters@0
|
396 #endif
|
tomwalters@0
|
397
|
tomwalters@0
|
398 /* common tail end */
|
tomwalters@0
|
399
|
tomwalters@0
|
400 #ifdef ENVELOPE
|
tomwalters@0
|
401 #ifdef FLOAT
|
tomwalters@0
|
402 if( output_store < 1. )
|
tomwalters@0
|
403 *output_ptr = LOG_ZERO ;
|
tomwalters@0
|
404 else
|
tomwalters@0
|
405 *output_ptr = log10( output_store ) * 1000. - filter_state->post_log ;
|
tomwalters@0
|
406
|
tomwalters@0
|
407 if( *output_ptr < 0. )
|
tomwalters@0
|
408 *output_ptr = 0. ;
|
tomwalters@0
|
409 #else
|
tomwalters@0
|
410 *output_ptr = ( imB( (long) output_store ) >> 1 ) - filter_state->post_log ;
|
tomwalters@0
|
411
|
tomwalters@0
|
412 if( *output_ptr < 0 )
|
tomwalters@0
|
413 *output_ptr = 0 ;
|
tomwalters@0
|
414 #endif
|
tomwalters@0
|
415 #else
|
tomwalters@0
|
416 /* for non-envelope output */
|
tomwalters@0
|
417
|
tomwalters@0
|
418 ALL( filter_state->output_phi ) += filter_state->output_delta_phi ;
|
tomwalters@0
|
419 #ifndef DSP32
|
tomwalters@0
|
420 ALL( filter_state->output_phi ) &= filterSineTableMask ;
|
tomwalters@0
|
421 #endif
|
tomwalters@0
|
422
|
tomwalters@0
|
423 /* scale output_ptr back down for output_ptr array compensating for over sampling if ness. */
|
tomwalters@0
|
424
|
tomwalters@0
|
425 #ifdef COMPLEX
|
tomwalters@0
|
426 #ifdef FLOAT
|
tomwalters@0
|
427 output_ptr->real = output_store * filter_state->output_scale ;
|
tomwalters@0
|
428 output_ptr->imag = ioutput_store * filter_state->output_scale ;
|
tomwalters@0
|
429 #else
|
tomwalters@0
|
430 output_ptr->real = output_store / filter_state->post_divisor ;
|
tomwalters@0
|
431 output_ptr->imag = ioutput_store / filter_state->post_divisor ;
|
tomwalters@0
|
432 #endif
|
tomwalters@0
|
433 #else
|
tomwalters@0
|
434 #ifdef FLOAT
|
tomwalters@0
|
435 *output_ptr = output_store * filter_state->output_scale ;
|
tomwalters@0
|
436 #else
|
tomwalters@0
|
437 *output_ptr = output_store / filter_state->post_divisor ;
|
tomwalters@0
|
438 #endif
|
tomwalters@0
|
439 #endif
|
tomwalters@0
|
440 #endif
|
tomwalters@0
|
441 }
|
tomwalters@0
|
442 }
|
tomwalters@0
|
443
|
tomwalters@0
|
444 return( sizeof ( OUTPUT_TYPE ) ) ;
|
tomwalters@0
|
445 }
|
tomwalters@0
|
446
|
tomwalters@0
|
447 /* for compatability */
|
tomwalters@0
|
448
|
tomwalters@0
|
449 PointCount FILTER_NAME( compensator_state, input_array, output_array, npoints )
|
tomwalters@0
|
450 FilterChannelInfo *compensator_state ;
|
tomwalters@0
|
451 INPUT_TYPE *input_array ;
|
tomwalters@0
|
452 OUTPUT_TYPE *output_array ;
|
tomwalters@0
|
453 PointCount npoints ;
|
tomwalters@0
|
454 {
|
tomwalters@0
|
455 ( (PhaseCompensatorState *) compensator_state )->filter_module = MODULE_NAME ;
|
tomwalters@0
|
456
|
tomwalters@0
|
457 return( PhaseCompensateFilter( (PhaseCompensatorState *) compensator_state, ( Pointer ) input_array, ( Pointer ) output_array, npoints ) ) ;
|
tomwalters@0
|
458 }
|
tomwalters@0
|
459
|
tomwalters@0
|
460
|
tomwalters@0
|
461 /* tidy up defines for redefinition */
|
tomwalters@0
|
462
|
tomwalters@0
|
463 #undef STATE_TYPE
|
tomwalters@0
|
464 #undef INPUT_TYPE
|
tomwalters@0
|
465 #undef OUTPUT_TYPE
|
tomwalters@0
|
466 #undef FILTER_NAME
|
tomwalters@0
|
467 #undef MODULE_NAME
|
tomwalters@0
|
468 #undef I_SHIFT
|
tomwalters@0
|
469 #undef K_SHIFT
|
tomwalters@0
|
470 #undef S_SHIFT
|
tomwalters@0
|
471
|
tomwalters@0
|
472 #undef SIN
|
tomwalters@0
|
473 #undef COS
|
tomwalters@0
|
474
|
tomwalters@0
|
475 #ifdef FLOAT
|
tomwalters@0
|
476 #undef FLOAT
|
tomwalters@0
|
477 #endif
|
tomwalters@0
|
478
|
tomwalters@0
|
479 #ifdef COMPLEX
|
tomwalters@0
|
480 #undef COMPLEX
|
tomwalters@0
|
481 #endif
|