comparison model/model.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 model.c
19 =====
20
21 APU, ASP model demonstration program.
22
23
24 Copyright (c), 1989 The Medical Research Council, Applied Psychology Unit.
25
26
27 Author : John Holdsworth
28 Written : 22th March, 1989.
29
30 Edited : Mike Allerhand, 1990.
31
32 Edited : Roy Patterson, 1992. Changed default values from time to time.
33
34 Edited : MAA 10th June 1993
35 Allowed pwidth=0
36
37 Edited : Christian Giguere, March 1994.
38 - Added tools for manipulating sampling rate and scaling data
39 - Added in an Entry Point for the outer/middle ear function
40 - Added in an Entry Point for the transmission line filterbank
41 - Implemented a completely new version of Meddis().
42 Files "haircell.h, haircell.c "
43 - Changed option "scale_at" into "gain_at".
44 That option is now passed to newCorti() as a double instead of an integer
45 In Corti(), this meant multiplying *optr by state->scale
46 - Provided facilities to print filterbank information to stderr via
47 option info_afb. This supersedes option erbscale_afb.
48 - Changed some default values
49 - To locate changes, search for "CG"
50
51 Edited : Jay Datta, November 1994.
52 Added the stcrit options.
53
54 : Jay Datta, March 1995.
55 Added a function Nwidth() which returns the number
56 of sample points of the nwidth section of a SAI.
57 : Silenced ulim_sas and llim_sas.
58 : Changed trise_at default to 1000 from 10000. May, 1995.
59 : Changed trise_at default to 10000 from 1000. May, 1995.
60 : Separated nwidth and strobe lag by creating a new
61 option called stlag_ai. May, 1995.
62
63 */
64
65 /***************************************************************************
66 * This module contains:
67 * Routines to access or modify string values.
68 * Unit conversion routines.
69 * Model entry-point functions.
70 ****************************************************************************/
71
72 #include <string.h>
73 #include <stdio.h>
74 #include <math.h>
75
76 #ifdef THINK_C
77 #include <stdlib.h>
78 #endif
79
80 /* interfaces to stitch system */
81
82 #include "options.h"
83
84 #include "stitch.h"
85 #include "source.h"
86 #include "funcs.h"
87 #include "units.h"
88 #include "calc.h"
89 #if defined( DSP32 ) || defined( PC )
90 #include "oops.h"
91 #else
92 #include "ops.h"
93 #endif
94 #include "io.h"
95
96 /* interface to model modules */
97
98 #include "gamma_tone.h"
99 #include "integrate.h"
100 #include "formulae.h" /* CG: removed haircell.h */
101 #include "recurse.h"
102 #include "scales.h"
103 #include "spiral.h"
104 #include "model.h"
105 #include "corti.h"
106 #include "image.h"
107 #include "bank.h"
108
109 /* interface to WDF module */ /* CG */
110
111 #include "formulae_tl.h"
112 #include "upsample.h"
113 #include "bank_tl.h"
114 #include "calc_tl.h"
115 #include "meddis.h"
116 #include "ear.h"
117
118 /********************* Model option parameter strings ***********************
119 * The strings are defined, allocated static array space, and initialized to
120 * default values.
121 ****************************************************************************/
122
123 #ifndef lint
124 static char *sccs_id = "@(#)model.c 1.49 John Holdsworth, Mike Allerhand, Roy Patterson, Paul Manson (MRC-APU) 12/23/92" ;
125 #endif
126
127 /* which model to use */
128
129 char whichdflt[] = "none" , *whichstr = whichdflt ;
130 char sampledflt[] = "20000." , *samplestr = sampledflt ;
131
132 /* input properties */
133
134 static char dBdflt[] = "60." , *dBstr = dBdflt ; /* CG */
135 static char bitsdflt[] = "12" , *bitstr = bitsdflt ;
136 static char swapdflt[] = "off" , *swapstr = swapdflt ;
137
138
139 /************************ File-format strings ******************************
140 * The strings are defined, allocated static array space, and initialized to
141 * default values.
142 ****************************************************************************/
143
144 #define RETURN_SIZE 50l
145
146 static char framesbuff[RETURN_SIZE] = "0", *framesstr = framesbuff ;
147 static char bytesbuff[RETURN_SIZE] = "1", *framebytesstr = bytesbuff ;
148 static char widthbuff[RETURN_SIZE] = "1", *framewidthstr = widthbuff ;
149 static char heightbuff[RETURN_SIZE] = "1", *frameheightstr = heightbuff ;
150 static char stepbuff[RETURN_SIZE] = "1", *framestepstr = stepbuff ;
151 static char nwidthdflt[] = "-5ms" , *nwidthstr = nwidthdflt ; /* roy 23-12-92 */
152 static char stlagdflt[] = "5ms" , *stlagstr = stlagdflt ; /* jay 16-05-95 */
153 static char susldflt[] = "5" , *suslevelstr = susldflt ; /* jay 30-08-95 */
154 /************************ File-format strings *******************************
155 *
156 * The data which flows through the model is called a "file".
157 * This is in an array which is structured or formatted according to the way
158 * data is interpreted as it is pulled from each particular source.
159 * The array is formatted into "frames", described by the file-format strings.
160 * The format may be as successive points, (in which case each frame is a
161 * single point with unit width and height), or the format may be as successive
162 * 2-dimensional arrays, (in which case each frame is an array divided into
163 * rows and columns).
164 *
165 * The strings are defined, allocated static array space, and initialized in
166 * gen.c. A set of convenience routines (see below) are given to access or to
167 * reset the value of a string. This enables the file format to be set up on
168 * the fly, depending upon the format of the data passing through the source.
169 *
170 * string: access: reset: comment:
171 * framesstr Frames setFrames num frames in file
172 * framebytesstr Framebytes setFramebytes num bytes in frame
173 * framewidthstr Framewidth setFramewidth num points along frame width
174 * frameheightst Frameheight setFrameheight num points along frame height
175 * framestepstr Framestep setFramestep num points between successive frames
176 *
177 * Access routines for file-format strings:
178 * Frames returns value of "framesstr", (initially 0)
179 * Framebytes returns value of "framebytesstr", (initially 1)
180 * Framewidth returns value of "framewidthstr", (initially 1)
181 * Frameheight returns value of "frameheightstr", (initially 1)
182 * Framestep returns value of "framestepstr", (initially 1)
183 *
184 ****************************************************************************/
185
186 long Frames()
187 {
188 return ( atoi( framesstr ) ) ;
189 }
190
191 int Framebytes()
192 {
193 return ( atoi( framebytesstr ) ) ;
194 }
195
196 int Framewidth()
197 {
198 return ( atoi( framewidthstr ) ) ;
199 }
200
201 int Frameheight()
202 {
203 return ( atoi( frameheightstr ) ) ;
204 }
205
206 int Framestep()
207 {
208 return ( atoi( framestepstr ) ) ;
209 }
210
211 int Nwidth()
212 {
213 int abc = (Samples(stlagstr, Samplerate()));
214 if ( (int)atoi(suslevelstr)>=4)
215 /* fprintf(stderr, "Nwidth is %d\n", -abc); */
216 return (-abc);
217 else
218 return 0;
219 }
220
221
222 /******************* Value-to-string conversion routines. ******************/
223 char *ltoa( val, buffer )
224 long val ;
225 char *buffer ;
226 {
227 (void) sprintf( buffer, "%ld", val ) ;
228
229 return ( buffer ) ;
230 }
231
232 char *itoa( val, buffer )
233 int val ;
234 char *buffer ;
235 {
236 (void) sprintf( buffer, "%d", val ) ;
237
238 return ( buffer ) ;
239 }
240
241 /******************* Reset routines for file-format strings ****************
242 * Convert argument (newval) to a string, and copy into the specific
243 * file-format string.
244 * setFrames resets "framesstr", (initially 0)
245 * setFramebytes resets "framebytesstr", (initially 1)
246 * setFramewidth resets "framewidthstr", (initially 1)
247 * setFrameheight resets "frameheightstr", (initially 1)
248 * setFramestep resets "framestepstr", (initially 1)
249 *
250 * updateFramebytes sets "framebytesstr" to the total number of bytes in
251 * the frame, (ie current width * height).
252 *
253 * Note: updateFramebytes is automatically done at the end of each call to
254 * setFramewidth or setFrameheight, to reset the "framebytesstr" to
255 * account for the new frame size.
256 ****************************************************************************/
257
258 void setFrames( newval )
259 long newval ;
260 {
261 framesstr = ltoa( newval, framesbuff ) ;
262 return ;
263 }
264
265 void setFramebytes( newval )
266 int newval ;
267 {
268 framebytesstr = itoa( newval, bytesbuff ) ;
269 return ;
270 }
271
272 void updateFramebytes()
273 {
274 setFramebytes( Framewidth() * Frameheight() * sizeof ( short ) ) ;
275 return ;
276 }
277
278 void setFramewidth( newval )
279 int newval ;
280 {
281 framewidthstr = itoa( newval, widthbuff ) ;
282 updateFramebytes() ;
283 return ;
284 }
285
286 void setFrameheight( newval )
287 int newval ;
288 {
289 frameheightstr = itoa( newval, heightbuff ) ;
290 updateFramebytes() ;
291 return ;
292 }
293
294 void setFramestep( newval )
295 int newval ;
296 {
297 framestepstr = itoa( newval, stepbuff ) ;
298 return ;
299 }
300
301
302 static Option wavopts[] = {
303
304 { "framebytes", bytesbuff, &framebytesstr, "framebytes - internal", SilentOption},
305 { "framebytes", bytesbuff, &framebytesstr, "framebytes - internal", OutputOption},
306 { "frameheight", heightbuff, &frameheightstr, "frameheight - internal", SilentOption},
307 { "frameheight", heightbuff, &frameheightstr, "frameheight - internal", OutputOption},
308 { "framewidth", widthbuff, &framewidthstr, "framewidth - internal", SilentOption},
309 { "framewidth", widthbuff, &framewidthstr, "framewidth - internal", OutputOption},
310 { "frameshift", stepbuff, &framestepstr, "framestep - internal", SilentOption},
311 { "frameshift", stepbuff, &framestepstr, "framestep - internal", OutputOption},
312 { "frames", framesbuff, &framesstr, "frames - internal", SilentOption},
313 { "frames", framesbuff, &framesstr, "frames - internal", OutputOption},
314
315 { "samplerate", sampledflt, &samplestr, "Input wave sample rate (Hz)", InOutOption},
316 { "swap_wave", swapdflt, &swapstr, "Swap bytes in input wave", InOutOption},
317 { "bits_wave", bitsdflt, &bitstr, "Significant bits in input wave", SilentOption},
318 { "dB_wave", dBdflt, &dBstr, "Rel. input level (_tlf & _med only)\n", InOutOption}, /* CG */
319 { "what", whichdflt, &whichstr, "Type of model to use required", SilentOption},
320
321 (char *) 0 } ;
322
323
324 /***************** Tools for manipulating sampling rate ********************* * CG *
325 * This set of two routines allows to change and keep track of the sampling
326 * rate of the data which flows through the model. It is the responsability
327 * of each entry-point function to update the sampling rate as necessary.
328 *
329 * routine:- comment:-
330 * Samplerate returns the current value of the sampling rate
331 * SetSamplerate resets the sampling rate
332 ****************************************************************************/
333
334 static double rateCache = 0.0 ;
335
336 void setSamplerate( newval )
337 double newval ;
338 {
339 rateCache = newval ;
340 return ;
341 }
342
343 double Samplerate()
344 {
345 if( rateCache == 0 )
346 rateCache = Freq( samplestr ) ;
347
348 return( rateCache ) ;
349 }
350
351 /******************* Tools for checking for special strings ****************
352 * OptionInt( str )
353 * OptionDouble( str )
354 * OptionStringsEqual( str1, str2 ) -(defined in options.c).
355 ****************************************************************************/
356
357 double OptionDouble( str )
358 char *str ;
359 {
360 if( strcmp( str, "on" ) == 0 )
361 return( 1. ) ;
362 else if( strcmp( str, "Not_used" ) == 0 )
363 return( 0. ) ;
364 else
365 return( atof( str ) ) ;
366 }
367
368 int OptionInt( str )
369 char *str ;
370 {
371 if( strcmp( str, "on" ) == 0 )
372 return( 1 ) ;
373 else if( strcmp( str, "Not_used" ) == 0 )
374 return( 0 ) ;
375 else
376 return( atoi( str ) ) ;
377 }
378
379 int OptionLog ( str )
380 char *str ;
381 {
382 if ( strcmp( str, "off" ) == 0 )
383 return( 0 ) ;
384 else
385 return( 1 ) ;
386 }
387
388
389
390
391 /************************* Tools for scaling data ************************** * CG *
392 * This set of two routines allows to keep track of the scaling factor needed
393 * to convert the data which flows through the model into absolute units in
394 * the cgs system ( 0.0002 dyne/cm2 ==> 0 dB SPL). It is the responsability of
395 * each entry-point function to update the correct scaling factor as necessary.
396 * The user must initially specify the scaling of the input wave using the
397 * "dB_wave" option. The default is "dB_wave=60.".
398 *
399 * routine:- comment:-
400 * Scaling returns a scalar to convert data to cgs units
401 * SetScaling resets the scaling factor
402 ****************************************************************************/
403
404 static double scalingCache = 0.0 ;
405
406 void setScaling( from_rms, from_dB, to_rms, to_dB )
407 double from_rms, from_dB, to_rms, to_dB ;
408 {
409 scalingCache = pow( 10., ( from_dB - to_dB ) / 20. ) * to_rms / from_rms ;
410 }
411
412 double Scaling()
413 {
414 double rms = 200. ; /* the default: 200 rms ==> 60 dB */
415 double dB = 60. ;
416
417 if( scalingCache == 0 ) {
418
419 if( strcmp( dBstr, "off" ) != 0 )
420 dB = Scalar( dBstr ) ;
421 setScaling( rms, dB, 0.0002, 0. ) ;
422 }
423
424 return( scalingCache ) ;
425 }
426
427 /************************ entry-point functions ***************************
428 * Each entry-point function creates and initializes a "source object", and
429 * returns a pointer to this object. Each source set up by one of the routines
430 * below is designed to be the entry point for a specialized auditory-modelling
431 * process. (See also io.c for sources which read from disk).
432 * Source set-up functions always return a Source. They may take one or more
433 * sources as arguments, as a specification of the input to the process
434 * the source performs. The set up routine intializes the source structure with
435 * a pointer to a callback function, which performs the data processing when
436 * the source is used.
437 *
438 * Pointers to the entry-point functions are defined in the stage table,
439 * (see FindStage() below). The functions are called, using these pointers,
440 * from routine ModeledSource() (see below). The purpose of this is to call the
441 * functions, in the order set by the stage table, so as to initialize a chain
442 * of objects which can ultimately be used to execute the program.
443 *
444 * The source set-up routines are analogous to fopen(), (see stitch/source.c).
445 * The processing phase, (analogous to fread()), uses pull/fill/roll functions,
446 * and this execution is started from gen.c:main() by a call to SinkSource().
447 *
448 * routine:- special subroutines:-
449 * EarEntry() Ear() * CG *
450 * GenericEntry() GenericFilterBank()
451 * FilterEntry() GenericEntry()
452 * TLF_FilterEntry() TLF_GenBank() * CG *
453 * FineEntry() EarEntry() FilterEntry() TLF_FilterEntry() * CG *
454 * EnvelopeEntry() GenericEntry()
455 * ComplexEntry() GenericEntry()
456 * PolarEntry()
457 * RectifyEntry()
458 * LogEntry()
459 * UncompressEntry()
460 * SaturateEntry() Saturate()
461 * LowpassEntry() LowpassDataTypeSource()
462 * ThresholdEntry() Meddis() Mfsai()
463 * AdaptEntry()
464 * HardEntry() Saturate()
465 * IntegralEntry() LowpassDataTypeSource()
466 * DownSampleEntry() DownSampleSource() BlockSampleSource()
467 * SaiEntry() Sai()
468 * SummaryEntry() Summary()
469 * NullEntry()
470 ****************************************************************************/
471
472 /* As a means of introducing "cgm" as an alias for "fed", this NullEntry point does
473 absolutely nothing to the data, but it DOES enable us to enter the queue just above
474 the entry point for "fed". */
475
476 static Source NullEntry( source )
477 Source source ;
478 {
479 return ( source ) ;
480 }
481
482
483 /***** upsampling parameters *****/ /* CG */
484
485 static char upfdflt[] = "auto" , *upfstr = upfdflt ; /* CG */
486 static char cutoffdflt[] = "1.0" , *cutoffstr = cutoffdflt ; /* CG */
487 static char downfdflt[] = "auto" , *downfstr = downfdflt ; /* CG */
488
489 /***** ear parameters *****/ /* CG */
490
491 static char middledflt[] = "on" , *middlestr = middledflt ; /* CG */
492 static char lconcdflt[] = "0.90" , *lconcstr = lconcdflt ; /* CG */
493 static char rconcdflt[] = "1.00" , *rconcstr = rconcdflt ; /* CG */
494 static char kconcdflt[] = "0.01" , *kconcstr = kconcdflt ; /* CG */
495 static char nconcdflt[] = "2" , *nconcstr = nconcdflt ; /* CG */
496 static char lcanaldflt[] = "2.85" , *lcanalstr = lcanaldflt ; /* CG */
497 static char rcanaldflt[] = "0.35" , *rcanalstr = rcanaldflt ; /* CG */
498 static char kcanaldflt[] = "0.04" , *kcanalstr = kcanaldflt ; /* CG */
499 static char ncanaldflt[] = "4" , *ncanalstr = ncanaldflt ; /* CG */
500
501 static Source EarEntry( source ) /* CG: new entry */
502 Source source ;
503 {
504 int upfactor, downfactor ;
505 double cutoff, gain = OptionDouble( middlestr ) ;
506 DeclareNew( struct _tube_info *, concha ) ;
507 DeclareNew( struct _tube_info *, canal ) ;
508
509 if( gain ) {
510
511 /*** set up/downsampling parameters ***/
512 if( strncmp( upfstr, "auto", 4 ) == 0 ) {
513 if( strncmp( downfstr, "auto", 4 ) == 0 )
514 upfactor = MIN( AUTO, ( int ) ( ( MAXSIGNALFREQ * AUTO * 2 ) / Samplerate() + 1.0 ) ) ;
515 else
516 upfactor = ABS( OptionInt( downfstr ) ) ;
517 downfactor = upfactor ;
518 }
519 else {
520 upfactor = ABS( OptionInt( upfstr ) ) ;
521 if( strncmp( downfstr, "auto", 4 ) == 0 )
522 downfactor = upfactor ;
523 else
524 downfactor = ABS( OptionInt( downfstr ) ) ;
525 }
526
527 /*** set cutoff frequency of FIR upsampling filter ***/
528 cutoff = 0.5 * Samplerate() * Scalar( cutoffstr ) ;
529 if( downfactor > upfactor ) {
530 upfactor = MAX( 1, upfactor ) ;
531 cutoff = cutoff * ( double ) upfactor / ( double ) downfactor ;
532 }
533
534 /*** upsample input wave ***/
535 if( upfactor >= 1 ) {
536 source = UpSample( source, Samplerate(), cutoff, upfactor ) ;
537 ( void ) setSamplerate( Samplerate() * upfactor ) ;
538 ( void ) setFrames( Frames() * upfactor ) ;
539 }
540
541 /*** outer/middle ear filter ***/
542 concha->Nsegments = atoi( nconcstr ) ;
543 concha->length = atof( lconcstr ) ;
544 concha->diameter = atof( rconcstr ) * 2. ;
545 concha->att_factor = atof( kconcstr ) ;
546 canal->Nsegments = atoi( ncanalstr ) ;
547 canal->length = atof( lcanalstr ) ;
548 canal->diameter = atof( rcanalstr ) * 2. ;
549 canal->att_factor = atof( kcanalstr ) ;
550
551 source = Ear( source, Samplerate(), gain, concha, canal ) ;
552
553 Delete( concha ) ;
554 Delete( canal ) ;
555
556 /*** downsample output data ***/
557 if( downfactor >= 1 ) {
558 source = DownSampleSource( source, downfactor, 1 ) ;
559 ( void ) setSamplerate( Samplerate() / downfactor ) ;
560 ( void ) setFrames( Frames() / downfactor ) ;
561 }
562
563 }
564 return ( source ) ;
565 }
566
567
568 /***** frequency scale parameters*****/
569
570 static char qualdflt[] = "9.265" , *qualstr = qualdflt ;
571 static char limitdflt[] = "24.7Hz" , *limitstr = limitdflt ;
572 static char mmdflt[] = "0.89" , *mmstr = mmdflt ; /* CG */
573
574 static char interpdflt[] = "off" , *interpstr = interpdflt ;
575
576 /***** filterbank parameters ****/
577
578 static char maxdflt[] = "6000Hz" , *maxstr = maxdflt ; /* roy 23-12-92 */
579 static char mindflt[] = "100Hz" , *minstr = mindflt ; /* roy 23-12-92 */
580 #ifdef PC
581 static char dendflt[] = "off" , *denstr = dendflt ; /* roy 23-12-92 */
582 #else
583 static char dendflt[] = "off" , *denstr = dendflt ; /* roy 23-12-92 */
584 #endif
585 static char chansdflt[] = "75" , *chansstr = chansdflt ; /* roy 23-12-92 */
586 static char audiodflt[] = "off" , *audiostr = audiodflt ; /* CG */
587 static char infodflt[] = "off" , *infostr = infodflt ; /* CG */
588
589 static char filterdflt[] = "gtf" , *filterstr = filterdflt ; /* CG */
590
591
592 /****************************************************************************
593 * updateFrequencies()
594 * Routine called from ModeledSource(), below.
595 * It sets the frameheight (number of filter-bank channels), and initializes
596 * the array of channel centre-frequencies, (called "frequencies").
597 * These are derived from three basic parameters:
598 * option-name: string-value: default: comment:
599 * mincf_afb minstr 220Hz Minimum center frequency (Hz)
600 * maxcf_afb maxstr 4400Hz Maximum center frequency (Hz)
601 * dencf_afb denstr 4. Filter density (filters/critical band)
602 *
603 * The frameheight is calculated in the routine "NumberCenterFrequencies",
604 * and the result is copied into the "frameheightstr" by a call to the routine
605 * "setFrameheight".
606 * The "frequencies" are calculated in the routine "GenerateCenterFrequencies".
607 * (Both CenterFrequency routines are in gamma_tone.c).
608 *
609 * The frequencies are stored in a global array of center frequencies (below).
610 ****************************************************************************/
611
612 double *frequencies ; /* global array of centre frequencies */
613
614 static void reverseFrequencies( freqs, channels )
615 double *freqs ;
616 int channels ;
617 {
618 int i ;
619 double d ;
620
621 for( i=0 ; i<channels/2 ; i++ ) {
622 d = freqs[i] ;
623 freqs[i] = freqs[channels-i] ;
624 freqs[channels-i] = d ;
625 }
626 }
627
628
629 static void updateFrequencies() /* CG: modified */
630 {
631 int chans = OptionInt( chansstr ) ;
632 double min, max, density = atof( denstr ) ;
633
634 if( frequencies != (double *) 0 )
635 Delete( frequencies ) ;
636
637 SetErbParameters( Freq( limitstr ), atof( qualstr ) ) ;
638
639 if( strncmp( filterstr, "tlf", 3 ) == 0 ) {
640
641 if( chans == 0 && density == 0. )
642 chans = 1 ;
643
644 min = adjustCF( Freq( minstr ), Samplerate() ) ;
645 max = adjustCF( MAX( Freq( maxstr ), min ), Samplerate() ) ;
646 }
647
648 else {
649 min = Freq( minstr ) ;
650 max = Freq( maxstr ) ;
651 }
652
653 if( chans == 0 ) {
654 frequencies = GenerateCenterFrequencies( min, max, density ) ;
655 setFrameheight( NumberCenterFrequencies( min, max, density ) ) ;
656 }
657 else {
658 frequencies = NumberedCenterFrequencies( min, max, chans ) ;
659 setFrameheight( chans ) ;
660 }
661
662 /*
663 reverseFrequencies( Frequencies, Frameheight() ) ;
664 */
665
666 return ;
667 }
668
669
670 ChannelAxis( min, max, label )
671 double *min, *max ;
672 char **label ;
673 {
674 *min = (int) ( ErbScale( Freq( minstr ) ) * 10. ) / 10. ;
675 *max = (int) ( ErbScale( Freq( maxstr ) ) * 10. ) / 10. ;
676
677 *label = "Center Frequency [ERBs]" ;
678 }
679
680 /***** GTF auditory filter parameters *****/ /* CG */
681
682 static char orderdflt[] = "4" , *orderstr = orderdflt ;
683 static char phasedflt[] = "0" , *phasestr = phasedflt ;
684 static char gaindflt[] = "4." , *gainstr = gaindflt ;
685 static char floatdflt[] = "off" , *floatstr = floatdflt ;
686
687 static Source GenericEntry( source, proc ) /* CG */
688 Source source ;
689 int (*proc)() ;
690 {
691 int chans ;
692 Source ret ;
693
694 updateFrequencies() ;
695
696 chans = Frameheight() ;
697 ret = GenericFilterBank( source, OptionInt( interpstr ), &chans, Samplerate(),
698 frequencies, Erb, ErbScale, Scalar( gainstr ), OptionDouble( audiostr ),
699 atoi( orderstr ), atoi( phasestr ), atoi( bitstr ), Frames(), proc,
700 sizeof ( DataType ), OptionInt( infostr ) ) ; /* CG */
701
702 setFrameheight( chans ) ;
703
704 return ( ret ) ;
705 }
706
707 static Source FilterEntry( source )
708 Source source ;
709 {
710 switch( OptionInt( floatstr ) ) {
711 #ifdef FLOAT
712 case 0 :
713 case 1 :
714 return ( GenericEntry( source, DoRealFilterFloatDataArray ) ) ;
715 #else
716 case 0 :
717 return ( GenericEntry( source, DoFilterShortDataArray ) ) ;
718 case 1 :
719 return ( GenericEntry( source, DoRealFilterShortDataArray ) ) ;
720 #endif
721 case 2 :
722 return ( GenericEntry( source, DoNewFilterDataArray ) ) ;
723 }
724
725 return ( source ) ;
726 }
727
728 /***** TLF auditory filter parameters *****/ /* CG */
729
730 static char tgaindflt[] = "4." , *tgainstr = tgaindflt ; /* CG */
731 static char dsatdflt[] = "5.75e-6" , *dsatstr = dsatdflt ; /* CG */
732 static char feeddflt[] = "0.99" , *feedstr = feeddflt ; /* CG */
733 static char qrefdflt[] = "2." , *qrefstr = qrefdflt ; /* CG */
734 static char outdendflt[] = "4." , *outdenstr = outdendflt ; /* CG */
735 static char motiondflt[] = "vel" , *motionstr = motiondflt ; /* CG */
736
737 static Source TLF_FilterEntry( source ) /* CG: new entry */
738 Source source ;
739 {
740 int chans ;
741 int upfactor, downfactor ;
742 double cutoff, dsat ;
743 DeclareNew( struct _tube_info *, concha ) ;
744 DeclareNew( struct _tube_info *, canal ) ;
745
746 /*** set up/downsampling parameters ***/
747 if( strncmp( upfstr, "auto", 4 ) == 0 ) {
748 if( strncmp( downfstr, "auto", 4 ) == 0 )
749 upfactor = MIN( AUTO, ( int ) ( ( MAXSIGNALFREQ * AUTO * 2 ) / Samplerate() +1.0 ) ) ;
750 else
751 upfactor = ABS( OptionInt( downfstr ) ) ;
752 downfactor = upfactor ;
753 }
754 else {
755 upfactor = ABS( OptionInt( upfstr ) ) ;
756 if( strncmp( downfstr, "auto", 4 ) == 0 )
757 downfactor = upfactor ;
758 else
759 downfactor = ABS( OptionInt( downfstr ) ) ;
760 }
761
762 /*** set cutoff frequency of FIR upsampling filter ***/
763 cutoff = 0.5 * Samplerate() * Scalar( cutoffstr ) ;
764 if( downfactor > upfactor ) {
765 upfactor = MAX( 1, upfactor ) ;
766 cutoff = cutoff * ( double ) upfactor / ( double ) downfactor ;
767 }
768
769 /*** upsample input wave ***/
770 if( upfactor >= 1 ) {
771 source = UpSample( source, Samplerate(), cutoff, upfactor ) ;
772 ( void ) setSamplerate( Samplerate() * upfactor ) ;
773 ( void ) setFrames( Frames() * upfactor ) ;
774 }
775
776 /*** set outer/middle ear parameters ***/
777 concha->Nsegments = atoi( nconcstr ) ;
778 concha->length = atof( lconcstr ) ;
779 concha->diameter = atof( rconcstr ) * 2. ;
780 concha->att_factor = atof( kconcstr ) ;
781 canal->Nsegments = atoi( ncanalstr ) ;
782 canal->length = atof( lcanalstr ) ;
783 canal->diameter = atof( rcanalstr ) * 2. ;
784 canal->att_factor = atof( kcanalstr ) ;
785
786 /*** set bank parameters ***/
787 updateFrequencies() ;
788 SetERBscaling( atof( mmstr ) ) ;
789 chans = Frameheight() ;
790
791 /*** OHC normalization: converts from cgs units (0 dB SPL=>0.0002 dynes/cm2) to input wave units ***/
792 dsat = atof( dsatstr ) / Scaling() ;
793
794 /*** process data and downsample output ***/
795 source = TLF_GenBank( source, OptionInt( interpstr ), OptionInt( infostr ), &chans, &downfactor,
796 Samplerate(), frequencies, Scalar( tgainstr ), atof( outdenstr ),
797 atof( qrefstr ), atof( feedstr ), dsat, motionstr, concha, canal ) ;
798
799 /*** reset sampling rate and file-format strings ***/
800 ( void ) setFrameheight( chans ) ;
801 ( void ) setSamplerate ( Samplerate() / downfactor ) ;
802 ( void ) setFrames( Frames() / downfactor ) ;
803
804 Delete( concha ) ;
805 Delete( canal ) ;
806
807 return ( source ) ;
808 }
809
810 static Source FineEntry(source ) /* CG: new Entry */
811 Source source ;
812 {
813 if( strncmp( filterstr, "off", 3 ) == 0 )
814 source = EarEntry( source ) ;
815
816 else {
817
818 if( strncmp( filterstr, "tlf", 3 ) == 0 )
819 source = TLF_FilterEntry( source ) ;
820
821 else {
822 source = EarEntry( source ) ;
823 source = FilterEntry( source ) ;
824 }
825 }
826
827 return( source ) ;
828 }
829
830 static Source EnvelopeEntry( source )
831 Source source ;
832 {
833 #ifdef FLOAT
834 return ( GenericEntry( source, DoRealEnvelopeFloatDataArray ) ) ;
835 #else
836 if( OptionInt( floatstr ) != 0 )
837 return ( GenericEntry( source, DoRealEnvelopeShortDataArray ) ) ;
838 else
839 return ( GenericEntry( source, DoEnvelopeShortDataArray ) ) ;
840 #endif
841 }
842
843 static Source ComplexEntry( source )
844 Source source ;
845 {
846 Source ret ;
847
848 #ifdef FLOAT
849 ret = GenericEntry( source, DoComplexFilterFloatDataArray ) ;
850 #else
851 ret = GenericEntry( source, DoComplexFilterShortDataArray ) ;
852 #endif
853 setFrameheight( Frameheight() * 2 ) ;
854
855 return ( ret ) ;
856 }
857
858 /******* [fbm] [bmm] [fcp,fcr] stage: "auditory filter output" ************/
859
860 static Option fbmopts[] = {
861
862 { "upfactor", upfdflt, &upfstr, "Upsampling factor (off, auto, int)", SilentOption}, /* CG */
863 { "cutoff", cutoffdflt, &cutoffstr, "LP cutoff as a fraction of Nyquist freq.", SilentOption}, /* CG */
864 { "downfactor", downfdflt, &downfstr, "Downsampling factor (off, auto, int)\n", SilentOption}, /* CG */
865
866 { "middle_ear", middledflt, &middlestr, "Enable outer/middle ear function\n", InOutOption}, /* CG */
867 { "nconcha_ear", nconcdflt, &nconcstr, "Number of segments in concha", SilentOption}, /* CG */
868 { "lconcha_ear", lconcdflt, &lconcstr, "Total length of concha (cm)", SilentOption}, /* CG */
869 { "rconcha_ear", rconcdflt, &rconcstr, "Radius of concha (cm)", SilentOption}, /* CG */
870 { "kconcha_ear", kconcdflt, &kconcstr, "Attn. constant of concha (1/cm)", SilentOption}, /* CG */
871 { "ncanal_ear", ncanaldflt, &ncanalstr, "Number of segments in ear canal", SilentOption}, /* CG */
872 { "lcanal_ear", lcanaldflt, &lcanalstr, "Length of ear canal (cm)", SilentOption}, /* CG */
873 { "rcanal_ear", rcanaldflt, &rcanalstr, "Radius of ear canal (cm)", SilentOption}, /* CG */
874 { "kcanal_ear", kcanaldflt, &kcanalstr, "Attn. constant of ear canal (1/cm)\n", SilentOption}, /* CG */
875
876 { "channels_afb", chansdflt, &chansstr, "Number of channels in filter", InOutOption},
877 { "mincf_afb", mindflt, &minstr, "Minimum center frequency (Hz)", InOutOption},
878 { "maxcf_afb", maxdflt, &maxstr, "Maximum center frequency (Hz)", InOutOption},
879 { "dencf_afb", dendflt, &denstr, "Filter density (filters/critical band)", InOutOption},
880 { "info_afb", infodflt, &infostr, "Prints filterbank information (to stderr).", InputOption}, /* CG */
881 { "interp_afb", interpdflt, &interpstr, "Levels of interpolation to apply", OutputOption},
882 { "interp_afb", interpdflt, &interpstr, "Levels of interpolation to apply", SilentOption},
883 {"audiogram_afb", audiodflt, &audiostr, "Audiogram equalisation parameter", SilentOption}, /* CG */
884 { "bwmin_afb", limitdflt, &limitstr, "Minimum filter bandwith", InOutOption},
885 { "quality_afb", qualdflt, &qualstr, "Ultimate qualtity factor of filters", InOutOption},
886 { "mmerb_afb", mmdflt, &mmstr, "Length of 1 erb-rate unit along BM (mm)\n", InOutOption}, /* CG */
887
888 { "filter", filterdflt, &filterstr, "Select auditory filter (gtf, tlf, off)\n", InOutOption}, /* CG */
889
890 { "float_gtf", floatdflt, &floatstr, "Floating point filter calculations", OutputOption},
891 { "float_gtf", floatdflt, &floatstr, "Floating point filter calculations", SilentOption},
892 { "phase_gtf", phasedflt, &phasestr, "Phase compensation option", InOutOption},
893 { "order_gtf", orderdflt, &orderstr, "Filter order", InOutOption},
894 { "gain_gtf", gaindflt, &gainstr, "Filter output amplification\n", InOutOption}, /* CG */
895
896 { "motion_tlf", motiondflt, &motionstr, "BM output motion (disp, vel)", InOutOption}, /* CG */
897 { "outdencf_tlf", outdendflt, &outdenstr, "Filter density outside display range", InOutOption}, /* CG */
898 { "qref_tlf", qrefdflt, &qrefstr, "Local Q-factor of BM segment", InOutOption}, /* CG */
899 { "feedback_tlf", feeddflt, &feedstr, "Feedback gain of OHCs (0 to 0.999)", InOutOption}, /* CG */
900 { "dsat_tlf", dsatdflt, &dsatstr, "Half-saturation displacement (cm)", InOutOption}, /* CG */
901 { "gain_tlf", tgaindflt, &tgainstr, "Filter output amplification\n", InOutOption}, /* CG */
902
903 ( char * ) 0 } ;
904
905 static void polar_callback( state, bytes, output, end, input )
906 Source state ;
907 ByteCount *bytes ;
908 scomplex *output, *end, *input ;
909 {
910 register scomplex *iptr = input ;
911 register scomplex *optr = output ;
912 register scomplex *eptr = end ;
913
914 while( optr < eptr ) {
915 optr->real = imB( (long) iptr->real * iptr->real + (long) iptr->imag * iptr->imag ) >> 1 ;
916 optr->imag = iatan2( iptr->imag, iptr->real ) ;
917 iptr++ ;
918 optr++ ;
919 }
920
921 return ;
922 }
923
924 static Source PolarEntry( source )
925 Source source ;
926 {
927 return ( NewSimpleProcessingSource( polar_callback, source, "model.c polar conversion" ) ) ;
928 }
929
930 static void fullwave_callback( state, bytes, buffer, end, input )
931 Source state ;
932 ByteCount *bytes ;
933 DataType *buffer, *end, *input ;
934 {
935 register DataType *iptr = input ;
936 register DataType *optr = buffer ;
937 register DataType *eptr = end ;
938
939 if( optr < eptr )
940 do
941 if( *iptr > 0 )
942 *optr++ = *iptr++ ;
943 else
944 *optr++ = -*iptr++ ;
945
946 while( optr < eptr ) ;
947
948 return ;
949 }
950
951
952 /* rectification */
953
954 static char rectdflt[] = "off", *rectstr = rectdflt ;
955
956 /************** [fbr] stage: "rectified filter output" ******************/
957
958 static Option fbropts[] = {
959
960 { "rectify", rectdflt, &rectstr, "Rectify filter output", InOutOption},
961
962 ( char * ) 0 } ;
963
964
965 static void halfwave_callback( state, bytes, buffer, end, input )
966 Source state ;
967 ByteCount *bytes ;
968 DataType *buffer, *end, *input ;
969 {
970 register DataType *iptr = input ;
971 register DataType *optr = buffer ;
972 register DataType *eptr = end ;
973
974 if( optr < eptr )
975 do
976 if( *iptr > 0 )
977 *optr++ = *iptr++ ;
978 else
979 *optr++ =0,*iptr++ ;
980
981 while( optr < eptr ) ;
982
983 return ;
984 }
985
986 static Source RectifyEntry( source )
987 Source source ;
988 {
989 switch( OptionInt( rectstr ) ) {
990
991 case 1 :
992 return ( SharingSource( NewSimpleProcessingSource( halfwave_callback, source, "model.c recification" ), source ) ) ;
993
994 case 2:
995 return ( SharingSource( NewSimpleProcessingSource( fullwave_callback, source, "model.c recification" ), source ) ) ;
996
997 default :
998 return ( source ) ;
999 }
1000 }
1001
1002
1003 /*********** [fbc] [fec] stage: "compressed filter output" **************/
1004
1005 /* logaritmic compression function */
1006
1007 static char logdflt[] = "log", *logstr = logdflt ;
1008 static char powdflt[] = "off", *powstr = powdflt ;
1009
1010 static Option fbcopts[] = {
1011
1012 { "compress", logdflt, &logstr, "Compression (log, power value [0-1], off)", InOutOption},
1013 ( char * ) 0 } ;
1014
1015
1016 #ifdef FLOAT
1017 static void mB_callback( state, bytes, buffer, end, input )
1018 Pointer state ;
1019 ByteCount *bytes ;
1020 DataType *buffer, *end, *input ;
1021 {
1022 register DataType *iptr = input ;
1023 register DataType *optr = buffer ;
1024 register DataType *eptr = end ;
1025 double pw;
1026
1027 if (!strcmp(logstr, "log") || !strcmp(logstr, "on"))
1028 ;
1029 else
1030 {
1031 pw=(double)atof(logstr);
1032 strcpy(powstr, "on");
1033 if (pw > 1.0) {
1034 fprintf(stderr, "The value of power compression cannot be more than 1.0\n");
1035 exit(-125);}
1036 }
1037
1038 if( optr < eptr )
1039 do{
1040 if( *iptr >= 1. ){
1041 if (!(strcmp(powstr, "off"))){
1042 *optr = log10( *iptr ) * 2000. ;}
1043 else{
1044 *optr = (float) pow((double)*iptr, (double) pw) * 100./(pw); }
1045 }
1046 else
1047 *optr = 0. ; /* -10. Changed from -10, AJD 29th August, 1995. */
1048 iptr++; optr++; }
1049 while( optr < eptr ) ;
1050
1051 return ;
1052
1053 }
1054 #endif
1055
1056 static Source LogEntry( source )
1057 Source source ;
1058 {
1059 if( OptionLog( logstr ) != 0 )
1060 #ifdef FLOAT
1061 return ( SharingSource( NewSimpleProcessingSource( mB_callback, source, "model.c compression" ), source ) ) ;
1062 #else
1063 return ( SharingSource( milliBellShortSource( source ), source ) ) ;
1064 #endif
1065 else
1066 return ( source ) ;
1067 }
1068
1069 /*********** [fbu] [feu] stage: "uncompressed filter output" **************/
1070
1071 /***** uncompress data by raising to a power *****/
1072
1073 static char powerdflt[] = "off", *powerstr = powerdflt ;
1074
1075 static Option fbuopts[] = {
1076
1077 { "power", powerdflt, &powerstr, "Power of Compression", SilentOption},
1078
1079 ( char * ) 0 } ;
1080
1081
1082 struct _uncompress_state { double power ; } ;
1083
1084 static void uncompress_callback( state, bytes, buffer, end, input )
1085 struct _uncompress_state *state ;
1086 ByteCount *bytes ;
1087 DataType *buffer, *end, *input ;
1088 {
1089 register DataType *iptr = input ;
1090 register DataType *optr = buffer ;
1091 register DataType *eptr = end ;
1092 register double power = state->power ;
1093
1094 if( optr < eptr )
1095 do
1096 *optr++ = pow( 10., *iptr++ * power ) ;
1097 while( optr < eptr ) ;
1098
1099 return ;
1100 }
1101 static Source UncompressEntry( source )
1102 Source source ;
1103 {
1104 DeclareNew( struct _uncompress_state *, state ) ;
1105
1106 if( OptionDouble( powerstr ) != 0.0 ) {
1107
1108 state->power = OptionDouble( powerstr ) / 2000. ;
1109
1110 return ( SharingSource (NewProcessingSource( state, uncompress_callback, stitch_free, source, "model.c compression" ), source ) ) ;
1111 }
1112 else
1113 return ( source ) ;
1114 }
1115
1116 /*********** [fbs] [fes] stage: "saturated filter output" **************/
1117
1118 /***** provide for possible saturation at this point *****/
1119
1120 static char satdflt[] = "off", *satstr = satdflt ;
1121
1122 static Option fbsopts[] = {
1123
1124 { "saturate", satdflt, &satstr, "Introduce Saturation of non-linearity\n", SilentOption},
1125
1126 ( char * ) 0 } ;
1127
1128
1129 struct _sat_state { int saturation ; } ;
1130
1131 static void sat_callback( state, bytes, buffer, end, input )
1132 struct _sat_state *state ;
1133 ByteCount *bytes ;
1134 DataType *buffer, *end, *input ;
1135 {
1136 register DataType *iptr = input ;
1137 register DataType *optr = buffer ;
1138 register DataType *eptr = end ;
1139
1140 if( optr < eptr )
1141 do {
1142
1143 if( *iptr > 0 )
1144 *optr++ = SCALE( *iptr ) / ( SCALE( 1 ) + SCALE( *iptr ) / state->saturation ) ;
1145 else
1146 *optr++ = SCALE( *iptr ) / ( SCALE( 1 ) - SCALE( *iptr ) / state->saturation ) ;
1147 iptr++ ;
1148
1149 } while( optr < eptr ) ;
1150
1151 return ;
1152 }
1153
1154 static Source Saturate( source, str )
1155 Source source ;
1156 char *str ;
1157 {
1158 DeclareNew( struct _sat_state *, state ) ;
1159
1160 if( OptionInt( str ) != 0 ) {
1161
1162 state->saturation = OptionInt( str ) ;
1163
1164 return ( SharingSource( NewProcessingSource( (Pointer) state, sat_callback, stitch_free, source, "model.c stauration" ), source ) ) ;
1165 }
1166 else
1167 return ( source ) ;
1168 }
1169
1170 static Source SaturateEntry( source )
1171 Source source ;
1172 {
1173 return( Saturate( source, satstr ) ) ;
1174 }
1175
1176 #if 00
1177 /***** new processing entry *****/
1178
1179 static char zongdflt[] = "off", *zongstr = zongdflt ; /* parameter default for table.c */
1180
1181 static Source ZongEntry( source )
1182 Source source ;
1183 {
1184 int i, chans = Frameheight() ;
1185 DeclareNewArray( WuState *, states, chans, "model.c for states" ) ;
1186
1187 /* for all of the channels create a new wu cels object */
1188
1189 for( i=0 ; i<chans ; i++ )
1190 states[ i ] = NewWu( zongstr ) ; /* call constructor of new wu cell */
1191
1192 /* use general purpose source for processing multiplexed files with these cells */
1193
1194 return (source ) ;
1195 return ( NewMultiplexedSource( states, WuMultiplexedDataArray, DeleteWu, chans, source, "model.c wu" ) ) ;
1196 }
1197 #endif
1198
1199 /*********** [fbl] [fel] stage: "low-pass filtered filter output ***********/
1200
1201 /* low pass filtering */
1202
1203 static char lstagedflt[] = "off", *lstagestr = lstagedflt ;
1204 static char lupdflt[] = "0.5ms", *lupstr = lupdflt ;
1205 static char ldowndflt[] = "1", *ldownstr = ldowndflt ;
1206 static char llossdflt[] = "1", *llossstr = llossdflt ;
1207 static char lvlossdflt[] = "0", *lvlossstr = lvlossdflt ;
1208 static char ligaindflt[] = "1", *ligainstr = ligaindflt ;
1209
1210 static Option fblopts[] = {
1211
1212 { "ligain_lpf", ligaindflt, &ligainstr, "Gain of integration stage\n", OutputOption},
1213 { "ligain_lpf", ligaindflt, &ligainstr, "Gain of integration stage\n", SilentOption},
1214 { "lvloss_lpf", lvlossdflt, &lvlossstr, "Rest level for loss", OutputOption},
1215 { "lvloss_lpf", lvlossdflt, &lvlossstr, "Rest level for loss", SilentOption},
1216 { "lloss_lpf", llossdflt, &llossstr, "Loss time constant", OutputOption},
1217 { "lloss_lpf", llossdflt, &llossstr, "Loss time constant", SilentOption},
1218 { "ltdown_lpf", ldowndflt, &ldownstr, "Downward time constant in ms", OutputOption},
1219 { "ltdown_lpf", ldowndflt, &ldownstr, "Downward time constant in ms", SilentOption},
1220 { "ltup_lpf", lupdflt, &lupstr, "Upward time constant in ms", SilentOption},
1221 { "lstages_lpf", lstagedflt, &lstagestr, "Stages of integration\n", SilentOption},
1222
1223 ( char * ) 0 } ;
1224
1225 static Source LowpassEntry( source )
1226 Source source ;
1227 {
1228 return ( LowpassDataTypeSource( source, OptionInt( lstagestr ), Frameheight(), Samples( lupstr, Samplerate() ), Samples( ldownstr, Samplerate() ), Scalar( ligainstr ) ) ) ;
1229 }
1230
1231
1232 /*********** [nap,fbt] [fet] stage: "neural activity pattern" **************/
1233
1234 /***** transduction switch *****/ /* CG */
1235
1236 static char transdflt[] = "at", *transstr = transdflt ; /* CG */
1237
1238
1239 /***** meddis inner haircell model *****/ /* CG */
1240
1241 static char meddisdflt[] = "1.", *meddisstr = meddisdflt ;
1242 static char fibredflt[] ="medium", *fibrestr = fibredflt ; /* CG */
1243 static char thresdflt[] = "0.", *thresstr = thresdflt ; /* CG */
1244
1245 Source Meddis( input, chans, samplerate, scalar ) /* CG: modified */
1246 Source input ;
1247 int chans ;
1248 double samplerate, scalar ;
1249 {
1250 char *state ;
1251 double coupling = 100. / pow( 10., atof( thresstr ) / 20. ) ;
1252
1253 /*** convert from filterbank units to meddis units (30 dB => 1 rms ) ***/
1254
1255 /* first convert from filterbank output units to cgs units (0 dB SPL => 0.0002 dynes/cm2) ***/
1256 ( void ) setScaling( 0.0002 / Scaling() * FILTERBANK_SCALE * 4.0, 0., 0.0002, 0. ) ;
1257
1258 /* second convert from cgs units to meddis units (30 dB => 1 rms) ***/
1259 ( void ) setScaling( 0.0002 / Scaling(), 0., MEDDIS_RMS, MEDDIS_dB ) ;
1260
1261 /*** start array of Meddis hair cells ***/
1262 coupling = coupling * Scaling() ;
1263 state = NewHaircells( chans, samplerate, scalar, coupling, fibrestr ) ;
1264 return ( NewProcessingSource( state, DoHaircells, CloseHaircells, input, "model.c meddis" ) ) ;
1265 }
1266
1267 /***** adaptive thresholding *****/
1268
1269 static char stxdflt[] = "1.", *stxstr = stxdflt ; /* CG 23-03-94 */
1270 static char risedflt[] = "10000.", *risestr = risedflt ;
1271 static char rapiddflt[] = "0.6", *rapidstr = rapiddflt ;
1272 static char fastdflt[] = "0.2", *faststr = fastdflt ;
1273 static char propdflt[] = "0.5", *propstr = propdflt ;
1274 static char latdflt[] = "20.", *latstr = latdflt ; /* roy 23-12-92 */
1275 static char vdraindflt[] = "5", *vdrainstr = vdraindflt ;
1276 static char timesdflt[] = "2", *timesstr = timesdflt ;
1277
1278 static char compdflt[] = "on", *compstr = compdflt ; /* mha 22/1/93 */
1279
1280
1281 static Option fbtopts[] = {
1282
1283 { "transduction", transdflt, &transstr, "Select transduction function (at, meddis, off)\n",InOutOption}, /* CG */
1284
1285 { "trise_at", risedflt, &risestr, "Threshold adaptation rate (upwards)", InOutOption},
1286 {"t1recovery_at", rapiddflt, &rapidstr, "Initial recovery rate relative to filter", InOutOption},
1287 {"t2recovery_at", fastdflt, &faststr, "Secondary recovery rate relative to filter", InOutOption},
1288 { "propt2t1_at", propdflt, &propstr, "Relative height of secondary adaptation", InOutOption},
1289 { "frecovery_at", latdflt, &latstr, "Recovery rate across frequency", InOutOption},
1290 { "reclimit_at", vdraindflt, &vdrainstr, "Limitation on recovery level", InOutOption},
1291 { "times_at", timesdflt, &timesstr, "Oversampling of calculation of threshold", OutputOption},
1292 { "times_at", timesdflt, &timesstr, "Oversampling of calculation of threshold", SilentOption},
1293 {"compensate_at", compdflt, &compstr, "Cochlea output compensation", SilentOption},
1294 { "gain_at", stxdflt, &stxstr, "Adaptive thresholding output gain\n", InOutOption}, /* CG */
1295
1296 { "fibre_med", fibredflt, &fibrestr, "Spont-rate fibre type (medium, high)", InOutOption}, /* CG */
1297 { "thresh_med", thresdflt, &thresstr, "Haircell threshold shift (dB)", InOutOption}, /* CG */
1298 { "gain_med", meddisdflt, &meddisstr, "Meddis haircell model output gain\n", InOutOption}, /* CG */
1299
1300 ( char * ) 0 } ;
1301
1302 static Source ThresholdEntry( source ) /* CG: modified */
1303 Source source ;
1304 {
1305 double density ;
1306
1307 if( OptionInt( chansstr ) == 0 )
1308 density = OptionDouble( denstr ) ;
1309 else
1310 density = OptionInt( chansstr ) / ( ErbScale( Freq( maxstr ) ) - ErbScale( Freq( minstr ) ) ) ;
1311
1312 if( strncmp( transstr, "off", 3 ) == 0 )
1313 source = source ;
1314
1315 else {
1316
1317 if( strncmp( transstr, "med", 3 ) == 0 )
1318 source = Meddis( source, Frameheight(), Samplerate(), OptionDouble( meddisstr ) ) ;
1319
1320 else {
1321 compensate = OptionDouble( compstr ) ;
1322
1323 source = NewProcessingSource(
1324 newCorti(
1325 Frameheight(), Samplerate(), frequencies, Erb,
1326 atof( risestr ), atof( latstr ) * density,
1327 atof( rapidstr ), atof( faststr ), atof( propstr ),
1328 log10( Scalar( vdrainstr ) ) * 2000.,
1329 (int) ( density * atof( latstr ) / Samplerate() + 1. ) * atoi( timesstr ),
1330 OptionDouble( stxstr )
1331 ), (void ( * )()) Corti, closeCorti,
1332 source,
1333 "model.c thresholding"
1334 ) ;
1335
1336 }
1337 }
1338 return ( source ) ;
1339 }
1340
1341 /* modulation frequency image */
1342
1343 static char stepmfdflt[] = "250Hz", *stepmfstr = stepmfdflt ;
1344 static char maxmfdflt[] = "250Hz", *maxmfstr = maxmfdflt ;
1345 static char minmfdflt[] = "50Hz", *minmfstr = minmfdflt ;
1346 static char denmfdflt[] = "off", *denmfstr = denmfdflt ;
1347
1348 #ifndef DSP32
1349
1350 Source Mfsai( source, segment ) /* CG */
1351 Source source ;
1352 int segment ;
1353 {
1354 extern char *filestr ;
1355 Source mfsource = FileNameSource( filestr ) ;
1356 int frameheight = Frameheight() ;
1357 int i ;
1358
1359 frequencies = GenerateCenterFrequencies( Freq( minmfstr ), Freq( maxmfstr ), OptionDouble( denmfstr ) ) ;
1360 setFrameheight( NumberCenterFrequencies( Freq( minmfstr ), Freq( maxmfstr ), OptionDouble( denmfstr ) ) ) ;
1361
1362 mfsource = GenericEntry( mfsource, DoFilterShortDataArray ) ;
1363 /* mfsource = GenericEntry( mfsource, DoNewFilterDataArray ) ; */
1364 mfsource = NewProcessingSource(
1365 newCorti(
1366 Frameheight(), Samplerate(), frequencies, Erb,
1367 atof( risestr ), atof( latstr ) * OptionDouble( denmfstr ),
1368 atof( rapidstr ), atof( faststr ), atof( propstr ),
1369 log10( Scalar( vdrainstr ) ) * 2000., /* convert to millibells */
1370 (int) ( OptionDouble( denmfstr ) * atof( latstr ) / Samplerate() + 1. ) * atoi( timesstr ),
1371 0
1372 ), (void ( * )()) Corti, closeCorti,
1373 mfsource,
1374 "model.c thresholding"
1375 ) ;
1376
1377 return ( mfsource ) ;
1378 }
1379
1380 #endif
1381 /***** long term adaptation - not implemented - used to sneak in modulation frequency thing *****/
1382
1383 static char adapdflt[] = "0", *adapstr = adapdflt ;
1384
1385 static Source AdaptEntry( source )
1386 Source source ;
1387 {
1388 #ifndef DSP32
1389 if( OptionDouble( denmfstr ) > 0 )
1390 source = Mfsai( source ) ;
1391 #endif
1392 return( source ) ;
1393 }
1394
1395 /*********** [fba] [fea] stage: "adapted transduced filter output" *********/
1396
1397 static Option fbaopts[] = {
1398
1399 { "mmincf_mfb", minmfdflt, &minmfstr, "Minimum modulation frequency (Hz)", SilentOption},
1400 { "mmaxcf_mfb", maxmfdflt, &maxmfstr, "Maximum modulation frequency (Hz)", SilentOption},
1401 { "mdencf_mfb", denmfdflt, &denmfstr, "Modulation filter density ", SilentOption},
1402 { "stepcf_mfb", stepmfdflt, &stepmfstr, "Step between images\n", SilentOption},
1403
1404 { "tadaptation", adapdflt, &adapstr, "Time constant of long term adaptation\n", SilentOption},
1405
1406 ( char * ) 0 } ;
1407
1408
1409
1410 /***** hard limiting *****/
1411
1412 static char harddflt[] = "off", *hardstr = harddflt ;
1413
1414 static Source HardEntry( source )
1415 Source source ;
1416 {
1417 return( Saturate( source, hardstr ) ) ;
1418 }
1419
1420 /*********** [fbh] [feh] stage: "hard limited filter output" **************/
1421
1422 static Option fbhopts[] = {
1423
1424 { "hard_limit", harddflt, &hardstr, "Hardlimit firing rate before integration\n",OutputOption},
1425 { "hard_limit", harddflt, &hardstr, "Hardlimit firing rate before integration\n",SilentOption},
1426
1427 ( char * ) 0 } ;
1428
1429
1430 /***** [sgm,cgm,fbd,fbi] [fed,fei] stage: "integrated filter output" *******/
1431
1432 /***** temporal integration *****/
1433
1434 static char stagedflt[] = "off", *stagestr = stagedflt ;
1435 static char updflt[] = "8ms", *upstr = updflt ;
1436 static char downdflt[] = "1", *downstr = downdflt ;
1437 static char lossdflt[] = "1", *lossstr = lossdflt ;
1438 static char vlossdflt[] = "0", *vlossstr = vlossdflt ;
1439 static char igaindflt[] = "1", *igainstr = igaindflt ;
1440
1441 static Option fbiopts[] = {
1442
1443 { "stages_idt", stagedflt, &stagestr, "Stages of integration", InOutOption},
1444 { "igain_idt", igaindflt, &igainstr, "Gain of integration stage\n", OutputOption},
1445 { "igain_idt", igaindflt, &igainstr, "Gain of integration stage\n", SilentOption},
1446
1447 { "vloss_idt", vlossdflt, &vlossstr, "Rest level for loss", OutputOption},
1448 { "vloss_idt", vlossdflt, &vlossstr, "Rest level for loss", SilentOption},
1449 { "loss_idt", lossdflt, &lossstr, "Loss time constant", OutputOption},
1450 { "loss_idt", lossdflt, &lossstr, "Loss time constant", SilentOption},
1451 { "tdown_idt", downdflt, &downstr, "Downward time constant in ms", OutputOption},
1452 { "tdown_idt", downdflt, &downstr, "Downward time constant in ms", SilentOption},
1453 { "tup_idt", updflt, &upstr, "Low-pass filter time constant", InOutOption},
1454
1455 ( char * ) 0 } ;
1456
1457 static Source IntegralEntry( source )
1458 Source source ;
1459 {
1460 return ( LowpassDataTypeSource( source, OptionInt( stagestr ), Frameheight(), Samples( upstr, Samplerate() ), Samples( downstr, Samplerate() ), Scalar( igainstr ) ) ) ;
1461 }
1462
1463
1464 /* downsampling */
1465
1466 static char downsdflt[] = "off", *downsstr = downsdflt ;
1467
1468 static Option dwnopts[] = {
1469
1470 { "downsample", downsdflt, &downsstr, "Downsampling over time", InOutOption},
1471 { "frstep_epn", downsdflt, &downsstr, "Downsampling over time\n", InOutOption},
1472
1473 (char *) 0 } ;
1474
1475 static Source DownSampleEntry( source )
1476 Source source ;
1477 {
1478 int spacing = Samples( downsstr, Samplerate() ) ;
1479 int channels = Frameheight() * Framewidth() ;
1480
1481 if( spacing != 0 ) {
1482
1483 #if defined( PC ) || defined( DSP32 )
1484 source = NewSegmentingSource( source, Frameheight() * Framewidth() * sizeof ( DataType ) * 4 ) ;
1485 #endif
1486
1487 if( spacing > 0 )
1488 source = DownSampleSource( source, spacing, channels ) ;
1489 else {
1490 spacing = -spacing ;
1491 source = BlockSampleSource( source, spacing, channels ) ;
1492 }
1493
1494 setFramestep( spacing ) ;
1495
1496 setFrames( Frames() / spacing ) ;
1497 }
1498
1499 return( source ) ;
1500 }
1501
1502
1503 /* stabilised image defaults */
1504
1505 static char llimdflt[] = "1.5c" , *llimstr = llimdflt ;
1506 static char ulimdflt[] = "24ms" , *ulimstr = ulimdflt ;
1507
1508 static char saidflt[] = "1" , *saistr = saidflt ;
1509 #ifdef PC
1510 static char pwidthdflt[] = "20ms" , *pwidthstr = pwidthdflt ;
1511 #else
1512 static char pwidthdflt[] = "35ms" , *pwidthstr = pwidthdflt ; /* roy 23-12-92 */
1513 #endif
1514 /* static char nwidthdflt[] = "-5ms" , *nwidthstr = nwidthdflt ; roy 23-12-92 */
1515
1516 static char ltlimdflt[] = "150Hz" , *ltlimstr = ltlimdflt ;
1517 static char utlimdflt[] = "20Hz" , *utlimstr = utlimdflt ;
1518 static char decaydflt[] = "30ms" , *decaystr = decaydflt ;
1519 static char cgmdflt[] = "2.5" , *cgmstr = cgmdflt ; /* 30ms > 1.25 roy 23-12-92 */
1520 static char ttdflt[] = "5" , *ttstr = ttdflt ; /* 8ms > 10 roy 23-12-92 */
1521
1522 static char sustdflt[] = "0" , *susthreshstr = sustdflt ;
1523
1524 static char swdflt[] = "off" , *swstr = swdflt ;
1525
1526 #ifdef PC
1527 static char stepdflt[] = "15.25ms" , *stepstr = stepdflt ;
1528 #else
1529 static char stepdflt[] = "16ms" , *stepstr = stepdflt ;
1530 #endif
1531
1532 /* spiral parameters */
1533
1534 static char zerodflt[] = "off" , *zerostr = zerodflt ;
1535 static char formdflt[] = "arch" , *formstr = formdflt ;
1536 static char origdflt[] = "3.072" , *origstr = origdflt ;
1537
1538 static char ArchStr[] = "arch" ;
1539 static char LogStr[] = "log" ;
1540
1541 static char expodflt[] = "off" , *expostr = expodflt ;
1542
1543 /*********** [spl,sai] [sie] stage: "stabilized auditory image" ************/
1544
1545 static Option saiopts[] = {
1546
1547 { "frstep_aid", stepdflt, &stepstr, "Step between frames of the auditory image (ms)",InOutOption},
1548 { "pwidth_aid", pwidthdflt, &pwidthstr, "Positive width of auditory image (ms)", InOutOption},
1549 { "nwidth_aid", nwidthdflt, &nwidthstr, "Negative width of auditory image (ms)", InOutOption},
1550
1551 { "form_spd", formdflt, &formstr, "Form of spiral: Archemedian or log", InputOption},
1552 { "zeroline_spd", zerodflt, &zerostr, "Draw zero axis of spiral", InOutOption},
1553 { "orig_spd", origdflt, &origstr, "Spiral rotation and circuit removal\n", InOutOption},
1554
1555 { "napdecay_ai", cgmdflt, &cgmstr, "Neural activity decay rate in %/ms", InOutOption},
1556 { "stdecay_ai", ttdflt, &ttstr, "Strobe-threshold decay rate in %/ms", InOutOption},
1557 {"stcrit_ai", susldflt, &suslevelstr,"Strobe criterion (1 to 5) ", InOutOption},
1558 {"stlag_ai" , stlagdflt, &stlagstr, "Auditory image strobe lag time (in ms)", InOutOption},
1559 { "stthresh_ai", sustdflt, &susthreshstr, "Strobe threshold set to all points above this", SilentOption},
1560 { "decay_ai", decaydflt, &decaystr, "Auditory image decay time constant", InOutOption},
1561 { "stinfo_ai", swdflt, &swstr, "Strobe information (off, on, filename)\n", InOutOption},
1562
1563 { "utrate_ai", utlimdflt, &utlimstr, "Disconnected in R5.6", SilentOption},
1564 { "ltrate_ai", ltlimdflt, &ltlimstr, "Disconnected in R5.6", SilentOption},
1565 { "ulim_sas", ulimdflt, &ulimstr, "Upper integration limit for auditory image", SilentOption},
1566 { "llim_sas", llimdflt, &llimstr, "Lower integration limit for auditory image\n", SilentOption},
1567
1568 { "exponential_decay" , expodflt, &expostr , "Exponential trigger Decay", SilentOption},
1569
1570 ( char * ) 0 } ;
1571
1572 /* generate Stabilised image in image.c */
1573
1574 static Source SaiEntry( source ) /* CG */
1575 Source source ;
1576 {
1577 int framestep = Samples( stepstr, Samplerate() ) / Framestep() ;
1578 int pwidth = Samples( pwidthstr, Samplerate() ) / Framestep() ;
1579 int nwidth = Samples( nwidthstr, Samplerate() ) / Framestep() ;
1580 int stlag = Samples( stlagstr, Samplerate() ) / Framestep() ;
1581
1582
1583 /* Convert arguments for spiral drawing. See spiral.ch */
1584
1585 #ifndef DSP32
1586 if (strncmp(formstr, ArchStr, strlen( formstr) ) == 0) form_spl = 'A';
1587 else if (strncmp(formstr, LogStr, strlen( formstr) ) == 0) form_spl = 'L';
1588 else stitch_error("gensai: unknown form_spl\n");
1589
1590 axis_spl = OptionInt( zerostr ) ;
1591 zero_spl = OptionDouble( origstr ) ;
1592 #endif
1593
1594 /* Hack so that spirals never include transient info. */
1595 if (strncmp(whichstr,"spl", strlen("spl")) == 0)
1596 { nwidth=0;
1597 if ( (int)atoi(suslevelstr)>=4)
1598 suslevelstr="3";
1599 /* if ( (int)atoi(suslevelstr)>=4)
1600 pwidth+=stlag;
1601 else
1602 stlag=0; */
1603 }
1604 /* Hack so that sas and sep have pwidth=max(ulim) and nwidth=min(llim) */
1605
1606 if ( strcmp(whichstr, "sas") == 0 || strcmp(whichstr, "sep") == 0 ) {
1607 pwidth = Cycles( ulimstr, frequencies[0], Samplerate() ) ;
1608 nwidth = Cycles( llimstr, frequencies[0], Samplerate() ) ;
1609 if (nwidth > 0) nwidth=0;
1610 }
1611
1612 /* Check ranges of pwidth and nwidth, and quit if invalid */
1613 if (pwidth < 0)
1614 stitch_error("Warning: gensai pwidth_aid should be positive\n");
1615 if (nwidth > 0)
1616 stitch_error("Warning: gensai nwidth_aid should be zero or negative\n");
1617
1618 /* nwidth is given as a -ve value, but is used internally as +ve */
1619 nwidth = -(nwidth);
1620
1621 source = Sai( source, Frameheight(), framestep, pwidth, nwidth,
1622 (int)Samples(decaystr, Samplerate())/Framestep(),
1623 (int)Samplerate(), frequencies,
1624 (double)atof(ttstr),
1625 Samples(cgmstr,Samplerate())/Framestep(),
1626 (int)Freq(utlimstr), (int)Freq(ltlimstr), (int)atoi(suslevelstr),
1627 susthreshstr, swstr, expostr, stlag);
1628
1629 setFramewidth( pwidth+nwidth ) ;
1630 setFramestep( framestep ) ;
1631 setFrames( Frames()/framestep ) ;
1632
1633 return( source ) ;
1634 }
1635
1636 DelayAxis( min, max, label )
1637 double *min, *max ;
1638 char **label ;
1639 {
1640 *min = -Samples( pwidthstr, Samplerate() ) / Samplerate() * 1000. ;
1641 *max = -Samples( nwidthstr, Samplerate() ) / Samplerate() * 1000. ;
1642
1643 *label = "Integration Interval [ms]" ;
1644 }
1645
1646
1647
1648 #if 0 /* where did this come from? */
1649 /* table of default model options */
1650
1651 static char llimdflt[] = "3.5", *llimstr = llimdflt ;
1652 static char ulimdflt[] = "imagedurn", *ulimstr = ulimdflt ;
1653 static char saidflt[] = "0.25", *saistr = saidflt ;
1654 /* static char susldflt[] = "1", *suslevelstr = susldflt ; AJD 13-3-95
1655 static char sustdflt[] = "0", *susthreshstr = sustdflt; */
1656 #endif
1657
1658
1659
1660 /*********** [sas] [sse] stage: "stabilized auditory spectrogram" **********/
1661
1662 /* summarise spectrogram by adding across rows */
1663
1664 static Option sasopts[] = {
1665
1666 ( char * ) 0 } ;
1667
1668 static Source SummaryEntry( source ) /* CG */
1669 Source source ;
1670 {
1671 source = Summary( source, Frameheight(), Scalar( saistr ), frequencies, Samplerate(), llimstr, ulimstr ) ;
1672
1673 setFramewidth( 1 ) ;
1674
1675 return( source ) ;
1676 }
1677
1678 #if defined(DSP32) || defined( THINK_C )
1679 static void swab( in, out, bytes )
1680 char *in, *out ;
1681 int bytes ;
1682 {
1683 register int i ;
1684
1685 for( i=0 ; i<bytes ; i+=2 ) {
1686 out[i+1] = in[i] ;
1687 out[i] = in[i+1] ;
1688 }
1689
1690 return ;
1691 }
1692 #endif
1693
1694 static void swab_callback( state, bytes, buffer, end, input )
1695 Source state ;
1696 ByteCount *bytes ;
1697 DataType *buffer, *end, *input ;
1698 {
1699 extern void swab() ;
1700
1701 swab( (char *) input, (char *) buffer, *bytes ) ;
1702
1703 return ;
1704 }
1705
1706 static Source SwabEntry( source )
1707 Source source ;
1708 {
1709 return ( NewSimpleProcessingSource( swab_callback, source, "model.c byte swapping" ) ) ;
1710 }
1711
1712 struct _test_state { struct _fillable_source parent ; Source source ; unsigned chans ; } ;
1713
1714 static Pointer test_callback( state, bytes, buffer )
1715 struct _test_state *state ;
1716 ByteCount *bytes ;
1717 DataType *buffer ;
1718 {
1719 register DataType input ;
1720 register DataType *optr = buffer ;
1721 register Pointer eptr = (Pointer) buffer + *bytes ;
1722 register int last = *bytes == 0 ;
1723 register int chan ;
1724
1725 while( (Pointer) optr < eptr ) {
1726
1727 input = *PullItems( state->source, 1, DataType ) ;
1728
1729 for( chan=0 ; chan<state->chans ; chan++ )
1730 *optr++ = input ;
1731 }
1732
1733 if( !last )
1734 return ( (Pointer) buffer ) ;
1735 else
1736 return ( DeleteFillableSource( state ) ) ;
1737 }
1738
1739 static Source TestEntry( source )
1740 Source source ;
1741 {
1742 DeclareNew( struct _test_state *, state ) ;
1743
1744 state->source = source ;
1745 state->chans = Frameheight() ;
1746
1747 return( SetFillableSource( state, test_callback, "test model.c" ) ) ;
1748 }
1749
1750 /********************* Option defaults (application specific) ***************
1751 * Each application may have its own set of option defaults.
1752 * These override the generic defaults defined for each option, when the
1753 * options table is constructed, (see constructOptions()).
1754 * Note that options must have their full names. Abbreviations won't do here.
1755 ****************************************************************************/
1756
1757 /* Wave and excitation pattern modules */
1758
1759 #ifndef DSP32
1760 static char zerobotstr[] = "bottom=0" ;
1761 static char excitestr[] = "view=excitation" ;
1762 static char nohiding[] = "hiddenline=off" ;
1763 static char downsample[] = "downsample=10ms" ;
1764 static char turn_on_idt[] = "stages_idt=2" ;
1765 static char mincfdflt[] = "mincf_afb=50" ;
1766 static char maxcfdflt[] = "maxcf_afb=5000" ;
1767 static char chandflt[] = "channels_afb=128" ;
1768 static char lengthdflt[] = "length=32ms" ;
1769 static char greyscalestr[] = "view=greyscale" ;
1770 #endif
1771
1772 char *wavdflts[] = {
1773 #ifndef DSP32
1774 "view=wave",
1775 #endif
1776 (char *)0 } ;
1777
1778 char *stpdflts[] = { /* CG */
1779 #ifndef DSP32
1780 "view=wave",
1781 "filter=off",
1782 #endif
1783 (char *)0 } ;
1784
1785 char *asadflts[] = {
1786 #ifndef DSP32
1787 excitestr,
1788 "top=2500", zerobotstr,
1789 nohiding,
1790 chandflt, /* CG */
1791 "transduction=off", /* CG */
1792 turn_on_idt, /* CG */
1793 downsample, /* CG */
1794 #endif
1795 (char *)0 } ;
1796
1797 char *epndflts[] = {
1798 #ifndef DSP32
1799 excitestr,
1800 "top=1000", zerobotstr, /* CG */
1801 nohiding,
1802 chandflt, /* CG */
1803 turn_on_idt,
1804 downsample,
1805 #endif
1806 (char *)0 } ;
1807
1808 char *sepdflts[] = {
1809 #ifndef DSP32
1810 excitestr,
1811 "top=200", zerobotstr,
1812 nohiding,
1813 chandflt, /* CG */
1814 "ulim_sas=16ms", "llim_sas=-4ms",
1815 #endif
1816 (char *)0 } ;
1817
1818 /* Auditory (ie landscape) modules */
1819
1820 char *bmmdflts[] = {
1821 #ifndef DSP32
1822 lengthdflt,
1823 "top=100", "bottom=-100",
1824 #endif
1825 (char *)0 } ;
1826
1827 char *napdflts[] = {
1828 #ifndef DSP32
1829 lengthdflt,
1830 "top=2000", zerobotstr, /* CG */
1831 chandflt, /* CG */
1832 "stages_idt=2",
1833 "tup_idt=0.133ms",
1834 "downsample=1p",
1835 #endif
1836 (char *)0 } ;
1837
1838
1839 char *saidflts[] = {
1840 #ifndef DSP32
1841 "top=500", zerobotstr, /* CG */
1842 "stages_idt=2",
1843 "tup_idt=0.133ms",
1844 "downsample=1p",
1845 "frstep_epn=1p",
1846 #endif
1847 (char *)0 } ;
1848
1849 char *spldflts[] = {
1850 #ifndef DSP32
1851 "view=spiral",
1852 #ifdef PC
1853 "width_win=300", "height_win=300",
1854 #else
1855 "width_win=500", "height_win=500",
1856 #endif
1857 "box_ps=off", /* MAA 6/9/1995 */
1858 "figurelinewidth_ps=0.25", /* MAA 6/9/1995 */
1859 "top=26", "bottom=25",
1860 "dencf=1", "pen=2",
1861 "nwidth_aid=0ms", "pwidth_aid=35ms",
1862 "stlag=5ms", "stcrit=5", /* AJD */
1863 #endif
1864 (char *)0 } ;
1865
1866 /* Speech (ie greyscale) modules */
1867
1868 char *sgmdflts[] = {
1869 #ifndef DSP32
1870 greyscalestr,
1871 "top=2500", zerobotstr,
1872 chandflt, /* CG */
1873 "transduction=off", /* CG */
1874 turn_on_idt,
1875 downsample,
1876 #endif
1877 (char *)0 } ;
1878
1879 char *cgmdflts[] = {
1880 #ifndef DSP32
1881 greyscalestr,
1882 "top=1000", zerobotstr, /* CG */
1883 chandflt, /* CG */
1884 turn_on_idt,
1885 downsample,
1886 #endif
1887 (char *)0 } ;
1888
1889 char *sasdflts[] = {
1890 #ifndef DSP32
1891 greyscalestr,
1892 "top=300", zerobotstr, /* CG */
1893 chandflt, /* CG */
1894 "stages_idt=off",
1895 "frstep_epn=off",
1896 "downsample=off",
1897 "ulim_sas=16ms", "llim_sas=-4ms",
1898 #endif
1899 (char *)0 } ;
1900
1901
1902
1903 /******************************* stage table ********************************
1904 *
1905 * The "stages" are application names.
1906 * A stage identifier name is the last three chars of the program name.
1907 * (Eg "sai" is the stage identifier for the stabilized auditory image
1908 * application, which is a program called "gensai". This is an alias for
1909 * the "gen" program, provided by one of the set of symbolic links).
1910 * The stages are grouped into "models" (each an array of structs below):
1911 * envelope: calculation of the envelope of the underlying function.
1912 * fine: calculation of the whole ("fine structure") of the function.
1913 * complex
1914 * nonmult
1915 * noncalc
1916 *
1917 * FindStage( which ) - find a place in the stage table for the program goal.
1918 * Take a stage identifier, (contained in the "which" string), and return a ptr
1919 * to the corresponding stage structure, (one line of one of the arrays below).
1920 *
1921 * The returned goal stage is the final processing stage of the sequence of
1922 * stages which make up the program.
1923 * The sequential order of processing is dictated by the stage table.
1924 * The sequence of stages is from the first stage (texually at the bottom of
1925 * each "model" group in the stage table), through each stage back up the table
1926 * to the goal stage.
1927 *
1928 * The stage structure (defined below) is as follows:
1929 * struct _stage {
1930 * char *ident ; Stage identifier name
1931 * Source (*entry)() ; Pointer to function for entry to stage
1932 * Option *options ; Model options for stage (see table.c)
1933 * char **defaults ; Option defaults for stage (see gen.c)
1934 * char *help ; Description of stage
1935 * };
1936 *
1937 * For example, the sai stage (found when gensai is asked for) is:
1938 * "sai", SaiEntry, saiopts, saidflts, "stabilized auditory image",
1939 *
1940 * The stage struct fields are:
1941 *
1942 * *ident
1943 * Stage identifier name used by FindStage() to match a stage struct to the
1944 * application. The stage is found by matching the ident string against those
1945 * stored in the model arrays of stages. The default stage is "wav".
1946 *
1947 * (*entry)()
1948 * The name of the entry-point function for the stage. Most entry-point
1949 * functions are defned in model.c. The entry-point function name is only
1950 * accessed by a call to FindStage() from ModeledSource() in gen.c.
1951 *
1952 * *options
1953 * The options field of a stage is used by the constructOptions() routine
1954 * to include the model options for that stage in the complete options table
1955 * which it constructs. This is composed of the display options, (which are
1956 * common to all applications, and are listed in array displayopts[] in gen.c),
1957 * the model options for the stage, (which are listed in table.c), AND all the
1958 * model options given for each of the stages back to the start stage, (at the
1959 * bottom of the stage table, within a model group of stages).
1960 *
1961 * **defaults
1962 * The defaults field is used by the constructOptions() routine to override the
1963 * defaults defined for the options which have been included in the complete
1964 * options table. The reason for this is so that each application can have its
1965 * own set of option defaults, if necessary. (If defaults are not given
1966 * or the set is not complete, then the original defaults still apply).
1967 * The defaults fields contain option defaults which override the generic
1968 * defaults defined for each option.
1969 * After the complete options table has been constructed, (constructOptions()),
1970 * all options in the table will be:
1971 * a) initialized to their default values (in getnopts()).
1972 * b) re-initialized by any corresponding options in "rc" files.
1973 * c) displayed as a help menu (if asked for).
1974 *
1975 * *help
1976 * This message is printed at the top of the help menu. The help field is only
1977 * accessed by modelHelp(which), called from gen.c, which takes a stage
1978 * identifier and returns the "help" string of the stage struct which has a
1979 * matching ident field, to assign it to "helpstring".
1980 *
1981 *
1982 * Its important to note that the options field refers to model options, and
1983 * these are cumulative over the sequential stages of processing.
1984 * The defaults field refers to the defaults to be used for the goal stage
1985 * only, (ie the application), and these are not cumulative.
1986 * The complete options table (constructed at run time) consists of the display
1987 * options, and the accumulated model options (one group per processing stage).
1988 *
1989 * The NullEntry routine is a dummy which does no processing, and is used to
1990 * introduce aliases into the stage sequence.
1991 *
1992 * Routines which call FindStage(), and access the stage table:
1993 *
1994 * main()
1995 * |
1996 * +----------------------+-----------------+
1997 * | | |
1998 * | | |
1999 * constructOptions() ModeledSource() modelHelp()
2000 * | | |
2001 * | | |
2002 * +----------------------+-----------------+
2003 * |
2004 * FindStage()
2005 *
2006 ****************************************************************************/
2007
2008
2009 #define NO_OPTS (Option *) 0
2010 #define NO_DFLTS (char **) 0
2011
2012 struct _stage *FindStage( which )
2013 char *which ;
2014 {
2015 static struct _stage envelope[] = {
2016 "sse", SummaryEntry, sasopts, sasdflts, "stabilized auditory spectrogram",
2017 "sie", SaiEntry, saiopts, saidflts, "stabilized auditory image",
2018 "sem", NullEntry, NO_OPTS, NO_DFLTS, "spectrogram",
2019 "fed", DownSampleEntry, dwnopts, NO_DFLTS, "downsampled filter envelope",
2020 "fei", IntegralEntry, fbiopts, NO_DFLTS, "integrated filter envelope",
2021 "feh", HardEntry, fbhopts, NO_DFLTS, "hard limited filter envelope",
2022 "fea", AdaptEntry, fbaopts, NO_DFLTS, "adapted filter envelope",
2023 "fet", ThresholdEntry, fbtopts, NO_DFLTS, "thresholded filter envelope",
2024 "fel", LowpassEntry, fblopts, NO_DFLTS, "low-pass filtered filter envelope",
2025 "fes", SaturateEntry, fbsopts, NO_DFLTS, "saturated filter envelope",
2026 "feu", UncompressEntry, fbuopts, NO_DFLTS, "uncompressed filter envelope",
2027 "fec", EnvelopeEntry, fbcopts, NO_DFLTS, "compressed filter envelope",
2028 "fem", NullEntry, fbmopts, NO_DFLTS, "dummy entry to get options through",
2029 "wav", NullEntry, wavopts, wavdflts, "picture of wave",
2030 ( char * ) 0 } ;
2031
2032 static struct _stage fine[] = {
2033 "sep", NullEntry, NO_OPTS, sepdflts, "stabilized excitation pattern",
2034 "sas", SummaryEntry, sasopts, sasdflts, "stabilized auditory spectrogram",
2035 "spl", NullEntry, NO_OPTS, spldflts, "spiral stabilized auditory image",
2036 "sai", SaiEntry, saiopts, saidflts, "stabilized auditory image",
2037 "sgm", NullEntry, NO_OPTS, sgmdflts, "spectrogram",
2038 "cgm", NullEntry, NO_OPTS, cgmdflts, "cochleogram",
2039 "nap", NullEntry, NO_OPTS, napdflts, "neural activity pattern",
2040 "asa", NullEntry, NO_OPTS, asadflts, "auditory spectral analysis",
2041 "epn", NullEntry, NO_OPTS, epndflts, "excitation pattern",
2042 "fbd", DownSampleEntry, dwnopts, NO_DFLTS, "downsampled filter output",
2043 "fbi", IntegralEntry, fbiopts, NO_DFLTS, "integrated filter output",
2044 "fbh", HardEntry, fbhopts, NO_DFLTS, "hard limited filter output",
2045 "fba", AdaptEntry, fbaopts, NO_DFLTS, "adapted transduced filter output",
2046 "fbt", ThresholdEntry, fbtopts, NO_DFLTS, "thresholded filter output",
2047 "fbl", LowpassEntry, fblopts, NO_DFLTS, "low-pass filtered filter output",
2048 "fbs", SaturateEntry, fbsopts, NO_DFLTS, "saturated filter output",
2049 "fbu", UncompressEntry, fbuopts, NO_DFLTS, "uncompressed filter output",
2050 "fbc", LogEntry, fbcopts, NO_DFLTS, "compressed filter output",
2051 "fbr", RectifyEntry, fbropts, NO_DFLTS, "rectified filter output",
2052 "fbm", NullEntry, NO_OPTS, NO_DFLTS, "auditory filter output", /* CG */
2053 "stp", FineEntry, fbmopts, stpdflts, "stapes vibration output", /* CG */
2054 "wav", NullEntry, wavopts, wavdflts, "picture of wave",
2055 ( char * ) 0 } ;
2056
2057 static struct _stage complex[] = {
2058 "fcp", PolarEntry, NO_OPTS, NO_DFLTS, "polar co-ordinate complex output",
2059 "fcr", ComplexEntry, fbmopts, NO_DFLTS, "rectangular co-ordinate complex output",
2060 "wav", NullEntry, wavopts, wavdflts, "picture of wave",
2061 ( char * ) 0 } ;
2062
2063 static struct _stage nonmult[] = {
2064 "bmm", NullEntry, NO_OPTS, bmmdflts, "basilar membrane motion", /* CG */
2065 "stp", FineEntry, fbmopts, stpdflts, "stapes vibration output", /* CG */
2066 "wav", NullEntry, wavopts, wavdflts, "draw wave",
2067 ( char * ) 0 } ;
2068
2069 static struct _stage noncalc[] = {
2070 "tst", TestEntry, NO_OPTS, NO_DFLTS, "Test system",
2071 "wav", NullEntry, wavopts, wavdflts, "draw wave",
2072 ( char * ) 0 } ;
2073
2074 static struct _stage *models[] = { envelope, fine, complex, nonmult, noncalc, ( struct _stage * ) 0 } ;
2075
2076 struct _stage *stage ;
2077 int model ;
2078
2079 /* for each type of model */
2080 for( model=0 ; models[ model ] != ( struct _stage * ) 0 ; model++ )
2081 /* for each stage in the model */
2082 for( stage=models[ model ] ; stage->ident != ( char * ) 0 ; stage++ )
2083 if( strncmp( which, stage->ident, strlen( stage->ident ) ) == 0 ) {
2084
2085 /* kludge to fix bug (see fixchans routine below) */
2086 if ( strcmp( which, "nap" ) == 0 )
2087 fixchans( stage->defaults ) ;
2088
2089 return ( stage ) ;
2090 }
2091
2092 return ( FindStage( "wav" ) ) ;
2093 }
2094
2095 /* Return the "help" string for the given stage identifier */
2096 /* This routine is called once from gen.c:main() */
2097 char *modelHelp( which )
2098 char *which ;
2099 {
2100 return( FindStage( which )->help ) ;
2101 }
2102
2103
2104 /*
2105 This routine is a hack to fix a bug we caused earlier!
2106 We changed the order of entry points in Findstage, so that nap was able
2107 to use the lp filter. But this caused nap to inherit the defaults of all
2108 the other entry points which use that filter. In particular, the number of
2109 channels for nap was changed as a result of this. This hack is designed to
2110 restore the number chans, in the case of gennap only, to their default
2111 value.
2112 */
2113
2114 fixchans( str )
2115 char **str ;
2116 {
2117 while ( *str != (char *)0 ) {
2118 if ( strncmp( *str, "channels_afb", 12 ) == 0 ) {
2119 strcpy( (*str)+13, chansdflt ) ;
2120 /* fprintf(stderr, "fixchans: %s\n", *str ) ; */
2121 break ;
2122 }
2123 *str++ ;
2124 }
2125 }
2126
2127
2128 /*********************** Strings for use in DSP version ********************/
2129
2130 #if defined(DSPHOST) || defined(DSP32)
2131 #if 00
2132 char **shared[] = { &llimstr, &ulimstr, &saistr, &pwidthstr,
2133 &nwidthstr, &ltlimstr, &utlimstr, &ttstr,
2134 &cgmstr, &decaystr, &stepstr, &downsstr,
2135 &stagestr, &upstr, &downstr, &lossstr,
2136 &vlossstr, &igainstr, &hardstr, &adapstr,
2137 &timesstr, &vdrainstr, &propstr, &faststr,
2138 &latstr, &rapidstr, &risestr, &stxstr,
2139 &lstagestr, &lupstr, &ldownstr, &llossstr,
2140 &lvlossstr, &ligainstr, &meddisstr, &satstr,
2141 &logstr, &rectstr, &qualstr, &limitstr,
2142 &interpstr, &minstr, &maxstr, &denstr,
2143 &chansstr, &orderstr, &phasestr, &gainstr,
2144 &audiostr, &floatstr, &samplestr, &bitstr,
2145 &envstr, &whichstr, &framesstr, &framebytesstr,
2146 &framewidthstr, &frameheightstr, &framestepstr,
2147 ( char ** ) 0 } ;
2148 #endif
2149 char **returned[] = { &framesstr, &framebytesstr, &framewidthstr,
2150 &frameheightstr, &framestepstr,
2151 ( char ** ) 0 } ;
2152
2153 #endif
2154
2155
2156 /******* support for DSP32 C ******************/
2157
2158 #ifdef DSP32
2159 void receiveParameters( parameters, psize )
2160 char *parameters ;
2161 short psize ;
2162 {
2163 struct _stage *stage = FindStage( "sas" ), *sptr ;
2164 char *bptr ;
2165 int c ;
2166
2167 for( sptr = stage ; sptr->ident != (char *) 0 ; sptr++ )
2168 ;
2169
2170 sptr-- ;
2171
2172 for( bptr = parameters ; bptr < parameters + psize ; sptr-- )
2173 if( sptr->options != (Option *) 0 )
2174 for( c=0 ; sptr->options[c].name != (char *) 0 ; c++ ) {
2175 *(sptr->options[c].value) = bptr ;
2176 bptr += strlen( bptr ) + 1 ;
2177 }
2178
2179 return ;
2180 }
2181 #endif
2182
2183 #ifdef DSPHOST
2184 #include "utils.h"
2185 #define DSP_BIN_VAR "DSPBIN"
2186 #define DEFAULT_DSP_BIN "c:\\bin\\dspmain"
2187 extern char *getenv() ;
2188
2189 void sendParameters( which )
2190 char *which ;
2191 {
2192 register struct _stage *stage = FindStage( which ), *sptr ;
2193 unsigned c, bytes = 0 ;
2194 char *buffer, *bptr ;
2195 long paddr, baddr ;
2196
2197 for( sptr = stage ; sptr->ident != (char *) 0 ; sptr++ )
2198 if( sptr->options != (Option *) 0 )
2199 for( c=0 ; sptr->options[c].name != (char *) 0 ; c++ )
2200 bytes += strlen( *(sptr->options[c].value) ) + 1 ;
2201
2202 sptr-- ;
2203
2204 buffer = Allocate( bytes, "argument array model.c" ) ;
2205
2206 for( bptr = buffer ; sptr >= stage ; sptr-- )
2207 if( sptr->options != (Option *) 0 )
2208 for( c=0 ; sptr->options[c].name != (char *) 0 ; c++ ) {
2209 (void) strcpy( bptr, *(sptr->options[c].value) ) ;
2210 bptr += strlen( bptr ) + 1 ;
2211 }
2212
2213
2214 paddr = find_label_name( "psize" ) ;
2215
2216 dsp_dl_int( paddr, (int) ( bptr - buffer ) ) ;
2217
2218 baddr = find_label_name( "params" ) ;
2219
2220 while( dsp_up_long( baddr ) == 0 )
2221 ;
2222
2223 dsp_dl_bytes( deref( baddr ), (long) ( bptr - buffer ), buffer ) ;
2224
2225 dsp_dl_int( paddr, 0 ) ;
2226
2227 return ;
2228 }
2229
2230
2231 struct _dsp_state { unsigned long needed_addr, output_addr, errno_addr ; } ;
2232
2233 static void dsp_callback( state, bytes, buffer )
2234 struct _dsp_state *state ;
2235 ByteCount bytes ;
2236 Pointer buffer ;
2237 {
2238 char errbuff[200] ;
2239
2240 /* tell dsp how much you want */
2241
2242 dsp_dl_int( state->needed_addr, bytes ) ;
2243
2244 /* wait for it to provide it */
2245
2246 while( dsp_up_int( state->needed_addr ) != 0 )
2247 if( dsp_up_int( state->errno_addr ) != 0 ) {
2248 /*
2249 if( dispw != ( WindowObject ) 0 ) Close( dispw ) ;
2250 */
2251 dsp_up_bytes( find_label_name( "errstr" ), (long) sizeof ( errbuff ), errbuff ) ;
2252 printf( "freemem %ld stackmax %lx\n",
2253 dsp_up_long( find_label_name( "freemem" ) ),
2254 dsp_up_long( find_label_name( "stackmax" ) ) ) ;
2255 stitch_error( errbuff, dsp_up_int( find_label_name( "errno" ) ) ) ;
2256 }
2257
2258 /* upload it into PC buffer */
2259
2260 dsp_up_bytes( deref( state->output_addr ), (long) bytes, buffer ) ;
2261
2262 return ;
2263 }
2264
2265 Source DspSource( source )
2266 Source source ;
2267 {
2268 DeclareNew( struct _dsp_state *, state ) ;
2269 unsigned long addr ;
2270 char errbuff[200] ;
2271 char ***param ;
2272 char *binary_path = getenv( DSP_BIN_VAR ) ;
2273
2274 if( binary_path == ( char * ) 0 )
2275 binary_path = DEFAULT_DSP_BIN ;
2276
2277 /* load dsp */
2278
2279 (void) fprintf( stderr, "Downloading %s to DSP32 at i/o addres 0x%x\n", binary_path, default_addr() ) ;
2280
2281 if( dsp_dl_exec( binary_path ) == 0 )
2282 stitch_error( "\nDSP load failed\n" ) ;
2283
2284 /* start dsp */
2285
2286 dsp_run() ;
2287
2288 /* send parameters down to model */
2289
2290 sendParameters( whichstr ) ;
2291
2292 /* send down input if required */
2293
2294 if( whichstr[0] != 'i' ) {
2295
2296 addr = find_label_name( "input" ) ;
2297
2298 while( dsp_up_long( addr ) == 0 )
2299 ;
2300
2301 (void) fprintf( stderr, "Downloading input file of %ld points to dsp addres 0x%lx\n", Frames(), deref( addr ) ) ;
2302
2303 dsp_dl_array( deref( addr ), Frames(), PullInts( source, Frames() ) ) ;
2304 }
2305
2306 /* wait for model setup */
2307
2308 state->needed_addr = find_label_name( "needed" ) ;
2309 state->output_addr = find_label_name( "output" ) ;
2310 state->errno_addr = find_label_name( "errno" ) ;
2311
2312 addr = find_label_name( "source" ) ;
2313
2314 while( dsp_up_long( addr ) == 0l && dsp_up_int( state->errno_addr ) == 0 )
2315 (void) fprintf( stderr, "Waiting for dsp (status:%d)\r", dsp_up_long( addr ) ) ;
2316
2317 if( dsp_up_int( state->errno_addr ) != 0 ) {
2318 dsp_up_bytes( find_label_name( "errstr" ), (long) sizeof ( errbuff ), errbuff ) ;
2319 (void) fprintf( stderr, "dsp error: %s\n", errbuff ) ;
2320 stitch_error( "so there" ) ;
2321 }
2322
2323 (void) fprintf( stderr, "DSP setup (source=0x%lx)\n", dsp_up_long( addr ) ) ;
2324
2325 addr = find_label_name( "returned" ) ;
2326
2327 for( param=returned ; *param != ( char ** ) 0 ; param++ ) {
2328
2329 dsp_up_bytes( deref( deref( addr ) ), RETURN_SIZE, **param ) ;
2330 addr += 4 ;
2331 }
2332 #if 0
2333 fprintf( stderr, "Frames %ld - %d %d %d\n\nType Return\n", Frames(), Frameheight(), Framewidth(), Framebytes() ) ;
2334 getchar() ;
2335 #endif
2336 return ( stdAutoSource( ( Pointer ) state, dsp_callback ) ) ;
2337 }
2338
2339 #endif
2340
2341 /***************************************************************************
2342 * ModeledSource()
2343 * Called from main() in gen.c to initialize a chain of objects which will
2344 * ultimately execute the program, (see also SinkSource() in gen.c:main).
2345 *
2346 * The routine ModeledSource() first uses Findstage() to find the appropriate
2347 * place in the stage table, called for by the program, (and indicated by
2348 * "whichstr", the last three chars of the program's name).
2349 * Then it finds the end of the table, and works back up to the stage called
2350 * for by the program.
2351 * At each stage, call the corresponding entry-point function, (provided it's
2352 * not a null pointer), to create and initialize a source object.
2353 * (Each stage in the table is a process on the way to the program as a whole.
2354 * The order of the stage table sets the order of processing).
2355 *
2356 * The "check" argument is used when the "useprevious" option is on,
2357 * (see main() and checkForFile() in gen.c), otherwise it will be a null ptr.
2358 ***************************************************************************/
2359
2360 Source ModeledSource( source, check )
2361 Source source ;
2362 Source (*check)() ;
2363 {
2364 /* Find the place in the stage table called for by the program */
2365 register struct _stage *sptr, *stage = FindStage( whichstr ) ;
2366 Source stmp ;
2367
2368 #if !defined( DSP32 ) && !defined( THINK_C )
2369 if( OptionInt( swapstr ) != 0 )
2370 source = SwabEntry( source ) ;
2371 #endif
2372
2373 #ifdef DSPHOST
2374 if( getenv( "DSP32" ) != ( char * ) 0 )
2375 return ( DspSource( source ) ) ;
2376 else
2377 (void) fprintf( stderr, "Not using DSP card\n" ) ;
2378 #endif
2379
2380 if( stage->entry == ( Source ( * )() ) 0 )
2381 return ( source ) ;
2382 #if 00
2383 /* Set frameheight (channels) and centre-frequencies array */
2384 updateFrequencies() ;
2385 #endif
2386
2387 #ifdef FLOAT
2388 source = ShortFloatSource( source ) ;
2389 #endif
2390
2391 /* Find the end of the stage table */
2392 for( sptr = stage ; sptr->ident != ( char * ) 0 ; sptr++ )
2393 ;
2394
2395 /* Work back up the stage table to the stage called for by the program */
2396 /* At each stage, call the entry-point function (if it's not null) */
2397 while( sptr-- > stage ) {
2398
2399 if( sptr->entry != (Source ( * )()) 0 )
2400 source = sptr->entry( source ) ;
2401
2402 if( check != ( Source ( * )() ) 0 ) {
2403 stmp = check( sptr->ident ) ;
2404 if( _SPTR( stmp ) != (struct _source *) 0 ) {
2405
2406 #ifdef FLOAT
2407 source = ShortFloatSource( stmp ) ;
2408 #else
2409 source = stmp ;
2410 #endif
2411 /* Set frameheight (channels) and centre-frequencies array */
2412 updateFrequencies() ;
2413 }
2414 }
2415 }
2416
2417 #ifdef FLOAT
2418 source = FloatShortSource( source ) ;
2419 #endif
2420
2421 setFrames( Frames() ) ;
2422
2423 return ( source ) ;
2424 }
2425
2426