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 corti.c
|
tomwalters@0
|
20 =======
|
tomwalters@0
|
21
|
tomwalters@0
|
22 attempt at model of organ of corti
|
tomwalters@0
|
23
|
tomwalters@0
|
24
|
tomwalters@0
|
25 Copyright (c), 1989 The Medical Research Council, Applied Psychology Unit.
|
tomwalters@0
|
26
|
tomwalters@0
|
27
|
tomwalters@0
|
28 Author : John Holdsworth
|
tomwalters@0
|
29 Written : 30th November, 1988.
|
tomwalters@0
|
30
|
tomwalters@0
|
31 Edited :
|
tomwalters@0
|
32
|
tomwalters@0
|
33 Christian Giguere, March 1994.
|
tomwalters@0
|
34 - Changed option "scale_at" into "gain_at".
|
tomwalters@0
|
35 - That option is now passed to newCorti() as a double instead of an integer
|
tomwalters@0
|
36 - In Corti(), this meant multiplying *optr by state->scale
|
tomwalters@0
|
37 - To locate changes, search for "CG"
|
tomwalters@0
|
38
|
tomwalters@0
|
39 */
|
tomwalters@0
|
40 #include <stdio.h>
|
tomwalters@0
|
41 #include <math.h>
|
tomwalters@0
|
42
|
tomwalters@0
|
43 #include "stitch.h"
|
tomwalters@0
|
44 #include "source.h"
|
tomwalters@0
|
45 #include "corti.h"
|
tomwalters@0
|
46 #include "calc.h"
|
tomwalters@0
|
47
|
tomwalters@0
|
48 #if 0
|
tomwalters@0
|
49 #define DEBUG
|
tomwalters@0
|
50 #endif
|
tomwalters@0
|
51
|
tomwalters@0
|
52 #ifndef lint
|
tomwalters@0
|
53 static char *sccs_id = "@(#)corti.c 1.15 J. Holdsworth (MRC-APU) 5/31/91" ;
|
tomwalters@0
|
54 #endif
|
tomwalters@0
|
55
|
tomwalters@0
|
56 /* calmB is the mB of the magnitude where the slope of temporal recovery is calculated */
|
tomwalters@0
|
57 /* 5497 corresponds to a magnitude of 500 units */
|
tomwalters@0
|
58
|
tomwalters@0
|
59 static double calmB = 5497. ;
|
tomwalters@0
|
60
|
tomwalters@0
|
61 struct _cell_state {
|
tomwalters@0
|
62 StoreType microphonic, rapid_limit, absolute_limit ;
|
tomwalters@0
|
63 ScalarType rapid_rise, fast_rise, rapid_decay, fast_decay ;
|
tomwalters@0
|
64 double compensate ; /* Changed to double from StoreType (mha:22/1/93) */
|
tomwalters@0
|
65 } ;
|
tomwalters@0
|
66
|
tomwalters@0
|
67 struct _corti_state {
|
tomwalters@0
|
68 struct _cell_state *cell_states ;
|
tomwalters@0
|
69 StoreType scale ;
|
tomwalters@0
|
70 ScalarType t_lat ;
|
tomwalters@0
|
71 unsigned cells, times ;
|
tomwalters@0
|
72 } ;
|
tomwalters@0
|
73
|
tomwalters@0
|
74
|
tomwalters@0
|
75 /* global variable for spectral tilt control to compensate for differences */
|
tomwalters@0
|
76 /* between channels in terms of mean firing rate */
|
tomwalters@0
|
77
|
tomwalters@0
|
78 double compensate = 1. ;
|
tomwalters@0
|
79
|
tomwalters@0
|
80
|
tomwalters@0
|
81 char *newCorti( cells, samplerate, center_frequencies, bandwidth_function, t_rise, t_lat, t_rapid, t_fast, prop, absthresh, times, scale )
|
tomwalters@0
|
82 int cells ;
|
tomwalters@0
|
83 double samplerate, *center_frequencies, (*bandwidth_function)(), t_rise, t_lat, t_rapid, t_fast, prop, absthresh ;
|
tomwalters@0
|
84 int times ;
|
tomwalters@0
|
85 double scale ; /* CG: 22/03/94 */
|
tomwalters@0
|
86 {
|
tomwalters@0
|
87 DeclareNew( struct _corti_state *, state ) ;
|
tomwalters@0
|
88 struct _cell_state *cell_ptr ;
|
tomwalters@0
|
89 double ratio, k_rise ;
|
tomwalters@0
|
90 double expected_rate, expected_reference ;
|
tomwalters@0
|
91
|
tomwalters@0
|
92 /* parameters that are constant across cells */
|
tomwalters@0
|
93
|
tomwalters@0
|
94 state->t_lat = SCALAR( t_lat / ( samplerate * times ) ) ;
|
tomwalters@0
|
95
|
tomwalters@0
|
96 state->cells = cells ;
|
tomwalters@0
|
97 state->times = times ;
|
tomwalters@0
|
98 state->scale = scale ;
|
tomwalters@0
|
99
|
tomwalters@0
|
100 state->cell_states = NewArray( struct _cell_state, state->cells, "corti.c for cell states" ) ;
|
tomwalters@0
|
101
|
tomwalters@0
|
102 for( cell_ptr = state->cell_states ; cell_ptr < state->cell_states + cells ; cell_ptr++ ) {
|
tomwalters@0
|
103
|
tomwalters@0
|
104 /* corti states */
|
tomwalters@0
|
105
|
tomwalters@0
|
106 cell_ptr->microphonic = SCALAR( absthresh ) ;
|
tomwalters@0
|
107 cell_ptr->rapid_limit = SCALAR( absthresh ) ;
|
tomwalters@0
|
108 cell_ptr->absolute_limit = SCALAR( absthresh ) ;
|
tomwalters@0
|
109
|
tomwalters@0
|
110 /* recovery time constants */
|
tomwalters@0
|
111
|
tomwalters@0
|
112 cell_ptr->rapid_decay = SCALAR( bandwidth_function( center_frequencies[cell_ptr-state->cell_states] ) *
|
tomwalters@0
|
113 t_rapid * calmB / ( calmB - absthresh ) / samplerate /* / ( 1. - prop ) */ ) ;
|
tomwalters@0
|
114
|
tomwalters@0
|
115 cell_ptr->fast_decay = SCALAR( 1. / t_fast / samplerate ) ;
|
tomwalters@0
|
116
|
tomwalters@0
|
117 /* adaptation time constants */
|
tomwalters@0
|
118
|
tomwalters@0
|
119 ratio = prop / ( 1. - prop ) / cell_ptr->rapid_decay * cell_ptr->fast_decay ;
|
tomwalters@0
|
120
|
tomwalters@0
|
121 if( t_rise > 0 )
|
tomwalters@0
|
122 k_rise = t_rise / ( samplerate * times ) ;
|
tomwalters@0
|
123 else
|
tomwalters@0
|
124 k_rise = 1. ;
|
tomwalters@0
|
125
|
tomwalters@0
|
126 cell_ptr->rapid_rise = SCALAR( k_rise * 1. / ( 1. + ratio ) ) ;
|
tomwalters@0
|
127 cell_ptr->fast_rise = SCALAR( k_rise * ratio / ( 1. + ratio ) ) ;
|
tomwalters@0
|
128
|
tomwalters@0
|
129 /* introduce variable amount of compensation w.r.t expected firing rate variation */
|
tomwalters@0
|
130
|
tomwalters@0
|
131 expected_rate = UNSCALE( cell_ptr->rapid_decay ) * ( calmB - absthresh ) ;
|
tomwalters@0
|
132
|
tomwalters@0
|
133 if( cell_ptr == state->cell_states )
|
tomwalters@0
|
134 expected_reference = expected_rate ;
|
tomwalters@0
|
135
|
tomwalters@0
|
136 /* New formula for computing cell_ptr->compensate (mha: 20/1/93) */
|
tomwalters@0
|
137 /* Parameters chosen to flatten pulse-train spectrum. */
|
tomwalters@0
|
138 /* _cell_state member "compensate" changed to double. */
|
tomwalters@0
|
139 /* The exponent used is 1.128*compensate so that the given */
|
tomwalters@0
|
140 /* parameter (compensate_at) can be set as "on" (ie 1.0) for */
|
tomwalters@0
|
141 /* optimal compensation (instead of a magic number) */
|
tomwalters@0
|
142 /* The value for "compensate_at=off", (calmB - absthresh) was */
|
tomwalters@0
|
143 /* chosen as similar to the original, and because the results */
|
tomwalters@0
|
144 /* were appropriate for an un-compensated spectrum. */
|
tomwalters@0
|
145
|
tomwalters@0
|
146 if (compensate)
|
tomwalters@0
|
147 cell_ptr->compensate = pow(center_frequencies[cell_ptr - state->cell_states], 1.128*compensate) + 800. ;
|
tomwalters@0
|
148 else
|
tomwalters@0
|
149 cell_ptr->compensate = calmB - absthresh ;
|
tomwalters@0
|
150
|
tomwalters@0
|
151 /* Originally, compensate used the SCALAR macro, and so it failed */
|
tomwalters@0
|
152 /* for a floating-point version (defined in calc.h). */
|
tomwalters@0
|
153 /* To fix this, the new compensate formula is scaled up using the */
|
tomwalters@0
|
154 /* original integer version of the UNSCALE macro (see calc.h). */
|
tomwalters@0
|
155
|
tomwalters@0
|
156 #ifdef FLOAT
|
tomwalters@0
|
157 cell_ptr->compensate /= (float) ( 1l << 16l ) ;
|
tomwalters@0
|
158 #endif
|
tomwalters@0
|
159
|
tomwalters@0
|
160 #ifdef DEBUG
|
tomwalters@0
|
161 (void) fprintf( stderr, "rapid_decay:%f fast_decay:%f ratio:%f k_rise:%f rapid_rise:%f fast_rise:%f compensation:%f\n",
|
tomwalters@0
|
162 UNSCALE(cell_ptr->rapid_decay), UNSCALE(cell_ptr->fast_decay),
|
tomwalters@0
|
163 ratio, k_rise, UNSCALE(cell_ptr->rapid_rise), UNSCALE(cell_ptr->fast_rise),
|
tomwalters@0
|
164 1./UNSCALE(cell_ptr->compensate) ) ;
|
tomwalters@0
|
165 #endif
|
tomwalters@0
|
166 }
|
tomwalters@0
|
167 #ifdef DEBUG
|
tomwalters@0
|
168 (void) fprintf( stderr, "times:%d t_lat:%f\n", times, UNSCALE( state->t_lat ) ) ;
|
tomwalters@0
|
169 #endif
|
tomwalters@0
|
170
|
tomwalters@0
|
171 return( (char *) state ) ;
|
tomwalters@0
|
172 }
|
tomwalters@0
|
173
|
tomwalters@0
|
174 int Corti( state_ptr, bytes, out, end, in )
|
tomwalters@0
|
175 char *state_ptr ;
|
tomwalters@0
|
176 ByteCount *bytes ;
|
tomwalters@0
|
177 DataType *out, *end, *in ;
|
tomwalters@0
|
178 {
|
tomwalters@0
|
179 register struct _corti_state *state = (struct _corti_state *) state_ptr ;
|
tomwalters@0
|
180 register struct _cell_state *cell_ptr, *cell_end = state->cell_states + state->cells ;
|
tomwalters@0
|
181 register DataType *iptr, *optr, *eptr = end ;
|
tomwalters@0
|
182 register StoreType delta, old_last_mic ;
|
tomwalters@0
|
183 register int time ;
|
tomwalters@0
|
184
|
tomwalters@0
|
185 while( out < eptr ) {
|
tomwalters@0
|
186
|
tomwalters@0
|
187 for( time=0 ; time < state->times ; time++ ) {
|
tomwalters@0
|
188
|
tomwalters@0
|
189 cell_ptr = state->cell_states ;
|
tomwalters@0
|
190
|
tomwalters@0
|
191 iptr = in ;
|
tomwalters@0
|
192 optr = out ;
|
tomwalters@0
|
193
|
tomwalters@0
|
194 /* raise threhsolds */
|
tomwalters@0
|
195
|
tomwalters@0
|
196 for( cell_ptr = state->cell_states ; cell_ptr < cell_end ; cell_ptr++ ) {
|
tomwalters@0
|
197
|
tomwalters@0
|
198 if( time == 0 )
|
tomwalters@0
|
199 *optr = 0 ;
|
tomwalters@0
|
200
|
tomwalters@0
|
201 delta = *iptr++ - DESCALE( cell_ptr->microphonic ) ;
|
tomwalters@0
|
202
|
tomwalters@0
|
203 if( delta > 0 ) {
|
tomwalters@0
|
204
|
tomwalters@0
|
205 cell_ptr->microphonic += delta * cell_ptr->rapid_rise ;
|
tomwalters@0
|
206 cell_ptr->rapid_limit += delta * cell_ptr->fast_rise ;
|
tomwalters@0
|
207
|
tomwalters@0
|
208 *optr += delta ;
|
tomwalters@0
|
209 }
|
tomwalters@0
|
210
|
tomwalters@0
|
211 optr++ ;
|
tomwalters@0
|
212 }
|
tomwalters@0
|
213
|
tomwalters@0
|
214 /* leak thresholds symetrically across channels */
|
tomwalters@0
|
215
|
tomwalters@0
|
216 old_last_mic = state->cell_states->microphonic ;
|
tomwalters@0
|
217
|
tomwalters@0
|
218 for( cell_ptr = state->cell_states+1 ; cell_ptr < cell_end ; cell_ptr++ ) {
|
tomwalters@0
|
219
|
tomwalters@0
|
220 delta = DESCALE( old_last_mic - cell_ptr->microphonic ) * state->t_lat ;
|
tomwalters@0
|
221 old_last_mic = cell_ptr->microphonic ;
|
tomwalters@0
|
222
|
tomwalters@0
|
223 if( cell_ptr-1 != state->cell_states )
|
tomwalters@0
|
224 (cell_ptr-1)->microphonic -= delta ;
|
tomwalters@0
|
225
|
tomwalters@0
|
226 if( cell_ptr+1 != cell_end )
|
tomwalters@0
|
227 (cell_ptr )->microphonic += delta ;
|
tomwalters@0
|
228 }
|
tomwalters@0
|
229 }
|
tomwalters@0
|
230
|
tomwalters@0
|
231 /* decay potentails */
|
tomwalters@0
|
232
|
tomwalters@0
|
233 for( cell_ptr = state->cell_states ; cell_ptr < cell_end ; cell_ptr++ )
|
tomwalters@0
|
234 cell_ptr->microphonic -= DESCALE( cell_ptr->microphonic - cell_ptr->rapid_limit ) * cell_ptr->rapid_decay ;
|
tomwalters@0
|
235
|
tomwalters@0
|
236 for( cell_ptr = state->cell_states ; cell_ptr < cell_end ; cell_ptr++ )
|
tomwalters@0
|
237 cell_ptr->rapid_limit -= DESCALE( cell_ptr->rapid_limit - cell_ptr->absolute_limit ) * cell_ptr->fast_decay ;
|
tomwalters@0
|
238
|
tomwalters@0
|
239 /* generate output */
|
tomwalters@0
|
240
|
tomwalters@0
|
241 iptr = in ;
|
tomwalters@0
|
242 optr = out ;
|
tomwalters@0
|
243
|
tomwalters@0
|
244 if( state->scale >= 0 ) /* CG: 22/3/94 */
|
tomwalters@0
|
245 for( cell_ptr = state->cell_states ; cell_ptr < cell_end ; cell_ptr++ ) {
|
tomwalters@0
|
246 delta = SCALE( *iptr++ ) - cell_ptr->microphonic ;
|
tomwalters@0
|
247 if( delta > 0 )
|
tomwalters@0
|
248 *optr++ = state->scale * delta / cell_ptr->compensate ; /* CG: 22/3/94 */
|
tomwalters@0
|
249 else
|
tomwalters@0
|
250 *optr++ = 0 ;
|
tomwalters@0
|
251 }
|
tomwalters@0
|
252 else if( state->scale < 0 )
|
tomwalters@0
|
253 switch( (int) state->scale ) {
|
tomwalters@0
|
254
|
tomwalters@0
|
255 /* output internal states */
|
tomwalters@0
|
256
|
tomwalters@0
|
257 case -1 :
|
tomwalters@0
|
258 for( cell_ptr = state->cell_states ; cell_ptr < cell_end ; cell_ptr++ )
|
tomwalters@0
|
259 *optr++ = DESCALE( cell_ptr->microphonic ) ;
|
tomwalters@0
|
260
|
tomwalters@0
|
261 break ;
|
tomwalters@0
|
262
|
tomwalters@0
|
263 case -2 :
|
tomwalters@0
|
264 for( cell_ptr = state->cell_states ; cell_ptr < cell_end ; cell_ptr++ )
|
tomwalters@0
|
265 *optr++ = DESCALE( cell_ptr->rapid_limit ) ;
|
tomwalters@0
|
266
|
tomwalters@0
|
267 break ;
|
tomwalters@0
|
268
|
tomwalters@0
|
269 default :
|
tomwalters@0
|
270 for( cell_ptr = state->cell_states ; cell_ptr < cell_end ; cell_ptr++ )
|
tomwalters@0
|
271 *optr++ = ( *iptr++ - DESCALE( cell_ptr->microphonic ) ) * -state->scale ;
|
tomwalters@0
|
272
|
tomwalters@0
|
273 break ;
|
tomwalters@0
|
274
|
tomwalters@0
|
275 }
|
tomwalters@0
|
276 /* else leave value as is */
|
tomwalters@0
|
277
|
tomwalters@0
|
278
|
tomwalters@0
|
279 /* next frame */
|
tomwalters@0
|
280
|
tomwalters@0
|
281 in += state->cells ;
|
tomwalters@0
|
282 out += state->cells ;
|
tomwalters@0
|
283 }
|
tomwalters@0
|
284
|
tomwalters@0
|
285 /* return amount processed */
|
tomwalters@0
|
286
|
tomwalters@0
|
287 return ( *bytes ) ;
|
tomwalters@0
|
288 }
|
tomwalters@0
|
289
|
tomwalters@0
|
290 /* for compatability */
|
tomwalters@0
|
291
|
tomwalters@0
|
292 int OldCorti( state_ptr, cells, in, out )
|
tomwalters@0
|
293 char *state_ptr ;
|
tomwalters@0
|
294 unsigned cells ;
|
tomwalters@0
|
295 DataType *in, *out ;
|
tomwalters@0
|
296 {
|
tomwalters@0
|
297 ByteCount bytes = ToBytes( DataType, cells ) ;
|
tomwalters@0
|
298
|
tomwalters@0
|
299 return ( ToPoints( DataType, Corti( state_ptr, &bytes, out, out+cells, in ) ) ) ;
|
tomwalters@0
|
300 }
|
tomwalters@0
|
301
|
tomwalters@0
|
302 void closeCorti( state )
|
tomwalters@0
|
303 struct _corti_state *state ;
|
tomwalters@0
|
304 {
|
tomwalters@0
|
305 Delete( state->cell_states ) ;
|
tomwalters@0
|
306 Delete( state ) ;
|
tomwalters@0
|
307
|
tomwalters@0
|
308 return ;
|
tomwalters@0
|
309 }
|
tomwalters@0
|
310
|
tomwalters@0
|
311
|
tomwalters@0
|
312 /* experimental corti simulation */
|
tomwalters@0
|
313
|
tomwalters@0
|
314
|
tomwalters@0
|
315 struct _corti2_state { int *working, *falls, slope, scale ; short *forward, *backward ; } ;
|
tomwalters@0
|
316
|
tomwalters@0
|
317 char *newCorti2( cells, samplerate, center_frequencies, bandwidth_function, bandwidth_scalar, t_slope, scale, forward, backward )
|
tomwalters@0
|
318 int cells ;
|
tomwalters@0
|
319 double samplerate, *center_frequencies, (*bandwidth_function)(), bandwidth_scalar, t_slope, scale ;
|
tomwalters@0
|
320 short *forward, *backward ;
|
tomwalters@0
|
321 {
|
tomwalters@0
|
322 DeclareNew( struct _corti2_state *, state ) ;
|
tomwalters@0
|
323 int i ;
|
tomwalters@0
|
324
|
tomwalters@0
|
325 state->working = NewArray( int, cells, "corti.c for works" ) ;
|
tomwalters@0
|
326 state->falls = NewZeroedArray( int, cells, "corti.c for falls" ) ;
|
tomwalters@0
|
327
|
tomwalters@0
|
328 for( i=0 ; i < cells ; i++ )
|
tomwalters@0
|
329 state->falls[i] = bandwidth_function( center_frequencies[i] ) * bandwidth_scalar /
|
tomwalters@0
|
330 samplerate * t_slope ;
|
tomwalters@0
|
331
|
tomwalters@0
|
332 state->forward = forward ;
|
tomwalters@0
|
333 state->backward = backward ;
|
tomwalters@0
|
334
|
tomwalters@0
|
335 state->scale = scale ;
|
tomwalters@0
|
336
|
tomwalters@0
|
337 return( ( char * ) state ) ;
|
tomwalters@0
|
338 }
|
tomwalters@0
|
339
|
tomwalters@0
|
340 int Corti2( state_ptr, cells, in, out )
|
tomwalters@0
|
341 char *state_ptr ;
|
tomwalters@0
|
342 unsigned cells ;
|
tomwalters@0
|
343 short *in, *out ;
|
tomwalters@0
|
344 {
|
tomwalters@0
|
345 struct _corti2_state *state ;
|
tomwalters@0
|
346 register int i, when ;
|
tomwalters@0
|
347
|
tomwalters@0
|
348 state = ( struct _corti2_state * ) state_ptr ;
|
tomwalters@0
|
349
|
tomwalters@0
|
350 for( i=0 ; i<cells ; i++ ) {
|
tomwalters@0
|
351 state->working[i] -= state->falls[i] ;
|
tomwalters@0
|
352 out[i] = in[i] - state->working[i] ;
|
tomwalters@0
|
353 if( out[i] > 0 )
|
tomwalters@0
|
354 state->working[i] += out[i] ;
|
tomwalters@0
|
355 }
|
tomwalters@0
|
356
|
tomwalters@0
|
357 when = 0 ;
|
tomwalters@0
|
358
|
tomwalters@0
|
359 for( i=1 ; i<cells ; i++ )
|
tomwalters@0
|
360 if( state->working[i] < state->working[ when ] + state->forward[ i - when ] ) {
|
tomwalters@0
|
361 state->working[i] = state->working[ when ] + state->forward[ i - when ] ;
|
tomwalters@0
|
362 out[i] = 0 ;
|
tomwalters@0
|
363 }
|
tomwalters@0
|
364 else
|
tomwalters@0
|
365 when = i ;
|
tomwalters@0
|
366
|
tomwalters@0
|
367 when = cells-1 ;
|
tomwalters@0
|
368
|
tomwalters@0
|
369 for( i=cells-2 ; i>=0 ; i-- )
|
tomwalters@0
|
370 if( state->working[i] < state->working[ when ] + state->backward[ when - i ] ) {
|
tomwalters@0
|
371 state->working[i] = state->working[ when ] + state->backward[ when - i ] ;
|
tomwalters@0
|
372 out[i] = 0 ;
|
tomwalters@0
|
373 }
|
tomwalters@0
|
374 else
|
tomwalters@0
|
375 when = i ;
|
tomwalters@0
|
376
|
tomwalters@0
|
377 for( i=0 ; i<cells ; i++ )
|
tomwalters@0
|
378 if( state->scale != 0 )
|
tomwalters@0
|
379 out[i] = out[i] * state->scale / state->falls[i] ;
|
tomwalters@0
|
380 else
|
tomwalters@0
|
381 out[i] = state->working[i] ;
|
tomwalters@0
|
382
|
tomwalters@0
|
383 return ;
|
tomwalters@0
|
384 }
|
tomwalters@0
|
385
|
tomwalters@0
|
386 void closeCorti2( state )
|
tomwalters@0
|
387 struct _corti2_state *state ;
|
tomwalters@0
|
388 {
|
tomwalters@0
|
389 stitch_free( ( char * ) state->working ) ;
|
tomwalters@0
|
390 stitch_free( ( char * ) state->falls ) ;
|
tomwalters@0
|
391
|
tomwalters@0
|
392 Delete( state ) ;
|
tomwalters@0
|
393
|
tomwalters@0
|
394 return ;
|
tomwalters@0
|
395 }
|
tomwalters@0
|
396
|
tomwalters@0
|
397 #if 0
|
tomwalters@0
|
398
|
tomwalters@0
|
399 /* obsolete code stored here for now.. stitch entry points */
|
tomwalters@0
|
400
|
tomwalters@0
|
401
|
tomwalters@0
|
402 struct _stx_state { Source source ; unsigned cells ; char *corti ; int (*model)() ; } ;
|
tomwalters@0
|
403
|
tomwalters@0
|
404 static void stx_callback( state, bytes, buffer )
|
tomwalters@0
|
405 struct _stx_state *state ;
|
tomwalters@0
|
406 ByteCount bytes ;
|
tomwalters@0
|
407 DataType *buffer ;
|
tomwalters@0
|
408 {
|
tomwalters@0
|
409 int points = ToPoints( DataType, bytes ) ;
|
tomwalters@0
|
410 DataType *input = PullItems( state->source, points, DataType ) ;
|
tomwalters@0
|
411 int pointer ;
|
tomwalters@0
|
412
|
tomwalters@0
|
413 for( pointer=0 ; pointer < points ; pointer += state->cells )
|
tomwalters@0
|
414 (void) state->model( state->corti, state->cells, input+pointer, buffer+pointer ) ;
|
tomwalters@0
|
415
|
tomwalters@0
|
416 return ;
|
tomwalters@0
|
417 }
|
tomwalters@0
|
418
|
tomwalters@0
|
419 Source Stx( source, chans, samplerate, center_frequencies, bandwidth_function, bandwidth_scalar, t_rise, t_lat, t_rapid, absthresh, times, scale )
|
tomwalters@0
|
420 Source source ;
|
tomwalters@0
|
421 int chans ;
|
tomwalters@0
|
422 double samplerate, *center_frequencies, (*bandwidth_function)(), bandwidth_scalar, t_rise, t_lat, t_rapid, absthresh ;
|
tomwalters@0
|
423 int times, scale ;
|
tomwalters@0
|
424 {
|
tomwalters@0
|
425 DeclareNew( struct _stx_state *, state ) ;
|
tomwalters@0
|
426
|
tomwalters@0
|
427 state->source = source ;
|
tomwalters@0
|
428 state->cells = chans ;
|
tomwalters@0
|
429
|
tomwalters@0
|
430 state->corti = newCorti( chans, samplerate, center_frequencies, bandwidth_function, t_rise, t_lat, t_rapid, absthresh, times, scale ) ;
|
tomwalters@0
|
431 state->model = OldCorti ;
|
tomwalters@0
|
432
|
tomwalters@0
|
433 return ( stdAutoSource( ( Pointer ) state, stx_callback ) ) ;
|
tomwalters@0
|
434 }
|
tomwalters@0
|
435
|
tomwalters@0
|
436 Source Stx2( source, chans, samplerate, center_frequencies, bandwidth_function, bandwidth_scalar, rapid_rises, scale )
|
tomwalters@0
|
437 Source source ;
|
tomwalters@0
|
438 int chans ;
|
tomwalters@0
|
439 double samplerate, *center_frequencies, (*bandwidth_function)(), bandwidth_scalar, rapid_rises, scale ;
|
tomwalters@0
|
440 {
|
tomwalters@0
|
441 DeclareNew( struct _stx_state *, state ) ;
|
tomwalters@0
|
442 short *forward = ( short * ) 0, *backward = ( short * ) 0 ;
|
tomwalters@0
|
443
|
tomwalters@0
|
444 state->source = source ;
|
tomwalters@0
|
445 state->cells = chans ;
|
tomwalters@0
|
446
|
tomwalters@0
|
447 state->corti = newCorti2( chans, samplerate, center_frequencies, bandwidth_function, bandwidth_scalar, rapid_rises, scale, forward, backward ) ;
|
tomwalters@0
|
448 state->model = Corti2 ;
|
tomwalters@0
|
449
|
tomwalters@0
|
450 return ( stdAutoSource( ( Pointer ) state, stx_callback ) ) ;
|
tomwalters@0
|
451 }
|
tomwalters@0
|
452
|
tomwalters@0
|
453 #endif
|