tomwalters@0
|
1 % generating function for 'aim-mat'
|
tomwalters@0
|
2 %
|
tomwalters@0
|
3 % INPUT VALUES:
|
tomwalters@0
|
4 %
|
tomwalters@0
|
5 % RETURN VALUE:
|
tomwalters@0
|
6 %
|
tomwalters@0
|
7 %
|
tomwalters@0
|
8 % (c) 2011, University of Southampton
|
bleeck@3
|
9 % Maintained by Stefan Bleeck (bleeck@gmail.com)
|
bleeck@3
|
10 % download of current version is on the soundsoftware site:
|
bleeck@3
|
11 % http://code.soundsoftware.ac.uk/projects/aimmat
|
bleeck@3
|
12 % documentation and everything is on http://www.acousticscale.org
|
tomwalters@0
|
13
|
tomwalters@0
|
14
|
tomwalters@0
|
15
|
tomwalters@0
|
16
|
tomwalters@0
|
17 function ret=gen_twoDat2003(bmm,options)
|
tomwalters@0
|
18 % two D adaptive thresholding
|
tomwalters@0
|
19
|
tomwalters@0
|
20 % first do the normal nap:
|
tomwalters@0
|
21 nap=gen_hcl(bmm,options.nap);
|
tomwalters@0
|
22
|
tomwalters@0
|
23 if nargin < 2
|
tomwalters@0
|
24 options=[];
|
tomwalters@0
|
25 end
|
tomwalters@0
|
26
|
tomwalters@0
|
27
|
tomwalters@0
|
28 vals=getvalues(nap);
|
tomwalters@0
|
29
|
tomwalters@0
|
30
|
tomwalters@0
|
31
|
tomwalters@0
|
32 %%%normalise to 0-60dB range
|
tomwalters@0
|
33 %max_nap=max(max(vals));
|
tomwalters@0
|
34 %nap_norm=60./max_nap;
|
tomwalters@0
|
35 %vals=vals*nap_norm;
|
tomwalters@0
|
36 %save vals.mat vals;
|
tomwalters@0
|
37
|
tomwalters@0
|
38 new_vals=zeros(size(vals));
|
tomwalters@0
|
39 nr_chan=size(vals,1);
|
tomwalters@0
|
40 nr_dots=size(vals,2);
|
tomwalters@0
|
41 sr=getsr(nap);
|
tomwalters@0
|
42 cfs=getcf(nap);
|
tomwalters@0
|
43 load bmm.mat;
|
tomwalters@0
|
44
|
tomwalters@0
|
45
|
tomwalters@0
|
46 % the delays can be set by an option
|
tomwalters@0
|
47 if isfield(options,'time_constant_factor') % this is multiplied to the threshold_time_const
|
tomwalters@0
|
48 time_constant_factor=options.time_constant_factor;
|
tomwalters@0
|
49 else
|
tomwalters@0
|
50 time_constant_factor=0.8;
|
tomwalters@0
|
51 end
|
tomwalters@0
|
52
|
tomwalters@0
|
53 if isfield(options,'frequency_constant_factor') % the influence of the left and the right channel
|
tomwalters@0
|
54 frequency_constant_factor=options.frequency_constant_factor;
|
tomwalters@0
|
55 else
|
tomwalters@0
|
56 frequency_constant_factor=0.9;
|
tomwalters@0
|
57 end
|
tomwalters@0
|
58
|
tomwalters@0
|
59
|
tomwalters@0
|
60 if isfield(options,'threshold_rise_constant') % the rate at which the threshold may rise
|
tomwalters@0
|
61 threshold_rise_constant=options.threshold_rise_constant;
|
tomwalters@0
|
62 else
|
tomwalters@0
|
63 threshold_rise_constant=1;
|
tomwalters@0
|
64 end
|
tomwalters@0
|
65
|
tomwalters@0
|
66
|
tomwalters@0
|
67
|
tomwalters@0
|
68
|
tomwalters@0
|
69 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
tomwalters@0
|
70 %the following calculates the envelope of nap response
|
tomwalters@0
|
71 %out_li=zeros(nr_chan,nr_dots);
|
tomwalters@0
|
72 %for chan=1:nr_chan
|
tomwalters@0
|
73 %out_li(chan,:)=standard_leaky_integrator(vals(chan,:),0.003,1,16000);
|
tomwalters@0
|
74 %out_li_scale=max(vals(chan,:))./max(out_li(chan,:));
|
tomwalters@0
|
75 %out_li(chan,:)=out_li(chan,:).*out_li_scale;
|
tomwalters@0
|
76 %end
|
tomwalters@0
|
77 %[ERB_no, dummy] = Freq2ERB(cfs);
|
tomwalters@0
|
78 %for chan=1:nr_chan
|
tomwalters@0
|
79 %out_li(chan,:)=standard_leaky_integrator(vals(chan,:),0.003,1,16000);
|
tomwalters@0
|
80 %out_li_scale=max(vals(chan,:))./max(out_li(chan,:));
|
tomwalters@0
|
81 %out_li(chan,:)=out_li(chan,:).*out_li_scale;
|
tomwalters@0
|
82 %end
|
tomwalters@0
|
83 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
tomwalters@0
|
84
|
tomwalters@0
|
85
|
tomwalters@0
|
86 save cfs.mat cfs;
|
tomwalters@0
|
87 order = 4;
|
tomwalters@0
|
88 [rate ERB] = Freq2ERB(cfs);
|
tomwalters@0
|
89 B=1.019.*ERB;
|
tomwalters@0
|
90
|
tomwalters@0
|
91
|
tomwalters@0
|
92 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
tomwalters@0
|
93 %note: decay of gammatone is described by: exp(-2*pi*B*t)
|
tomwalters@0
|
94 % time to drop to 1/2 (6dB) --in seconds
|
tomwalters@0
|
95 %i.e. exp(-2*pi*B*t)=0.5
|
tomwalters@0
|
96 drop6dbtime=-log(0.5)./(2*pi.*B);
|
tomwalters@0
|
97
|
tomwalters@0
|
98 % this means so many per samplepoint
|
tomwalters@0
|
99 threshold_decay_constant=-log10(2)*20./(drop6dbtime*sr);
|
tomwalters@0
|
100 threshold_decay_constant=threshold_decay_constant./time_constant_factor;
|
tomwalters@0
|
101
|
tomwalters@0
|
102
|
tomwalters@0
|
103
|
tomwalters@0
|
104
|
tomwalters@0
|
105 threshold_rise=(100.*B.^0.9)./sr;
|
tomwalters@0
|
106 threshold_rise=threshold_rise.*threshold_rise_constant;
|
tomwalters@0
|
107 %threshold_rise=zeros(nr_chan);
|
tomwalters@0
|
108
|
tomwalters@0
|
109
|
tomwalters@0
|
110
|
tomwalters@0
|
111
|
tomwalters@0
|
112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
tomwalters@0
|
113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
tomwalters@0
|
114
|
tomwalters@0
|
115 %calc frequency slope values
|
tomwalters@0
|
116 if nr_chan>1
|
tomwalters@0
|
117 %frequency_slope_c=calcfreqslope(cfs(2),cfs(1));
|
tomwalters@0
|
118 %frequency_slope_a=calcfreqslope(cfs(1),cfs(2));
|
tomwalters@0
|
119
|
tomwalters@0
|
120 %c is effect from channel above but we must input
|
tomwalters@0
|
121 %the higher frequency (2) as the adjacent band and
|
tomwalters@0
|
122 %the channel in which we want the level (1)as
|
tomwalters@0
|
123 %the centre freq
|
tomwalters@0
|
124 frequency_slope_c=calcfreqslope(cfs(1),cfs(2));
|
tomwalters@0
|
125
|
tomwalters@0
|
126 %a is effect from channel below but we must input
|
tomwalters@0
|
127 %the lower frequency (1) as the adjacent band and
|
tomwalters@0
|
128 %the channel in which we want the level (2) as
|
tomwalters@0
|
129 %the centre freq
|
tomwalters@0
|
130 frequency_slope_a=calcfreqslope(cfs(2),cfs(1));
|
tomwalters@0
|
131
|
tomwalters@0
|
132 else
|
tomwalters@0
|
133 frequency_slope_c=0;
|
tomwalters@0
|
134 frequency_slope_a=0;
|
tomwalters@0
|
135 end
|
tomwalters@0
|
136
|
tomwalters@0
|
137 %we divide by the frequency_constant_factor because we want a
|
tomwalters@0
|
138 %frequency_constant_factor of 1 to mean we use the actual
|
tomwalters@0
|
139 %frequency slope and a frequency_constant_factor of 0.5
|
tomwalters@0
|
140 %to mean that the frequency slope falls away at twice the rate
|
tomwalters@0
|
141 %i.e. less effect
|
tomwalters@0
|
142 frequency_slope_c=frequency_slope_c./frequency_constant_factor;
|
tomwalters@0
|
143 frequency_slope_a=frequency_slope_a./frequency_constant_factor;
|
tomwalters@0
|
144
|
tomwalters@0
|
145
|
tomwalters@0
|
146
|
tomwalters@0
|
147
|
tomwalters@0
|
148 oldfigure=gcf;
|
tomwalters@0
|
149 if nr_chan==1
|
tomwalters@0
|
150 onechannelfigure=figure(3); % assuming, the other one is 1
|
tomwalters@0
|
151 end
|
tomwalters@0
|
152
|
tomwalters@0
|
153 % channel_select=1:nr_chan;
|
tomwalters@0
|
154 times_per_ms=round(sr*0.01);
|
tomwalters@0
|
155 if nr_chan>1
|
tomwalters@0
|
156 waithand=waitbar(0,'generating 2dat');
|
tomwalters@0
|
157 end
|
tomwalters@0
|
158
|
tomwalters@0
|
159
|
tomwalters@0
|
160
|
tomwalters@0
|
161 val_e=zeros(nr_chan,nr_dots);
|
tomwalters@0
|
162 val_inp=zeros(nr_chan,nr_dots);
|
tomwalters@0
|
163 val_thres=zeros(nr_chan,nr_dots);
|
tomwalters@0
|
164
|
tomwalters@0
|
165
|
tomwalters@0
|
166
|
tomwalters@0
|
167
|
tomwalters@0
|
168 % a is the decayed working variable from the channel above
|
tomwalters@0
|
169 % b is the range limit
|
tomwalters@0
|
170 % c is the decayed working variable from the channel below
|
tomwalters@0
|
171 % d is the delayed and decayed nap signal from on-channel
|
tomwalters@0
|
172 % e is the maximum of [a b c d]
|
tomwalters@0
|
173 % threshold is the working variable
|
tomwalters@0
|
174 % thresholdlast is the working variable in the last round
|
tomwalters@0
|
175 % inp is the current input
|
tomwalters@0
|
176
|
tomwalters@0
|
177
|
tomwalters@0
|
178 thresholdlast=zeros(nr_chan,1);
|
tomwalters@0
|
179 threshold=zeros(nr_chan,1);
|
tomwalters@0
|
180 a=0;b=1;c=0;d=0;e=0;
|
tomwalters@0
|
181
|
tomwalters@0
|
182
|
tomwalters@0
|
183
|
tomwalters@0
|
184 for ii=1:nr_dots % through the time
|
tomwalters@0
|
185 if nr_chan>1
|
tomwalters@0
|
186 if mod(ii,times_per_ms)==0
|
tomwalters@0
|
187 waitbar(ii/nr_dots);
|
tomwalters@0
|
188 end
|
tomwalters@0
|
189 end
|
tomwalters@0
|
190
|
tomwalters@0
|
191 for jj=1:nr_chan % through all channels: prepare working variable
|
tomwalters@0
|
192 inp=vals(jj,ii);% current input
|
tomwalters@0
|
193
|
tomwalters@0
|
194 if jj< nr_chan
|
tomwalters@0
|
195 chan_above=thresholdlast(jj+1);
|
tomwalters@0
|
196 a=chan_above+frequency_slope_a;
|
tomwalters@0
|
197 else
|
tomwalters@0
|
198 a=0;
|
tomwalters@0
|
199 end
|
tomwalters@0
|
200 if jj>1
|
tomwalters@0
|
201 chan_below=thresholdlast(jj-1);
|
tomwalters@0
|
202 c=chan_below+frequency_slope_c;
|
tomwalters@0
|
203 else
|
tomwalters@0
|
204 c=0;
|
tomwalters@0
|
205 end
|
tomwalters@0
|
206
|
tomwalters@0
|
207 %a=0;
|
tomwalters@0
|
208 %c=0;
|
tomwalters@0
|
209
|
tomwalters@0
|
210
|
tomwalters@0
|
211
|
tomwalters@0
|
212
|
tomwalters@0
|
213 d=max(thresholdlast(jj)+threshold_decay_constant(jj),0);
|
tomwalters@0
|
214
|
tomwalters@0
|
215
|
tomwalters@0
|
216 e1=max(a,b);
|
tomwalters@0
|
217 e2=max(c,d);
|
tomwalters@0
|
218 e=max(e1,e2);
|
tomwalters@0
|
219
|
tomwalters@0
|
220
|
tomwalters@0
|
221
|
tomwalters@0
|
222
|
tomwalters@0
|
223 if inp>e %threshold is exceeded
|
tomwalters@0
|
224
|
tomwalters@0
|
225 threshold(jj)=min(thresholdlast(jj)+threshold_rise(jj),inp);
|
tomwalters@0
|
226 %threshold(jj)=inp;
|
tomwalters@0
|
227
|
tomwalters@0
|
228 %new_vals(jj,ii)=threshold(jj)-e;
|
tomwalters@0
|
229 new_vals(jj,ii)=inp-threshold(jj);
|
tomwalters@0
|
230 % % else threshold decays
|
tomwalters@0
|
231 else
|
tomwalters@0
|
232 threshold(jj)=e;
|
tomwalters@0
|
233 new_vals(jj,ii)=0;
|
tomwalters@0
|
234 end
|
tomwalters@0
|
235
|
tomwalters@0
|
236
|
tomwalters@0
|
237
|
tomwalters@0
|
238 val_e(jj,ii)=e;
|
tomwalters@0
|
239 val_inp(jj,ii)=inp;
|
tomwalters@0
|
240 val_thres(jj,ii)=threshold(jj);
|
tomwalters@0
|
241
|
tomwalters@0
|
242
|
tomwalters@0
|
243 end
|
tomwalters@0
|
244
|
tomwalters@0
|
245
|
tomwalters@0
|
246
|
tomwalters@0
|
247
|
tomwalters@0
|
248
|
tomwalters@0
|
249 % prepare next round
|
tomwalters@0
|
250 if ii< nr_dots
|
tomwalters@0
|
251 thresholdlast=threshold;
|
tomwalters@0
|
252 end
|
tomwalters@0
|
253
|
tomwalters@0
|
254 if nr_chan==1
|
tomwalters@0
|
255 tvals(ii)=thresholdlast;
|
tomwalters@0
|
256 end
|
tomwalters@0
|
257
|
tomwalters@0
|
258
|
tomwalters@0
|
259 end
|
tomwalters@0
|
260
|
tomwalters@0
|
261
|
tomwalters@0
|
262
|
tomwalters@0
|
263
|
tomwalters@0
|
264
|
tomwalters@0
|
265 if nr_chan==1
|
tomwalters@0
|
266 figure(onechannelfigure);
|
tomwalters@0
|
267 plot(nap);
|
tomwalters@0
|
268 hold on
|
tomwalters@0
|
269 a=plot(tvals,'r');
|
tomwalters@0
|
270 set(a,'LineWidth',1.5);
|
tomwalters@0
|
271 end
|
tomwalters@0
|
272
|
tomwalters@0
|
273
|
tomwalters@0
|
274 nap=setvalues(nap,new_vals);
|
tomwalters@0
|
275 %save nap.mat nap;
|
tomwalters@0
|
276
|
tomwalters@0
|
277 vals=getvalues(nap);
|
tomwalters@0
|
278 nap=setallmaxvalue(nap,max(max(vals))*2);
|
tomwalters@0
|
279 nap=setallminvalue(nap,min(min(vals)));
|
tomwalters@0
|
280
|
tomwalters@0
|
281
|
tomwalters@0
|
282
|
tomwalters@0
|
283 %save val_e.mat val_e;
|
tomwalters@0
|
284 %save new_vals.mat new_vals;
|
tomwalters@0
|
285 %save val_inp.mat val_inp;
|
tomwalters@0
|
286 %save val_thres.mat val_thres;
|
tomwalters@0
|
287
|
tomwalters@0
|
288
|
tomwalters@0
|
289
|
tomwalters@0
|
290
|
tomwalters@0
|
291
|
tomwalters@0
|
292
|
tomwalters@0
|
293
|
tomwalters@0
|
294 ret=nap;
|
tomwalters@0
|
295 if nr_chan>1
|
tomwalters@0
|
296 close(waithand);
|
tomwalters@0
|
297 end
|
tomwalters@0
|
298
|
tomwalters@0
|
299 figure(oldfigure); |