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