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 ear.c
|
tomwalters@0
|
42 ===========================================================
|
tomwalters@0
|
43
|
tomwalters@0
|
44 Design of outer and middle ear (EAR) filter.
|
tomwalters@0
|
45 (uncoupled version)
|
tomwalters@0
|
46
|
tomwalters@0
|
47 Author : Christian Giguere
|
tomwalters@0
|
48 First written : 01st June, 1991
|
tomwalters@0
|
49 Last edited : 07th March, 1994
|
tomwalters@0
|
50 ===========================================================
|
tomwalters@0
|
51 */
|
tomwalters@0
|
52
|
tomwalters@0
|
53
|
tomwalters@0
|
54 /***** includes *****/
|
tomwalters@0
|
55
|
tomwalters@0
|
56 #include <math.h>
|
tomwalters@0
|
57 #include <stdio.h>
|
tomwalters@0
|
58 #include "stitch.h"
|
tomwalters@0
|
59 #include "source.h"
|
tomwalters@0
|
60 #include "calc.h"
|
tomwalters@0
|
61 #include "calc_tl.h"
|
tomwalters@0
|
62 #include "wdf_ear.h"
|
tomwalters@0
|
63 #include "ear.h"
|
tomwalters@0
|
64
|
tomwalters@0
|
65
|
tomwalters@0
|
66 /***** defines *****/
|
tomwalters@0
|
67
|
tomwalters@0
|
68 #if 0
|
tomwalters@0
|
69 #define _DEBUG_
|
tomwalters@0
|
70 #endif
|
tomwalters@0
|
71
|
tomwalters@0
|
72 /***** functions *****/
|
tomwalters@0
|
73
|
tomwalters@0
|
74
|
tomwalters@0
|
75 /**************************************************************************
|
tomwalters@0
|
76 * name: function:
|
tomwalters@0
|
77 *
|
tomwalters@0
|
78 * ear_callback() Callable procedure returning pointer to filtered
|
tomwalters@0
|
79 * data (stapes velocity).
|
tomwalters@0
|
80 *
|
tomwalters@0
|
81 * Ear() Set-up and initialization function for the design
|
tomwalters@0
|
82 * of the outer and middle ear filter (this filter is
|
tomwalters@0
|
83 * not coupled to the cochlea). Returns pointer to
|
tomwalters@0
|
84 * a new source.
|
tomwalters@0
|
85 ***************************************************************************/
|
tomwalters@0
|
86
|
tomwalters@0
|
87 struct _ear_state {
|
tomwalters@0
|
88 struct _fillable_source parent ;
|
tomwalters@0
|
89 Source source ;
|
tomwalters@0
|
90 Pointer input ;
|
tomwalters@0
|
91 int inout_size ;
|
tomwalters@0
|
92 void (*proc)(), (*close)() ;
|
tomwalters@0
|
93 int Ntube ;
|
tomwalters@0
|
94 WaveWDFstate *wave_states ;
|
tomwalters@0
|
95 EartubeWDFstate **eartube_states ;
|
tomwalters@0
|
96 EarmiddleWDFstate *earmiddle_states ;
|
tomwalters@0
|
97 } ;
|
tomwalters@0
|
98
|
tomwalters@0
|
99
|
tomwalters@0
|
100 /******************************** ear_callback() *************************************/
|
tomwalters@0
|
101
|
tomwalters@0
|
102 static Pointer ear_callback( state, bytes, buffer )
|
tomwalters@0
|
103 struct _ear_state *state ;
|
tomwalters@0
|
104 ByteCount *bytes ;
|
tomwalters@0
|
105 Pointer buffer ;
|
tomwalters@0
|
106 {
|
tomwalters@0
|
107 register int last = *bytes == 0 ;
|
tomwalters@0
|
108 register int points ;
|
tomwalters@0
|
109
|
tomwalters@0
|
110 /***** process *****/
|
tomwalters@0
|
111 if( !last ) {
|
tomwalters@0
|
112
|
tomwalters@0
|
113 /*** get input data ***/
|
tomwalters@0
|
114 Fill(state->source, *bytes, buffer ) ;
|
tomwalters@0
|
115
|
tomwalters@0
|
116 /*** process data ***/
|
tomwalters@0
|
117 points = *bytes / state->inout_size ;
|
tomwalters@0
|
118 state->proc( state->wave_states, state->eartube_states, state->earmiddle_states,
|
tomwalters@0
|
119 state->Ntube, buffer, points ) ;
|
tomwalters@0
|
120
|
tomwalters@0
|
121 return ( buffer ) ;
|
tomwalters@0
|
122 }
|
tomwalters@0
|
123
|
tomwalters@0
|
124 /***** close *****/
|
tomwalters@0
|
125 else {
|
tomwalters@0
|
126
|
tomwalters@0
|
127 Fill( state->source, 0, buffer ) ;
|
tomwalters@0
|
128 state->close( state->wave_states, state->eartube_states, state->earmiddle_states, state->Ntube ) ;
|
tomwalters@0
|
129
|
tomwalters@0
|
130 return ( DeleteFillableSource( state ) ) ;
|
tomwalters@0
|
131 }
|
tomwalters@0
|
132
|
tomwalters@0
|
133 }
|
tomwalters@0
|
134
|
tomwalters@0
|
135
|
tomwalters@0
|
136 /************************************ Ear() *******************************************/
|
tomwalters@0
|
137
|
tomwalters@0
|
138 Source Ear( source, samplerate, output_gain, concha, canal )
|
tomwalters@0
|
139 Source source ;
|
tomwalters@0
|
140 double samplerate, output_gain ;
|
tomwalters@0
|
141 TubeInfo *concha, *canal ;
|
tomwalters@0
|
142 {
|
tomwalters@0
|
143 DeclareNew( struct _ear_state *, state ) ;
|
tomwalters@0
|
144 double length, diam, attn ;
|
tomwalters@0
|
145 int segment ;
|
tomwalters@0
|
146
|
tomwalters@0
|
147 /***** initialise input-related parameters *****/
|
tomwalters@0
|
148 state->inout_size = sizeof ( DataType ) ;
|
tomwalters@0
|
149 state->input = ( Pointer ) 0 ;
|
tomwalters@0
|
150 state->source = source ;
|
tomwalters@0
|
151
|
tomwalters@0
|
152 /***** Specify WDF filter design parameters *****/
|
tomwalters@0
|
153 state->wave_states = FreefieldWDF( samplerate, RHO_air, C, As, concha->diameter/2. ) ;
|
tomwalters@0
|
154
|
tomwalters@0
|
155 state->Ntube = canal->Nsegments + concha->Nsegments ;
|
tomwalters@0
|
156 state->eartube_states = NewArray( EartubeWDFstate *, state->Ntube, "ear.c for eartube states" ) ;
|
tomwalters@0
|
157
|
tomwalters@0
|
158 length = concha->length / concha->Nsegments ;
|
tomwalters@0
|
159 diam = concha->diameter ;
|
tomwalters@0
|
160 attn = concha->att_factor ;
|
tomwalters@0
|
161 for( segment = 0 ; segment < concha->Nsegments ; segment++ )
|
tomwalters@0
|
162 state->eartube_states[ segment ] = EartubeWDF( samplerate, RHO_air, C, diam, length, attn ) ;
|
tomwalters@0
|
163
|
tomwalters@0
|
164 length = canal->length / canal->Nsegments ;
|
tomwalters@0
|
165 diam = canal->diameter ;
|
tomwalters@0
|
166 attn = canal->att_factor ;
|
tomwalters@0
|
167 for( ; segment < state->Ntube ; segment++ )
|
tomwalters@0
|
168 state->eartube_states[ segment ] = EartubeWDF( samplerate, RHO_air, C, diam, length, attn ) ;
|
tomwalters@0
|
169
|
tomwalters@0
|
170 state->earmiddle_states = EarmiddleWDF( samplerate, 0.0, output_gain, 1.0 ) ;
|
tomwalters@0
|
171
|
tomwalters@0
|
172 state->proc = DoEarWDF ;
|
tomwalters@0
|
173 state->close = CloseEarWDF ;
|
tomwalters@0
|
174
|
tomwalters@0
|
175 /***** return *****/
|
tomwalters@0
|
176 source = SetFillableSource( state, ear_callback, "ear filter stage" ) ;
|
tomwalters@0
|
177 return ( source ) ;
|
tomwalters@0
|
178
|
tomwalters@0
|
179 }
|
tomwalters@0
|
180
|