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