annotate wdf/wdf_ear.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 THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
tomwalters@0 17 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE
tomwalters@0 18 A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
tomwalters@0 19 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
tomwalters@0 20 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
tomwalters@0 21 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
tomwalters@0 22 */
tomwalters@0 23
tomwalters@0 24 /*
tomwalters@0 25 Acknowledgment:
tomwalters@0 26 ==============
tomwalters@0 27
tomwalters@0 28 The source code provided in this file was originally developed by
tomwalters@0 29 Christian Giguere as part of a Ph.D degree at the Department of
tomwalters@0 30 Engineering of the University of Cambridge from April 1990 to
tomwalters@0 31 November 1993. The code was subsequently adapted under a grant
tomwalters@0 32 from the Hearing Research Trust for full compatibility with
tomwalters@0 33 AIM Release 6.15.
tomwalters@0 34
tomwalters@0 35 Christian Giguere 25/03/94
tomwalters@0 36
tomwalters@0 37 */
tomwalters@0 38
tomwalters@0 39 /*
tomwalters@0 40 ===========================================================
tomwalters@0 41 wdf_ear.c
tomwalters@0 42 ===========================================================
tomwalters@0 43
tomwalters@0 44 Wave digital filter (WDF) implementation of the outer and
tomwalters@0 45 middle ear (EAR) electroacoustic networks.
tomwalters@0 46
tomwalters@0 47 Author : Christian Giguere
tomwalters@0 48 First written : 01st June, 1991
tomwalters@0 49 Last edited : 18th February, 1994
tomwalters@0 50
tomwalters@0 51 References:
tomwalters@0 52 (1) C.Giguere and P.C.Woodland (1992). Technical Report
tomwalters@0 53 CUED/F-INFENG/TR.93, University of Cambridge.
tomwalters@0 54 (2) C.Giguere and P.C.Woodland (1994). JASA 95(1): 331-342.
tomwalters@0 55 (3) M.E.Lutman and A.M.Martin (1979). J.Sound.Vib. 64(1): 133-157
tomwalters@0 56 (4) A.Fettweis (1986). Proceedings IEEE 74(2): 270-327.
tomwalters@0 57
tomwalters@0 58 Note: Ref (1) describes an implementation where the outer
tomwalters@0 59 ear and middle ear module is _UNCOUPLED_ to the cochlea.
tomwalters@0 60 In this case, the middle ear network is that of Lutman
tomwalters@0 61 and Martin (1979) unmodified.
tomwalters@0 62
tomwalters@0 63 Ref (2) describes an implementation where the outer
tomwalters@0 64 ear and middle ear module is _COUPLED_ to the cochlea.
tomwalters@0 65 In this case, the middle ear network is a modified
tomwalters@0 66 version of Lutman and Martin (1979) network (See Fig.2)
tomwalters@0 67 ===========================================================
tomwalters@0 68 */
tomwalters@0 69
tomwalters@0 70
tomwalters@0 71 /***** includes *****/
tomwalters@0 72
tomwalters@0 73 #include <math.h>
tomwalters@0 74 #include <stdio.h>
tomwalters@0 75 #include "stitch.h"
tomwalters@0 76 #include "calc.h"
tomwalters@0 77 #include "calc_tl.h"
tomwalters@0 78 #include "wdf_ear.h"
tomwalters@0 79
tomwalters@0 80 /***** defines *****/
tomwalters@0 81
tomwalters@0 82 #define N_OF_FREEFIELD_STATES ( 12 )
tomwalters@0 83 #define N_OF_EARTUBE_STATES ( 16 ) /* per segment */
tomwalters@0 84 #define N_OF_EARMIDDLE_STATES ( 48 )
tomwalters@0 85
tomwalters@0 86 #if 0
tomwalters@0 87 #define _DEBUG_
tomwalters@0 88 #define _OVERFLOW_
tomwalters@0 89 #endif
tomwalters@0 90
tomwalters@0 91 #if 0
tomwalters@0 92 #define _IMPULSE_ /* bypasses input wave with a delta impulse */
tomwalters@0 93 #endif
tomwalters@0 94
tomwalters@0 95 #if 0
tomwalters@0 96 #define _EARDRUM_ /* outputs eardrum pressure instead of stapes velocity */
tomwalters@0 97 #endif
tomwalters@0 98
tomwalters@0 99 /* Middle ear circuit elements in CGS units (From Lutman and Martin (1979) */
tomwalters@0 100
tomwalters@0 101 #define La ( 14.0e-03 ) /* Middle ear cavities */
tomwalters@0 102 #define Cp ( 5.1e-06 )
tomwalters@0 103 #define Ra ( 10.0 )
tomwalters@0 104 #define Rm ( 390.0 )
tomwalters@0 105 #define Ct ( 0.35e-06 )
tomwalters@0 106 #define Rd1 ( 200.0 ) /* Eardrum losses */
tomwalters@0 107 #define Cd1 ( 0.8e-06 )
tomwalters@0 108 #define Cd2 ( 0.4e-06 )
tomwalters@0 109 #define Rd2 ( 220.0 )
tomwalters@0 110 #define Ld ( 15.0e-03 )
tomwalters@0 111 #define Rd3 ( 5900.0 )
tomwalters@0 112 #define Cd3 ( 0.2e-06 )
tomwalters@0 113 #define Lo ( 40.0e-03 ) /* Eardrum, mallus, incus */
tomwalters@0 114 #define Co ( 1.4e-06 )
tomwalters@0 115 #define Ro ( 70.0 )
tomwalters@0 116 #define Cs ( 0.25e-06 ) /* Incudo-stapedial joint */
tomwalters@0 117 #define Rs ( 3000.0 )
tomwalters@0 118 #define Lc ( 45.0e-03 ) /* Stapes and cochlea */
tomwalters@0 119 #define Cc ( 0.6e-06 )
tomwalters@0 120 #define Rc ( 550.0 )
tomwalters@0 121
tomwalters@0 122 /* Additional middle ear circuit elements in CGS units (From Giguere and Woodland (1994) */
tomwalters@0 123
tomwalters@0 124 #define Ral ( 100.0 ) /* annular ligaments */
tomwalters@0 125 #define Kst_max ( 1./0.1e-06 ) /* max. Stapedius stiffness */
tomwalters@0 126 #define Kst_min_ratio ( 0.0001 ) /* min value of Kst_ratio */
tomwalters@0 127
tomwalters@0 128
tomwalters@0 129 /***** external variables *****/
tomwalters@0 130
tomwalters@0 131 double Kst_ratio = Kst_min_ratio ; /* initial fraction of Kst_max */
tomwalters@0 132 /* updated by feedback module */
tomwalters@0 133 static double rn_1 ;
tomwalters@0 134
tomwalters@0 135
tomwalters@0 136 /***** functions *****/
tomwalters@0 137
tomwalters@0 138 /******************************* WDF set-up functions ************************************
tomwalters@0 139 * name: function:
tomwalters@0 140 *
tomwalters@0 141 * FreefieldWDF() Set-up function for the WDF implementation of the external ear network
tomwalters@0 142 * (Giguere and Woodland, 1994, Figs. 1 and 8). It generates the multiplier
tomwalters@0 143 * coefficients and initializes the states of the filter.
tomwalters@0 144 *
tomwalters@0 145 * In the case of the _UNCOUPLED_ ear version, it is called by the
tomwalters@0 146 * function ``Ear()'' in file ``ear.c''.
tomwalters@0 147 * In the case of the _COUPLED_ ear version, it is called by the
tomwalters@0 148 * function ``TLF_GenBank()'' in file ``bank_tl.c''.
tomwalters@0 149 *
tomwalters@0 150 * It returns a pointer to a structure containing all the relevant
tomwalters@0 151 * information for the computation of the whole filter.
tomwalters@0 152 *
tomwalters@0 153 * EartubeWDF() Set-up function for the WDF implementation of the concha and auditory
tomwalters@0 154 * canal transmission lines (Giguere and Woodland, 1994, Figs. 1 and 8).
tomwalters@0 155 * It generates the multiplier coefficients and initializes the states
tomwalters@0 156 * of the filter.
tomwalters@0 157 *
tomwalters@0 158 * In the case of the _UNCOUPLED_ ear version, it is called by the
tomwalters@0 159 * function ``Ear()'' in file ``ear.c'' once for each segment of the
tomwalters@0 160 * transmission lines starting from the outermost segment.
tomwalters@0 161 * In the case of the _COUPLED_ ear version, it is called by the
tomwalters@0 162 * function ``TLF_GenBank()'' in file ``bank_tl.c'' once for each segment
tomwalters@0 163 * of the transmission lines starting from the outermost segment.
tomwalters@0 164 *
tomwalters@0 165 * It returns a pointer to a structure containing all the relevant
tomwalters@0 166 * information for the current filter segment.
tomwalters@0 167 *
tomwalters@0 168 * EarmiddleWDF() Set-up function for the WDF implementation of the middle ear network
tomwalters@0 169 * (Giguere and Woodland, 1994, Figs. 2 and 9). It generates the multiplier
tomwalters@0 170 * coefficients and initializes the states of the filter.
tomwalters@0 171 *
tomwalters@0 172 * In the case of the _UNCOUPLED_ ear version, it is called by the
tomwalters@0 173 * function ``Ear()'' in file ``ear.c''.
tomwalters@0 174 * In the case of the _COUPLED_ ear version, it is called by the
tomwalters@0 175 * function ``TLF_GenBank()'' in file ``bank_tl.c''.
tomwalters@0 176 *
tomwalters@0 177 * It returns a pointer to a structure containing all the relevant
tomwalters@0 178 * information for the computation of the whole filter.
tomwalters@0 179 ******************************************************************************************/
tomwalters@0 180
tomwalters@0 181 /************************** FreefieldWDF() *****************************/
tomwalters@0 182
tomwalters@0 183 WaveWDFstate *FreefieldWDF( samplerate, rho, velocity, diffraction_radius, radiation_radius )
tomwalters@0 184 double samplerate ;
tomwalters@0 185 double rho, velocity ;
tomwalters@0 186 double diffraction_radius, radiation_radius ;
tomwalters@0 187 {
tomwalters@0 188 DeclareNew( WaveWDFstate *, filter_state ) ;
tomwalters@0 189 double fs2 ;
tomwalters@0 190 double r1, r2, r3, g1, g2, g3 ;
tomwalters@0 191 double zh, zr ;
tomwalters@0 192 double Lh, Rh, Lr, Rr ;
tomwalters@0 193
tomwalters@0 194 /*** electrical circuit elements (CGS) ***/
tomwalters@0 195 Rh = rho * velocity / ( Pi * diffraction_radius * diffraction_radius ) ;
tomwalters@0 196 Lh = 0.5 * rho / ( Pi * diffraction_radius ) ;
tomwalters@0 197 Rr = rho * velocity / ( Pi * radiation_radius * radiation_radius ) ;
tomwalters@0 198 Lr = 0.7 * rho / ( Pi * radiation_radius ) ;
tomwalters@0 199
tomwalters@0 200 /*** sampling frequency ***/
tomwalters@0 201 fs2 = samplerate * 2. ;
tomwalters@0 202
tomwalters@0 203 /*** WDF-port resistances and multiplier coefficients ***/
tomwalters@0 204
tomwalters@0 205 /* Adaptor 0 */
tomwalters@0 206 g1 = 1. / ( fs2 * Lh ) ; /* (1 / Zlh) */
tomwalters@0 207 g2 = 1. / Rh ; /* (1 / Zrh) */
tomwalters@0 208 g3 = g1 + g2 ;
tomwalters@0 209 zh = 1. / g3 ;
tomwalters@0 210 filter_state->gamma01 = g1 / g3 ;
tomwalters@0 211
tomwalters@0 212 /* Adaptor 2 */
tomwalters@0 213 g1 = 1. / ( fs2 * Lr ) ; /* (1 / Zlr) */
tomwalters@0 214 g2 = 1. / Rr ; /* (1 / Zrr) */
tomwalters@0 215 g3 = g1 + g2 ;
tomwalters@0 216 zr = 1. / g3 ;
tomwalters@0 217 filter_state->gamma21 = g1 / g3 ;
tomwalters@0 218
tomwalters@0 219 /* Adaptor 1 */
tomwalters@0 220 r1 = zh ;
tomwalters@0 221 r2 = zr ;
tomwalters@0 222 r3 = rn_1 = r1 + r2 ;
tomwalters@0 223 filter_state->gamma11 = r1 / r3 ;
tomwalters@0 224
tomwalters@0 225 #ifdef _DEBUG_
tomwalters@0 226 fprintf( stderr, "Rh=%e Lh=%e Rr=%e Lr=%e\n", Rh, Lh, Rr, Lr ) ;
tomwalters@0 227 fprintf( stderr, "gamma01=%f\n", filter_state->gamma01 ) ;
tomwalters@0 228 fprintf( stderr, "gamma11=%f\n", filter_state->gamma11 ) ;
tomwalters@0 229 fprintf( stderr, "gamma21=%f\n", filter_state->gamma21 ) ;
tomwalters@0 230 #endif
tomwalters@0 231
tomwalters@0 232 /*** initialise filter states ***/
tomwalters@0 233 filter_state->Nstates = N_OF_FREEFIELD_STATES ;
tomwalters@0 234 filter_state->states = ( char * ) NewZeroedArray( StateType, filter_state->Nstates,
tomwalters@0 235 "wdf_ear.c for freefield states\n" ) ;
tomwalters@0 236
tomwalters@0 237 /*** return ***/
tomwalters@0 238 return( filter_state ) ;
tomwalters@0 239 }
tomwalters@0 240
tomwalters@0 241 /************************** EartubeWDF() *****************************/
tomwalters@0 242
tomwalters@0 243 EartubeWDFstate *EartubeWDF( samplerate, rho, velocity, diam, seglength, attn )
tomwalters@0 244 double samplerate ;
tomwalters@0 245 double rho, velocity ;
tomwalters@0 246 double diam, seglength ;
tomwalters@0 247 double attn ;
tomwalters@0 248 {
tomwalters@0 249 DeclareNew( EartubeWDFstate *, filter_state ) ;
tomwalters@0 250 double an, d, c, k, alpha, fs2 ;
tomwalters@0 251 double Ln, Cn, Gn, Zn ;
tomwalters@0 252 double r1, r2, r3, g1, g2, g3, r33, g43, g53 ;
tomwalters@0 253
tomwalters@0 254 /*** acoustic tube parameters for current segment ***/
tomwalters@0 255 an = Pi * diam * diam / 4. ; /* cross-sectional area of tube (cm2) */
tomwalters@0 256 d = seglength; /* length of tube (cm) */
tomwalters@0 257 c = velocity ; /* sound velocity in air (cm/s) */
tomwalters@0 258 alpha = attn ; /* attenuation constant of travelling waves (1/cm) */
tomwalters@0 259
tomwalters@0 260 /*** sampling frequency ***/
tomwalters@0 261 fs2 = samplerate * 2. ;
tomwalters@0 262
tomwalters@0 263 /*** electrical circuit elements (CGS units) for current segment ***/
tomwalters@0 264 Ln = ( rho * d ) / an ; /* series inductor (either Lch or Lcl) */
tomwalters@0 265 Cn = ( an * d ) / ( rho * c * c ) ; /* shunt capacitor (either Cch or Ccl) */
tomwalters@0 266 Zn = sqrt( Ln / Cn ) ; /* characteristic impedance ( either Zch or Zcl) */
tomwalters@0 267 Gn = 2. / Zn * alpha * d ; /* shunt conductance (either Gch or Gcl) */
tomwalters@0 268
tomwalters@0 269 /*** WDF multiplier coefficients for current tube segment ***/
tomwalters@0 270
tomwalters@0 271 /* Adaptor 3 */
tomwalters@0 272 r1 = fs2 * Ln / 2. ; /* 0.5 Zl */
tomwalters@0 273 r2 = rn_1 ;
tomwalters@0 274 r3 = r33 = r1 + r2 ;
tomwalters@0 275 filter_state->gamma31 = r1 / r3 ;
tomwalters@0 276
tomwalters@0 277 /* Adaptor 5 */
tomwalters@0 278 g1 = Gn ; /* (1 / Zg ) */
tomwalters@0 279 g2 = fs2 * Cn ; /* (1 / Zc ) */
tomwalters@0 280 g3 = g53 = g1 + g2 ;
tomwalters@0 281 filter_state->gamma51 = g1 / g3 ;
tomwalters@0 282
tomwalters@0 283 /* Adaptor 4 */
tomwalters@0 284 g1 = 1 / r33 ;
tomwalters@0 285 g2 = g53 ;
tomwalters@0 286 g3 = g43 = g1 + g2 ;
tomwalters@0 287 filter_state->gamma41 = g1 / g3 ;
tomwalters@0 288
tomwalters@0 289 /* Adaptor 6 */
tomwalters@0 290 r1 = 1 / g43 ;
tomwalters@0 291 r2 = fs2 * Ln / 2. ; /* 0.5 Zl */
tomwalters@0 292 r3 = rn_1 = r1 + r2 ;
tomwalters@0 293 filter_state->gamma61 = r1 / r3 ;
tomwalters@0 294
tomwalters@0 295 #ifdef _DEBUG_
tomwalters@0 296 fprintf( stderr, "gamma31=%f ", filter_state->gamma31 ) ;
tomwalters@0 297 fprintf( stderr, "gamma41=%f ", filter_state->gamma41 ) ;
tomwalters@0 298 fprintf( stderr, "gamma51=%f ", filter_state->gamma51 ) ;
tomwalters@0 299 fprintf( stderr, "gamma61=%f\n", filter_state->gamma61 ) ;
tomwalters@0 300 #endif
tomwalters@0 301
tomwalters@0 302 /*** initialise filter states ***/
tomwalters@0 303 filter_state->Nstates = N_OF_EARTUBE_STATES ;
tomwalters@0 304 filter_state->states = ( char * ) NewZeroedArray( StateType, filter_state->Nstates,
tomwalters@0 305 "wdf_ear.c for earcanal states\n" ) ;
tomwalters@0 306
tomwalters@0 307 /*** return ***/
tomwalters@0 308 return( filter_state ) ;
tomwalters@0 309 }
tomwalters@0 310
tomwalters@0 311
tomwalters@0 312 /********************** EarmiddleWDF() ***************************/
tomwalters@0 313
tomwalters@0 314 EarmiddleWDFstate *EarmiddleWDF( samplerate, zov, output_scale, ratio )
tomwalters@0 315 double samplerate, zov, output_scale, ratio ;
tomwalters@0 316 {
tomwalters@0 317 DeclareNew( EarmiddleWDFstate *, filter_state ) ;
tomwalters@0 318 double fs2 ;
tomwalters@0 319 double r1, r2, r3, r4, g1, g2, g3, g4 ;
tomwalters@0 320 double r73, r84, r94, r103, r114, r123, r133, r143, r153 ;
tomwalters@0 321 double r163, r174, r183, r193, r204, r214 ;
tomwalters@0 322 void update_earmiddle_init(), update_earmiddle() ;
tomwalters@0 323
tomwalters@0 324 /*** sampling frequency ***/
tomwalters@0 325 fs2 = samplerate * 2. ;
tomwalters@0 326
tomwalters@0 327 /*** WDF-port resistances and multiplier coefficients ***/
tomwalters@0 328
tomwalters@0 329 /* Adaptor 9 */
tomwalters@0 330 r1 = 1. / ( fs2 * Cp ) ; /* Zcp */
tomwalters@0 331 r2 = Ra ; /* Zra */
tomwalters@0 332 r3 = fs2 * La ; /* Zla */
tomwalters@0 333 r4 = r94 = r1 + r2 + r3 ;
tomwalters@0 334 filter_state->gamma91 = r1 / r4 ;
tomwalters@0 335 filter_state->gamma92 = r2 / r4 ;
tomwalters@0 336
tomwalters@0 337 /* Adaptor 8 */
tomwalters@0 338 g1 = 1. / r94 ;
tomwalters@0 339 g2 = 1. / Rm ; /* (1 / Zrm) */
tomwalters@0 340 g3 = fs2 * Ct ; /* (1 / Zct) */
tomwalters@0 341 g4 = g1 + g2 + g3 ;
tomwalters@0 342 r84 = 1. /g4 ;
tomwalters@0 343 filter_state->gamma81 = g1 / g4 ;
tomwalters@0 344 filter_state->gamma82 = g2 / g4 ;
tomwalters@0 345
tomwalters@0 346 /* Adaptor 7 */
tomwalters@0 347 r1 = r84 ;
tomwalters@0 348 r2 = rn_1 ;
tomwalters@0 349 r3 = r73 = r1 + r2 ;
tomwalters@0 350 filter_state->gamma71 = r1 / r3 ;
tomwalters@0 351
tomwalters@0 352 /* Adaptor 13 */
tomwalters@0 353 r1 = 1. / ( fs2 * Cd2 ) ; /* Zcd2 */
tomwalters@0 354 r2 = Rd2 ; /* Zrd2 */
tomwalters@0 355 r3 = r133 = r1 + r2 ;
tomwalters@0 356 filter_state->gamma131 = r1 / r3 ;
tomwalters@0 357
tomwalters@0 358 /* Adaptor 12 */
tomwalters@0 359 g1 = 1. / ( fs2 * Ld ) ; /* (1 / Zld) */
tomwalters@0 360 g2 = 1. / r133 ;
tomwalters@0 361 g3 = g1 + g2 ;
tomwalters@0 362 r123 = 1. / g3 ;
tomwalters@0 363 filter_state->gamma121 = g1 / g3 ;
tomwalters@0 364
tomwalters@0 365 /* Adaptor 14 */
tomwalters@0 366 g1 = 1. / Rd3 ; /* (1 / Zrd3) */
tomwalters@0 367 g2 = fs2 * Cd3 ; /* (1 / Zcd3) */
tomwalters@0 368 g3 = g1 + g2 ;
tomwalters@0 369 r143 = 1. / g3 ;
tomwalters@0 370 filter_state->gamma141 = g1 / g3 ;
tomwalters@0 371
tomwalters@0 372 /* Adaptor 15 */
tomwalters@0 373 r1 = 1. / ( fs2 * Cd1 ) ; /* Zcd1 */
tomwalters@0 374 r2 = Rd1 ; /* Zrd1 */
tomwalters@0 375 r3 = r153 = r1 + r2 ;
tomwalters@0 376 filter_state->gamma151 = r1 / r3 ;
tomwalters@0 377
tomwalters@0 378 /* Adaptor 11 */
tomwalters@0 379 r1 = r143 ;
tomwalters@0 380 r2 = r123 ;
tomwalters@0 381 r3 = r153 ;
tomwalters@0 382 r4 = r114 = r1 + r2 + r3 ;
tomwalters@0 383 filter_state->gamma111 = r1 / r4 ;
tomwalters@0 384 filter_state->gamma112 = r2 / r4 ;
tomwalters@0 385
tomwalters@0 386 /* Adaptor 10 */
tomwalters@0 387 g1 = 1. / r114 ;
tomwalters@0 388 g2 = 1. / r73 ;
tomwalters@0 389 g3 = g1 + g2 ;
tomwalters@0 390 r103 = 1. /g3 ;
tomwalters@0 391 filter_state->gamma101 = g1 / g3 ;
tomwalters@0 392
tomwalters@0 393 /* Adaptor 17 */
tomwalters@0 394 r1 = 1. / ( fs2 * Co ) ; /* Zco */
tomwalters@0 395 r2 = Ro ; /* Zro */
tomwalters@0 396 r3 = fs2 * Lo ; /* Zlo */
tomwalters@0 397 r4 = r174 = r1 + r2 + r3 ;
tomwalters@0 398 filter_state->gamma171 = r1 / r4 ;
tomwalters@0 399 filter_state->gamma172 = r2 / r4 ;
tomwalters@0 400
tomwalters@0 401 /* Adaptor 16 */
tomwalters@0 402 r1 = r103 ;
tomwalters@0 403 r2 = r174 ;
tomwalters@0 404 r3 = r163 = r1 + r2 ;
tomwalters@0 405 filter_state->gamma161 = r1 / r3 ;
tomwalters@0 406
tomwalters@0 407 /* Adaptor 19 */
tomwalters@0 408 r1 = 1. / ( fs2 * Cs ) ; /* Zcs */
tomwalters@0 409 r2 = Rs ; /* Zrs */
tomwalters@0 410 r3 = r193 = r1 + r2 ;
tomwalters@0 411 filter_state->gamma191 = r1 / r3 ;
tomwalters@0 412
tomwalters@0 413 /* Adaptor 18 */
tomwalters@0 414 g1 = 1. / r163 ;
tomwalters@0 415 g2 = 1. / r193 ;
tomwalters@0 416 g3 = g1 + g2 ;
tomwalters@0 417 r183 = 1. / g3 ;
tomwalters@0 418 filter_state->gamma181 = g1 / g3 ;
tomwalters@0 419
tomwalters@0 420 /* Adaptor 20 */
tomwalters@0 421 #ifdef _DEBUG_
tomwalters@0 422 fprintf( stderr, "Zov=%e\n", zov ) ;
tomwalters@0 423 #endif
tomwalters@0 424 if( zov != 0. ) { /* coupled version ? */
tomwalters@0 425 r1 = Ral ; /* Zral */
tomwalters@0 426 r2 = zov / ( ratio * ratio ) ; /* Zov / (r*r) */
tomwalters@0 427 }
tomwalters@0 428 else { /* uncoupled version */
tomwalters@0 429 r1 = 0.0 ;
tomwalters@0 430 r2 = Rc ; /* Zrc */
tomwalters@0 431 }
tomwalters@0 432 r3 = r183 ;
tomwalters@0 433 r4 = r204 = r1 + r2 +r3 ;
tomwalters@0 434 filter_state->gamma201 = r1 / r4 ;
tomwalters@0 435 filter_state->gamma202 = r2 / r4 ;
tomwalters@0 436 filter_state->ratio = ratio ;
tomwalters@0 437
tomwalters@0 438 /* Adaptor 21 */
tomwalters@0 439 r1 = 1. / ( fs2 * Cc ) ; /* Zcc */
tomwalters@0 440 r2 = r204 ;
tomwalters@0 441 if( zov != 0. ) /* coupled version ? */
tomwalters@0 442 r3 = 0.0 ;
tomwalters@0 443 else /* uncoupled version */
tomwalters@0 444 r3 = fs2 * Lc ; /* Zlc */
tomwalters@0 445 r4 = r214 = r1 + r2 + r3 ;
tomwalters@0 446 filter_state->gamma211 = r1 / r4 ;
tomwalters@0 447 filter_state->gamma212 = r2 / r4 ;
tomwalters@0 448
tomwalters@0 449 /* Adaptor 22 */
tomwalters@0 450 r1 = Kst_ratio * Kst_max / fs2 ; /* Zcst (initial value only) */
tomwalters@0 451 r2 = r214 ;
tomwalters@0 452 r3 = r1 + r2 ;
tomwalters@0 453 filter_state->gamma221 = 2. * r1 / r3 ;
tomwalters@0 454
tomwalters@0 455 #ifdef _DEBUG_
tomwalters@0 456 fprintf ( stderr, "gamma71 =%f \n", filter_state->gamma71 ) ;
tomwalters@0 457 fprintf ( stderr, "gamma81 =%f gamma82 =%f\n", filter_state->gamma81
tomwalters@0 458 , filter_state->gamma82 ) ;
tomwalters@0 459 fprintf ( stderr, "gamma91 =%f gamma92 =%f\n", filter_state->gamma91
tomwalters@0 460 , filter_state->gamma92 ) ;
tomwalters@0 461 fprintf ( stderr, "gamma101=%f \n", filter_state->gamma101 ) ;
tomwalters@0 462 fprintf ( stderr, "gamma111=%f gamma112=%f\n", filter_state->gamma111
tomwalters@0 463 , filter_state->gamma112 ) ;
tomwalters@0 464 fprintf ( stderr, "gamma121=%f \n", filter_state->gamma121 ) ;
tomwalters@0 465 fprintf ( stderr, "gamma131=%f \n", filter_state->gamma131 ) ;
tomwalters@0 466 fprintf ( stderr, "gamma141=%f \n", filter_state->gamma141 ) ;
tomwalters@0 467 fprintf ( stderr, "gamma151=%f \n", filter_state->gamma151 ) ;
tomwalters@0 468 fprintf ( stderr, "gamma161=%f \n", filter_state->gamma161 ) ;
tomwalters@0 469 fprintf ( stderr, "gamma171=%f gamma172=%f\n", filter_state->gamma171
tomwalters@0 470 , filter_state->gamma172 ) ;
tomwalters@0 471 fprintf ( stderr, "gamma181=%f \n", filter_state->gamma181 ) ;
tomwalters@0 472 fprintf ( stderr, "gamma191=%f \n", filter_state->gamma191 ) ;
tomwalters@0 473 fprintf ( stderr, "gamma201=%f gamma202=%f\n", filter_state->gamma201
tomwalters@0 474 , filter_state->gamma202 ) ;
tomwalters@0 475 fprintf ( stderr, "gamma211=%f gamma212=%f\n", filter_state->gamma211
tomwalters@0 476 , filter_state->gamma212 ) ;
tomwalters@0 477 fprintf ( stderr, "gamma221=%f \n", filter_state->gamma221 ) ;
tomwalters@0 478 #endif
tomwalters@0 479
tomwalters@0 480 /*** specify and initialise coefficient update procedure ***/
tomwalters@0 481 filter_state->update_proc = update_earmiddle ;
tomwalters@0 482 ( void ) update_earmiddle_init( fs2, r214 ) ;
tomwalters@0 483
tomwalters@0 484 /*** output scaling ***/
tomwalters@0 485 filter_state->out_scale = output_scale ;
tomwalters@0 486
tomwalters@0 487 /*** initialise filter states ***/
tomwalters@0 488 filter_state->Nstates = N_OF_EARMIDDLE_STATES ;
tomwalters@0 489 filter_state->states = ( char * ) NewZeroedArray( StateType, filter_state->Nstates,
tomwalters@0 490 "wdf_ear.c for middle ear states\n" ) ;
tomwalters@0 491
tomwalters@0 492 /*** return ***/
tomwalters@0 493 return( filter_state ) ;
tomwalters@0 494 }
tomwalters@0 495
tomwalters@0 496
tomwalters@0 497 /*********************************** WDF procedures ***************************************
tomwalters@0 498 * name: function:
tomwalters@0 499 *
tomwalters@0 500 * DoEarWDF() WDF realization of the _UNCOUPLED_ version of the outer ear and
tomwalters@0 501 * middle ear networks. It is called by function ``ear_callback()''
tomwalters@0 502 * in file ``ear.c'' once for a specified number of input points.
tomwalters@0 503 * It computes the stapes velocity for each input point and keeps
tomwalters@0 504 * track of the filter states.
tomwalters@0 505 *
tomwalters@0 506 * Note: The code for the realization of the _COUPLED_ ear version
tomwalters@0 507 * is located in file ``wdf_tl.c''.
tomwalters@0 508 *
tomwalters@0 509 *
tomwalters@0 510 * CloseEarWDF() Deletes all private data structures and arrays of the outer and
tomwalters@0 511 * middle ear filter upon completion of filtering.
tomwalters@0 512 * In the case of the _UNCOUPLED_ ear version, it is called by the
tomwalters@0 513 * function ``ear_callback()'' in file ``ear.c''.
tomwalters@0 514 * In the case of the _COUPLED_ ear version, it is called by the
tomwalters@0 515 * function ``tlf_bank_callbank()'' in file ``bank_tl.c''.
tomwalters@0 516 ******************************************************************************************/
tomwalters@0 517
tomwalters@0 518 /******************************* DoEarWDF() **************************************/
tomwalters@0 519
tomwalters@0 520 void DoEarWDF( ws, eartube_states, ms, tube_segments, inout_ptr, points )
tomwalters@0 521 register WaveWDFstate *ws ;
tomwalters@0 522 register EartubeWDFstate **eartube_states ;
tomwalters@0 523 register EarmiddleWDFstate *ms ;
tomwalters@0 524 register int tube_segments ;
tomwalters@0 525 register DataType *inout_ptr ;
tomwalters@0 526 register int points ;
tomwalters@0 527 {
tomwalters@0 528 register EartubeWDFstate *ts ;
tomwalters@0 529 register StateType *st, in, out ;
tomwalters@0 530 register StateType a0, an_1, b1, b2, b3, b161, b202, b212, bn ;
tomwalters@0 531 register int tube_segment = -1 ;
tomwalters@0 532 #ifdef _IMPULSE_
tomwalters@0 533 static int impulse = 10000 ;
tomwalters@0 534 #endif
tomwalters@0 535
tomwalters@0 536
tomwalters@0 537 /***** update stapedial muscle state *****/
tomwalters@0 538
tomwalters@0 539 ( void ) ms->update_proc( ms ) ;
tomwalters@0 540
tomwalters@0 541 /***** for all points *****/
tomwalters@0 542
tomwalters@0 543 while( points-- > 0 ) {
tomwalters@0 544
tomwalters@0 545 /*** input point ***/
tomwalters@0 546
tomwalters@0 547 in = ( StateType ) *inout_ptr ;
tomwalters@0 548
tomwalters@0 549 #ifdef _IMPULSE_
tomwalters@0 550 if( impulse != 0 ) {
tomwalters@0 551 in = ( StateType ) impulse ;
tomwalters@0 552 impulse = 0 ;
tomwalters@0 553 }
tomwalters@0 554 else
tomwalters@0 555 in = ( StateType ) 0 ;
tomwalters@0 556 #endif
tomwalters@0 557
tomwalters@0 558 /*** computation in FORWARD direction for current input point ***/
tomwalters@0 559
tomwalters@0 560 /* freefield - external ear */
tomwalters@0 561
tomwalters@0 562 /* get states */
tomwalters@0 563 st = ( StateType * ) ws->states ;
tomwalters@0 564
tomwalters@0 565 /* Adaptor 0 */
tomwalters@0 566 st[4] = ws->gamma01 * ( st[3] - in ) ; /* b00 */
tomwalters@0 567 st[5] = st[4] + in + in ; /* b03 = -a11 */
tomwalters@0 568
tomwalters@0 569 /* Adaptor 2 */
tomwalters@0 570 st[1] = -ws->gamma21 * st[0] ; /* b20 */
tomwalters@0 571 st[2] = st[1] ; /* b23 = a12 */
tomwalters@0 572
tomwalters@0 573 /* Adaptor 1 */
tomwalters@0 574 st[6] = st[5] - st[2] ; /* b13 = a32 */
tomwalters@0 575 an_1 = st[6] ;
tomwalters@0 576
tomwalters@0 577 /* concha and auditory canal */
tomwalters@0 578
tomwalters@0 579 while( ++tube_segment < tube_segments ) {
tomwalters@0 580
tomwalters@0 581 /* get states */
tomwalters@0 582 ts = *eartube_states++ ;
tomwalters@0 583 st = ( StateType * ) ts->states ;
tomwalters@0 584
tomwalters@0 585 /* Adaptor 3 */
tomwalters@0 586 st[3] = st[4] - an_1 ; /* b33 = a41 */
tomwalters@0 587
tomwalters@0 588 /* Adaptor 5 */
tomwalters@0 589 st[0] = -ts->gamma51 * st[1] ; /* b50 */
tomwalters@0 590 st[2] = st[0] + st[1] ; /* b53 = a42 */
tomwalters@0 591
tomwalters@0 592 /* Adaptor 4 */
tomwalters@0 593 st[5] = st[3] - st[2] ; /* -a42+a41 */
tomwalters@0 594 st[6] = ts->gamma41 * st[5] ; /* b40 */
tomwalters@0 595 st[7] = st[6] + st[2] ; /* b43 = a61 */
tomwalters@0 596
tomwalters@0 597 /* Adaptor 6 */
tomwalters@0 598 st[8] = st[9] - st[7] ; /* b63 = a32 */
tomwalters@0 599 an_1 = st[8] ;
tomwalters@0 600 }
tomwalters@0 601
tomwalters@0 602 /* middle ear */
tomwalters@0 603
tomwalters@0 604 /* get states */
tomwalters@0 605 st = ( StateType * ) ms->states ;
tomwalters@0 606
tomwalters@0 607 /* Adaptor 9 */
tomwalters@0 608 st[31] = st[30] - st[29] ; /* b94 = a81 */
tomwalters@0 609
tomwalters@0 610 /* Adaptor 8 */
tomwalters@0 611 st[32] = st[35] - st[31] ; /* a83-a81 */
tomwalters@0 612 st[33] = -ms->gamma81 * st[32] - ms->gamma82 * st[35] ; /* b80 */
tomwalters@0 613 st[34] = st[33] + st[35] ; /* b84 = a71 */
tomwalters@0 614
tomwalters@0 615 /* Adaptor 7 */
tomwalters@0 616 st[36] = -st[34] - an_1 ; /* b73 = a102 */
tomwalters@0 617
tomwalters@0 618 /* Adaptor 13 */
tomwalters@0 619 st[15] = -st[14] ; /* b133 = a122 */
tomwalters@0 620
tomwalters@0 621 /* Adaptor 12 */
tomwalters@0 622 st[16] = st[15] + st[18] ; /* a122-a121 */
tomwalters@0 623 st[17] = -ms->gamma121 * st[16] ; /* b120 */
tomwalters@0 624 st[19] = st[17] + st[15] ; /* b123 = a112 */
tomwalters@0 625
tomwalters@0 626 /* Adaptor 14 */
tomwalters@0 627 st[21] = -ms->gamma141 * st[20] ; /* b140 */
tomwalters@0 628 st[22] = st[21] + st[20] ; /* b143 = a111 */
tomwalters@0 629
tomwalters@0 630 /* Adaptor 15 */
tomwalters@0 631 st[23] = -st[24] ; /* b153 = a113 */
tomwalters@0 632
tomwalters@0 633 /* Adaptor 11 */
tomwalters@0 634 st[25] = -st[22] - st[19] - st[23] ; /* b114 = a101 */
tomwalters@0 635
tomwalters@0 636 /* Adaptor 10 */
tomwalters@0 637 st[26] = st[25] - st[36] ; /* -a102+a101 */
tomwalters@0 638 st[27] = ms->gamma101 * st[26] ; /* b100 */
tomwalters@0 639 st[28] = st[27] + st[36] ; /* b103 = a161 */
tomwalters@0 640
tomwalters@0 641 /* Adaptor 17 */
tomwalters@0 642 st[10] = st[12] - st[11] ; /* b174 = a162 */
tomwalters@0 643
tomwalters@0 644 /* Adaptor 16 */
tomwalters@0 645 st[13] = -st[28] - st[10] ; /* b163 = a181 */
tomwalters@0 646
tomwalters@0 647 /* Adaptor 19 */
tomwalters@0 648 st[5] = -st[6] ; /* b193 = a182 */
tomwalters@0 649
tomwalters@0 650 /* Adaptor 18 */
tomwalters@0 651 st[7] = st[13] - st[5] ; /* -a182+a181 */
tomwalters@0 652 st[8] = ms->gamma181 * st[7] ; /* b180 */
tomwalters@0 653 st[9] = st[8] + st[5] ; /* b183 = a203 */
tomwalters@0 654
tomwalters@0 655 /* Adaptor 20 */
tomwalters@0 656 st[3] = -st[9] ; /* b204 = a212 */
tomwalters@0 657
tomwalters@0 658 /* Adaptor 21 */
tomwalters@0 659 st[0] = st[2] - st[1] - st[3] ; /* b214 = a222 */
tomwalters@0 660
tomwalters@0 661
tomwalters@0 662 /*** computation in BACKWARD direction for current input point ***/
tomwalters@0 663
tomwalters@0 664 /* middle ear */
tomwalters@0 665
tomwalters@0 666 /* Adaptor 22 */
tomwalters@0 667 a0 = st[4] + st[0] ; /* a220 */
tomwalters@0 668 st[4] = st[4] - ms->gamma221 * a0 ; /* b221 */
tomwalters@0 669 b2 = -st[4] - a0 ; /* b222 = a214 */
tomwalters@0 670
tomwalters@0 671 /* Adaptor 21 */
tomwalters@0 672 a0 = b2 - st[0] ; /* a210 */
tomwalters@0 673 st[1] = st[1] - ms->gamma211 * a0 ; /* b211 */
tomwalters@0 674 b212 = st[3] - ms->gamma212 * a0 ; /* b212 = a204 */
tomwalters@0 675 st[2] = -st[1] - b212 - b2 ; /* b213 */
tomwalters@0 676
tomwalters@0 677 /* Adaptor 20 */
tomwalters@0 678 a0 = b212 - st[3] ; /* a200 */
tomwalters@0 679 b202 = - ms->gamma202 * a0 ; /* b202 */
tomwalters@0 680 b3 = ms->gamma201 * a0 - b202 - b212 ; /* b203 = a183 */
tomwalters@0 681
tomwalters@0 682 /* Adaptor 18 */
tomwalters@0 683 b2 = st[8] + b3 ; /* b182 = a193 */
tomwalters@0 684 b1 = b2 - st[7] ; /* b181 = a163 */
tomwalters@0 685
tomwalters@0 686 /* Adaptor 19 */
tomwalters@0 687 st[6] = st[6] + ms->gamma191 * ( st[5] - b2 ) ; /* b191 */
tomwalters@0 688
tomwalters@0 689 /* Adaptor 16 */
tomwalters@0 690 b161 = st[28] + ms->gamma161 * ( st[13] - b1 ) ; /* b161 = a103 */
tomwalters@0 691 b2 = -b161 - b1 ; /* b162 = a174 */
tomwalters@0 692
tomwalters@0 693 /* Adaptor 17 */
tomwalters@0 694 a0 = b2 - st[10] ; /* a170 */
tomwalters@0 695 st[11] = st[11] - ms->gamma171 * a0 ; /* b171 */
tomwalters@0 696 st[12] = ms->gamma172 * a0 - b2 - st[11] ; /* b173 */
tomwalters@0 697
tomwalters@0 698 /* Adaptor 10 */
tomwalters@0 699 st[37] = st[27] + b161 ; /* b102 = a73 */
tomwalters@0 700 st[38] = st[37] - st[26] ; /* b101 = a114 */
tomwalters@0 701
tomwalters@0 702 /* Adaptor 11 */
tomwalters@0 703 a0 = st[38] - st[25] ; /* a110 */
tomwalters@0 704 b1 = st[22] - ms->gamma111 * a0 ; /* b111 = a143 */
tomwalters@0 705 b2 = st[19] - ms->gamma112 * a0 ; /* b112 = a123 */
tomwalters@0 706 b3 = -b1 -b2 - st[38] ; /* b113 = a153 */
tomwalters@0 707
tomwalters@0 708 /* Adaptor 15 */
tomwalters@0 709 st[24] = st[24] + ms->gamma151 * ( st[23] - b3 ) ; /* b151 */
tomwalters@0 710
tomwalters@0 711 /* Adaptor 14 */
tomwalters@0 712 st[20] = st[21] + b1 ; /* b142 */
tomwalters@0 713
tomwalters@0 714 /* Adaptor 12 */
tomwalters@0 715 b2 = st[17] + b2 ; /* b122 = a133 */
tomwalters@0 716 st[18] = b2 + st[16] ; /* b121 */
tomwalters@0 717
tomwalters@0 718 /* Adaptor 13 */
tomwalters@0 719 st[14] = st[14] + ms->gamma131 * ( st[15] - b2 ) ; /* b131 */
tomwalters@0 720
tomwalters@0 721 /* Adaptor 7 */
tomwalters@0 722 b1 = st[34] + ms->gamma71 * ( st[36] - st[37] ) ; /* b71 = a84 */
tomwalters@0 723 st[39] = -b1 - st[37] ; /* b72 = a63 */
tomwalters@0 724
tomwalters@0 725 /* Adaptor 8 */
tomwalters@0 726 st[35] = st[33] + b1 ; /* b83 */
tomwalters@0 727 b1 = st[35] + st[32] ; /* b81 = a94 */
tomwalters@0 728
tomwalters@0 729 /* Adaptor 9 */
tomwalters@0 730 a0 = b1 - st[31] ; /* a90 */
tomwalters@0 731 st[29] = st[29] - ms->gamma91 * a0 ; /* b91 */
tomwalters@0 732 st[30] = -st[29] + ms->gamma92 * a0 - b1 ; /* b93 */
tomwalters@0 733
tomwalters@0 734 bn = st[39] ;
tomwalters@0 735
tomwalters@0 736 /* concha and auditory canal */
tomwalters@0 737
tomwalters@0 738 while( tube_segment-- > 0 ) {
tomwalters@0 739
tomwalters@0 740 /* get states */
tomwalters@0 741 ts = *--eartube_states ;
tomwalters@0 742 st = ( StateType * ) ts->states ;
tomwalters@0 743
tomwalters@0 744 /* Adaptor 6 */
tomwalters@0 745 b1 = st[7] - ts->gamma61 * ( bn - st[8] ) ; /* b61 = a43 */
tomwalters@0 746 st[9] = -b1 - bn ; /* b62 */
tomwalters@0 747
tomwalters@0 748 /* Adaptor 4 */
tomwalters@0 749 b2 = st[6] + b1 ; /* b42 = a53 */
tomwalters@0 750 b1 = b2 - st[5] ; /* b41 = a33 */
tomwalters@0 751
tomwalters@0 752 /* Adaptor 5 */
tomwalters@0 753 st[1] = st[0] + b2 ; /* b52 */
tomwalters@0 754
tomwalters@0 755 /* Adaptor 3 */
tomwalters@0 756 st[4] = ts->gamma31 * ( st[3] - b1 ) - st[4] ; /* b31 */
tomwalters@0 757 bn = -st[4] - b1 ; /* b32 = a63 */
tomwalters@0 758 }
tomwalters@0 759
tomwalters@0 760 /* freefield - external ear */
tomwalters@0 761
tomwalters@0 762 /* get states */
tomwalters@0 763 st = ( StateType * ) ws->states ;
tomwalters@0 764
tomwalters@0 765 /* Adaptor 1 */
tomwalters@0 766 b1 = ws->gamma11 * ( st[6] - bn ) - st[5] ; /* b11 = -a03 */
tomwalters@0 767 b2 = -b1 - bn ; /* b12 = a23 */
tomwalters@0 768
tomwalters@0 769 /* Adaptor 2 */
tomwalters@0 770 st[0] = st[1] + b2 + st[0] ; /* b61 */
tomwalters@0 771
tomwalters@0 772 /* Adaptor 0 */
tomwalters@0 773 st[3] = b1 - st[4] + st[3] ; /* -b01 + p */
tomwalters@0 774
tomwalters@0 775 /*** output ***/
tomwalters@0 776 #ifdef _EARDRUM_
tomwalters@0 777 st = ( StateType * ) ms->states ;
tomwalters@0 778 out = 0.5 * ( st[39] + an_1 ) * ms->out_scale ;
tomwalters@0 779 #else
tomwalters@0 780 out = -0.5 * b202 * ms->out_scale ;
tomwalters@0 781 #endif
tomwalters@0 782
tomwalters@0 783 #ifdef _OVERFLOW_
tomwalters@0 784 if( out > _MaxOutput_ || out < _MinOutput_ )
tomwalters@0 785 fprintf( stderr, "Overflow error in Outer/Middle ear output=%e\n", ( double ) out ) ;
tomwalters@0 786 #endif
tomwalters@0 787 *inout_ptr++ = out ;
tomwalters@0 788
tomwalters@0 789 }
tomwalters@0 790 return ;
tomwalters@0 791 }
tomwalters@0 792
tomwalters@0 793
tomwalters@0 794 /******************************* CloseEarWDF() *************************************/
tomwalters@0 795
tomwalters@0 796 void CloseEarWDF( wave_states, eartube_states, earmiddle_states, tube_segments )
tomwalters@0 797 register WaveWDFstate *wave_states ;
tomwalters@0 798 register EartubeWDFstate **eartube_states ;
tomwalters@0 799 register EarmiddleWDFstate *earmiddle_states ;
tomwalters@0 800 register int tube_segments ;
tomwalters@0 801 {
tomwalters@0 802 Delete( earmiddle_states->states ) ;
tomwalters@0 803 Delete( earmiddle_states ) ;
tomwalters@0 804
tomwalters@0 805 for( ; --tube_segments < 0 ; ) {
tomwalters@0 806 Delete( eartube_states[ tube_segments ]->states ) ;
tomwalters@0 807 Delete( eartube_states[ tube_segments ] ) ;
tomwalters@0 808 }
tomwalters@0 809 Delete( eartube_states ) ;
tomwalters@0 810
tomwalters@0 811 Delete( wave_states->states ) ;
tomwalters@0 812 Delete( wave_states ) ;
tomwalters@0 813
tomwalters@0 814 return ;
tomwalters@0 815
tomwalters@0 816 }
tomwalters@0 817
tomwalters@0 818 /************** low level functions **************/
tomwalters@0 819
tomwalters@0 820 static double den221 ;
tomwalters@0 821 static double Kst_old_ratio ;
tomwalters@0 822
tomwalters@0 823 void update_earmiddle_init( rate, z )
tomwalters@0 824 double rate, z ;
tomwalters@0 825 {
tomwalters@0 826 Kst_old_ratio = Kst_ratio ;
tomwalters@0 827 den221 = rate * z / Kst_max ;
tomwalters@0 828 return ;
tomwalters@0 829 }
tomwalters@0 830
tomwalters@0 831 void update_earmiddle( ms )
tomwalters@0 832 EarmiddleWDFstate *ms ;
tomwalters@0 833 {
tomwalters@0 834 if( Kst_ratio < Kst_min_ratio )
tomwalters@0 835 Kst_ratio = Kst_min_ratio ;
tomwalters@0 836
tomwalters@0 837 ms->gamma221 = 2. * Kst_ratio / ( Kst_ratio + den221 ) ;
tomwalters@0 838 ms->states[4] = ms->states[4] * Kst_ratio / Kst_old_ratio ;
tomwalters@0 839
tomwalters@0 840 Kst_old_ratio = Kst_ratio ;
tomwalters@0 841
tomwalters@0 842 return ;
tomwalters@0 843 }
tomwalters@0 844