Mercurial > hg > aim92
comparison model/bank.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 bank.c | |
20 ====== | |
21 | |
22 long awaited proper generic multiplexed filter bank with phase compensation! | |
23 | |
24 | |
25 Copyright (c), 1989 The Medical Research Council, Applied Psychology Unit. | |
26 | |
27 | |
28 Author : John Holdsworth | |
29 Written : 10th March, 1989. | |
30 | |
31 Edited : | |
32 Christian Giguere, March 1994 | |
33 - Provided facilities to print filterbank information to stderr | |
34 - To locate changes, search for "CG" | |
35 | |
36 */ | |
37 | |
38 #include <math.h> | |
39 #include <stdio.h> /* CG */ | |
40 | |
41 #include "stitch.h" | |
42 #include "source.h" | |
43 #include "recurse.h" | |
44 #include "formulae.h" | |
45 | |
46 #include "bank.h" | |
47 | |
48 #ifndef lint | |
49 static char *sccs_id = "@(#)bank.c 1.16 John Holdsworth (MRC-APU) 6/6/91" ; | |
50 #endif | |
51 | |
52 | |
53 /* interpolation */ | |
54 | |
55 struct _interp_state { struct _fillable_source parent ; Source source ; unsigned ichans ; int (*interp)() ; } ; | |
56 | |
57 static Pointer interp_callback( state, bytes, buffer ) | |
58 struct _interp_state *state ; | |
59 ByteCount *bytes ; | |
60 short *buffer ; | |
61 { | |
62 register int last = *bytes == 0 ; | |
63 register int ipointer, points = ToPoints( short, *bytes ) ; | |
64 register int ipoints = points / (state->ichans*2-1) * state->ichans ; | |
65 short *input = PullShorts( state->source, ipoints ) ; | |
66 | |
67 if( !last ) { | |
68 for( ipointer=0 ; ipointer < ipoints ; ipointer += state->ichans ) | |
69 state->interp( input+ipointer, buffer+ipointer/state->ichans*(state->ichans*2-1), state->ichans, state->ichans*2-1 ) ; | |
70 | |
71 return ( (Pointer) buffer ) ; | |
72 } | |
73 else | |
74 return ( DeleteFillableSource( state ) ) ; | |
75 } | |
76 | |
77 Source InterpSource( source, ichans ) | |
78 Source source ; | |
79 int ichans ; | |
80 { | |
81 DeclareNew( struct _interp_state *, state ) ; | |
82 extern int interp() ; | |
83 | |
84 state->source = source ; | |
85 state->ichans = ichans ; | |
86 state->interp = interp ; | |
87 | |
88 return ( SetFillableSource( state, interp_callback, "bank.c interpolating" ) ) ; | |
89 } | |
90 | |
91 Source LinterpSource( source, ichans ) | |
92 Source source ; | |
93 int ichans ; | |
94 { | |
95 DeclareNew( struct _interp_state *, state ) ; | |
96 extern int linterp() ; | |
97 | |
98 state->source = source ; | |
99 state->ichans = ichans ; | |
100 state->interp = linterp ; | |
101 | |
102 return ( SetFillableSource( state, interp_callback, "bank.c linterpolating" ) ) ; | |
103 } | |
104 | |
105 static int segsize = 50 ; | |
106 | |
107 #ifdef DSP32 | |
108 #define BUFFSIZE 256 | |
109 #else | |
110 #define BUFFSIZE 2048 | |
111 #endif | |
112 | |
113 /* multiplexed filter bank */ | |
114 | |
115 struct _bank_state { | |
116 struct _fillable_source parent ; | |
117 Source source ; char *input ; unsigned chans ; | |
118 int active, pointer, iptr, *delays, (*proc)(), input_size, output_size ; | |
119 RecursiveFilterState **states ; | |
120 } ; | |
121 | |
122 static Pointer bank_callback( state, bytes, buffer ) | |
123 struct _bank_state *state ; | |
124 ByteCount *bytes ; | |
125 char *buffer ; | |
126 { | |
127 extern char *bstart, *bend ; | |
128 register int last = *bytes == 0 ; | |
129 static int segment = BUFFSIZE ; | |
130 int points, bytecount ; | |
131 | |
132 if( state->input == ( char * ) 0 ) { | |
133 | |
134 if( state->delays[0] < 0 ) | |
135 state->pointer = state->delays[0] ; | |
136 else | |
137 state->pointer = 0 ; | |
138 | |
139 if( segment < state->delays[state->chans-1] - state->delays[0] ) | |
140 segment = state->delays[state->chans-1] - state->delays[0] << 1 ; | |
141 | |
142 state->input = Pull( state->source, segment * state->input_size ) ; | |
143 state->iptr = state->pointer ; | |
144 state->active = 0 ; | |
145 | |
146 bstart = state->input - segment * state->input_size ; | |
147 bend = state->input + segment * state->input_size ; | |
148 } | |
149 | |
150 if( !last ) { | |
151 for( bytecount=0 ; bytecount<*bytes ; ) { | |
152 | |
153 if( state->iptr + segsize - state->delays[0] >= segment ) { | |
154 state->input = Pull( state->source, segment * state->input_size ) ; | |
155 state->iptr -= segment ; | |
156 | |
157 bstart = state->input - segment * state->input_size ; | |
158 bend = state->input + segment * state->input_size ; | |
159 | |
160 } | |
161 | |
162 while( state->active < state->chans && state->delays[ state->active ] <= state->pointer ) | |
163 state->active++ ; | |
164 | |
165 if( state->pointer < 0 || state->active < state->chans || state->output_size == 0 ) { | |
166 | |
167 points = 1 ; | |
168 | |
169 state->output_size = state->proc( state->states, state->delays, state->input + state->iptr * state->input_size, buffer+bytecount, points, state->active ) ; | |
170 | |
171 stitch_bzero( buffer+bytecount+state->active*state->output_size, (int) ( ( state->chans - state->active ) * state->output_size ) ) ; | |
172 } | |
173 else { | |
174 points = ( *bytes - bytecount ) / state->chans / state->output_size ; | |
175 | |
176 if( points > segsize ) | |
177 points = segsize ; | |
178 | |
179 state->output_size = state->proc( state->states, state->delays, state->input + state->iptr * state->input_size, buffer+bytecount, points, state->active ) ; | |
180 } | |
181 | |
182 state->iptr += points ; | |
183 | |
184 if( ++state->pointer > 0 ) | |
185 bytecount += points*state->chans*state->output_size ; | |
186 } | |
187 | |
188 return ( buffer ) ; | |
189 } | |
190 else { | |
191 Pull( state->source, 0 ) ; | |
192 | |
193 for( last=0 ; last<state->chans ; last++ ) | |
194 Delete( state->states[last] ) ; | |
195 | |
196 Delete( state->states ) ; | |
197 Delete( state->delays ) ; | |
198 | |
199 return ( DeleteFillableSource( state ) ) ; | |
200 } | |
201 | |
202 } | |
203 | |
204 | |
205 Source GenericFilterBank( source, interps, chans, samplerate, center_frequencies, bandwidth_function, scale_function, output_scale, audio_power, order, phase_compensation, input_bits, frames, proc, input_size, info ) | |
206 Source source ; | |
207 int interps, *chans ; | |
208 double samplerate, *center_frequencies, (*bandwidth_function)(), (*scale_function)() ; /* CG: 23-03-94 */ | |
209 double output_scale, audio_power ; /* CG: 23-03-94 */ | |
210 int order, phase_compensation, input_bits ; | |
211 long frames ; | |
212 int (*proc)(), input_size, info ; /* CG: 23-03-94 */ | |
213 { | |
214 DeclareNew( struct _bank_state *, state ) ; | |
215 double sample_delay, max_delay, freq ; | |
216 extern Source Interp() ; | |
217 Source out ; | |
218 int chan ; | |
219 | |
220 state->chans = *chans >> interps ; | |
221 | |
222 state->states = NewArray( RecursiveFilterState *, state->chans, "bank.c for states" ) ; | |
223 state->delays = NewArray( int, state->chans, "bank.c for delays" ) ; | |
224 | |
225 state->input_size = input_size ; | |
226 | |
227 if( info ) /* CG: 23-03-94 */ | |
228 fprintf( stderr, "\nGTF filterbank information:\n" ) ; | |
229 | |
230 for( chan=0 ; chan < state->chans ; chan++ ) { | |
231 sample_delay = 0 ; | |
232 | |
233 freq = center_frequencies[ chan<<interps ] ; | |
234 | |
235 if( info ) /* CG: 23-03-94 */ | |
236 fprintf( stderr, "%3d -- cf:%7.1f Hz =%6.2f ERBs -- bwidth=%5.1f Hz\n", | |
237 chan + 1 , freq, scale_function( freq ), bandwidth_function( freq ) ) ; | |
238 | |
239 state->states[ chan ] = NewRecursiveFilter( samplerate, freq, bandwidth_function( freq ), | |
240 output_scale * pow( Audiogram( freq ), audio_power ), | |
241 order, phase_compensation, input_bits, &sample_delay ) ; | |
242 | |
243 if( chan == 0 ) | |
244 max_delay = sample_delay ; | |
245 | |
246 if( phase_compensation == FINE_ALIGNMENT || phase_compensation == ENVELOPE_ALIGNMENT ) | |
247 state->delays[ chan ] = sample_delay - max_delay ; | |
248 else | |
249 state->delays[ chan ] = sample_delay ; | |
250 } | |
251 | |
252 state->output_size = 0 ; | |
253 | |
254 state->source = NewRetainingSource( source, BUFFSIZE * state->input_size ) ; | |
255 | |
256 state->input = ( char * ) 0 ; | |
257 state->proc = proc ; | |
258 | |
259 out = SetFillableSource( state, bank_callback, "bank.c filter" ) ; | |
260 | |
261 for( chan = state->chans ; interps-- > 0 ; chan = chan*2-1 ) | |
262 out = InterpSource( out, chan ) ; | |
263 | |
264 *chans = chan ; | |
265 | |
266 return ( out ) ; | |
267 } | |
268 |