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