bleeck@4
|
1 % function [pitchstrength, dominant_time] = find_pitches(profile, , a_priori, fqp_fq)
|
bleeck@4
|
2 %
|
bleeck@4
|
3 % To analyse the time interval profile of the auditory image
|
bleeck@4
|
4 %
|
bleeck@4
|
5 % INPUT VALUES:
|
bleeck@4
|
6 %
|
bleeck@4
|
7 % RETURN VALUE:
|
bleeck@4
|
8 %
|
bleeck@4
|
9
|
bleeck@4
|
10 % (c) 2003, University of Cambridge, Medical Research Council
|
bleeck@4
|
11 % Stefan Bleeck (stefan@bleeck.de)
|
bleeck@4
|
12 % http://www.mrc-cbu.cam.ac.uk/cnbh/aimmanual
|
bleeck@4
|
13 % $Date: 2003/07/17 10:56:16 $
|
bleeck@4
|
14 % $Revision: 1.5 $
|
bleeck@4
|
15 function result = find_pitches(profile,options)
|
bleeck@4
|
16 % different ways to define the pitch strength:
|
bleeck@4
|
17 % 1: the absolute height of the highest peak
|
bleeck@4
|
18 % 2: ratio between peak hight and width devided at base
|
bleeck@4
|
19 % % % % 2: the ration of the highest peak divided by the width at a certain point (given
|
bleeck@4
|
20 % % % % by the parameter height_to_width_ratio
|
bleeck@4
|
21 % 3: the height of the highest peak divided by the hight of the peak just one to
|
bleeck@4
|
22 % the right. This measurement is very successfull in the ramped/damped stimuli
|
bleeck@4
|
23 %
|
bleeck@4
|
24 % 4: Further we want to know all these values at a fixed point called target_frequency
|
bleeck@4
|
25 % and in the range given by allowed_frequency_deviation in %
|
bleeck@4
|
26 %
|
bleeck@4
|
27 % 5: We are also interested in the frequency value of the highest peak, because
|
bleeck@4
|
28 % we hope, that this is finally the pitch.
|
bleeck@4
|
29 %
|
bleeck@4
|
30 % 6: for the dual profile model, we also give back two more values concerning similar
|
bleeck@4
|
31 % properties for the spectral profile. Here, the pitch strenght is defined as the
|
bleeck@4
|
32 % height of the highest peak divided by the range that is given in two parameters
|
bleeck@4
|
33 % (usually 20% to 80% of the maximum)
|
bleeck@4
|
34
|
bleeck@4
|
35
|
bleeck@4
|
36 plot_switch =1;
|
bleeck@4
|
37
|
bleeck@4
|
38 if nargin < 2
|
bleeck@4
|
39 options=[];
|
bleeck@4
|
40 end
|
bleeck@4
|
41 %
|
bleeck@4
|
42
|
bleeck@4
|
43 % peaks must be higher then this of the maximum to be recognised
|
bleeck@4
|
44 ps_threshold=0.1;
|
bleeck@4
|
45 height_width_ratio=options.ps_options.height_width_ratio; % height of peak, where the width is measured
|
bleeck@4
|
46
|
bleeck@4
|
47
|
bleeck@4
|
48 % preliminary return values.
|
bleeck@4
|
49 % height of the highest peak
|
bleeck@4
|
50 % result.free.highest_peak_hight=0;
|
bleeck@4
|
51 % result.free.highest_peak_frequency=0;
|
bleeck@4
|
52 % hight to width ratio
|
bleeck@4
|
53 % result.free.height_width_ratio=0;
|
bleeck@4
|
54 % highest peak divided by next highest
|
bleeck@4
|
55 % result.free.neigbouring_ratio=0;
|
bleeck@4
|
56
|
bleeck@4
|
57 % now all these at a fixed frequency:
|
bleeck@4
|
58 % % result.fixed.highest_peak_hight=0;
|
bleeck@4
|
59 % result.fixed.highest_peak_frequency=0;
|
bleeck@4
|
60 % result.fixed.height_width_ratio=0;
|
bleeck@4
|
61 % result.fixed.neigbouring_ratio=0;
|
bleeck@4
|
62 %
|
bleeck@4
|
63 % % other things useful for plotting
|
bleeck@4
|
64 % result.smoothed_signal=[];
|
bleeck@4
|
65 % result.peaks = [];
|
bleeck@4
|
66
|
bleeck@4
|
67
|
bleeck@4
|
68 % now start the show
|
bleeck@4
|
69
|
bleeck@4
|
70 % % change the scaling to logarithm, before doing anything else:
|
bleeck@4
|
71 % log_profile=logsigx(profile,0.001,0.035);
|
bleeck@4
|
72 % result.smoothed_signal=log_profile;
|
bleeck@4
|
73
|
bleeck@4
|
74 % don't do this change
|
bleeck@4
|
75 log_profile=profile;
|
bleeck@4
|
76
|
bleeck@4
|
77 current_lowpass_frequency=options.ps_options.low_pass_frequency;
|
bleeck@4
|
78 smooth_sig=lowpass(log_profile,current_lowpass_frequency);
|
bleeck@4
|
79 envpeaks = PeakPicker(smooth_sig);
|
bleeck@4
|
80 result.smoothed_signal=smooth_sig;
|
bleeck@4
|
81
|
bleeck@4
|
82 if isempty(envpeaks) % only, when there is no signal
|
bleeck@4
|
83 return
|
bleeck@4
|
84 end
|
bleeck@4
|
85
|
bleeck@4
|
86 % reject impossible peaks
|
bleeck@4
|
87 ep=envpeaks;ep2=[];c=1;
|
bleeck@4
|
88 for i=1:length(envpeaks);
|
bleeck@4
|
89 if envpeaks{i}.t>0.002 && envpeaks{i}.t<0.03 && envpeaks{i}.y>0.01
|
bleeck@4
|
90 ep2{c}=ep{i};
|
bleeck@4
|
91 c=c+1;
|
bleeck@4
|
92 end
|
bleeck@4
|
93 end
|
bleeck@4
|
94 envpeaks=ep2; % replace
|
bleeck@4
|
95 if isempty(envpeaks) % only, when there is no signal
|
bleeck@4
|
96 return
|
bleeck@4
|
97 end
|
bleeck@4
|
98 %
|
bleeck@4
|
99 % % translate times back to times:
|
bleeck@4
|
100 % for i=1:length(envpeaks) % construct all maxima
|
bleeck@4
|
101 % envpeaks{i}.t=1/x2fre(smooth_sig,envpeaks{i}.x);
|
bleeck@4
|
102 % end
|
bleeck@4
|
103
|
bleeck@4
|
104
|
bleeck@4
|
105 % nr1: highest peak value
|
bleeck@4
|
106 % find the highest peak and its frequency
|
bleeck@4
|
107 % sort all for the highest first!
|
bleeck@4
|
108 % envpeaks=sortstruct(envpeaks,'y');
|
bleeck@4
|
109 % result.free.highest_peak_frequency=1/envpeaks{1}.t;
|
bleeck@4
|
110 % result.free.highest_peak_hight=envpeaks{1}.y;
|
bleeck@4
|
111
|
bleeck@4
|
112
|
bleeck@4
|
113
|
bleeck@4
|
114 % SB 08.2012: adjusted the method to make it simpler for Daniels signals of
|
bleeck@4
|
115 % IRN
|
bleeck@4
|
116 % nr 2: height to width of each peak. Height=height of peak. Width = width
|
bleeck@4
|
117 % of the two adjacent minima
|
bleeck@4
|
118 for i=1:length(envpeaks) % construct all maxima
|
bleeck@4
|
119 where=envpeaks{i}.t;
|
bleeck@4
|
120 hp=envpeaks{i}.y; % height peak
|
bleeck@4
|
121 hb=(envpeaks{i}.left.y+envpeaks{i}.right.y)/2;% base peak
|
bleeck@4
|
122 diffheight=hp-hb;
|
bleeck@4
|
123 w=log(envpeaks{i}.right.t)-log(envpeaks{i}.left.t); % width at base
|
bleeck@4
|
124 if w>0 && diffheight>0.
|
bleeck@4
|
125 envpeaks{i}.v2012_height_base_width_ratio=diffheight/w;
|
bleeck@4
|
126 else
|
bleeck@4
|
127 envpeaks{i}.v2012_height_base_width_ratio=0;
|
bleeck@4
|
128 end
|
bleeck@4
|
129 envpeaks{i}.v2012_base_width=w;
|
bleeck@4
|
130 envpeaks{i}.v2012_base_where_widths=hb; %base height
|
bleeck@4
|
131 end
|
bleeck@4
|
132
|
bleeck@4
|
133 envpeaks=sortstruct(envpeaks,'v2012_height_base_width_ratio');
|
bleeck@4
|
134
|
bleeck@4
|
135 if plot_switch
|
bleeck@4
|
136 figure(2134)
|
bleeck@4
|
137 clf
|
bleeck@4
|
138 hold on
|
bleeck@4
|
139 plot(log_profile,'r');
|
bleeck@4
|
140 plot(smooth_sig,'b')
|
bleeck@4
|
141 for i=1:min(5,length(envpeaks))
|
bleeck@4
|
142 % time=envpeaks{i}.t;
|
bleeck@4
|
143 % x=envpeaks{i}.x;
|
bleeck@4
|
144 % y=envpeaks{i}.y;
|
bleeck@4
|
145 % plot(time,y,'Marker','o','Markerfacecolor','g','MarkeredgeColor','g','MarkerSize',2);
|
bleeck@4
|
146 % time_left=envpeaks{i}.left.t;
|
bleeck@4
|
147 % % x_left=envpeaks{i}.left.x;
|
bleeck@4
|
148 % y_left=envpeaks{i}.left.y;
|
bleeck@4
|
149 % time_right=envpeaks{i}.right.t;
|
bleeck@4
|
150 % % x_right=envpeaks{i}.right.x;
|
bleeck@4
|
151 % y_right=envpeaks{i}.right.y;
|
bleeck@4
|
152 % plot(time_left,y_left,'Marker','o','Markerfacecolor','r','MarkeredgeColor','r','MarkerSize',2);
|
bleeck@4
|
153 % plot(time_right,y_right,'Marker','o','Markerfacecolor','r','MarkeredgeColor','r','MarkerSize',2);
|
bleeck@4
|
154
|
bleeck@4
|
155 t=envpeaks{i}.t;
|
bleeck@4
|
156 ypeak=envpeaks{i}.y;
|
bleeck@4
|
157 % ps=peaks{ii}.pitchstrength;
|
bleeck@4
|
158 ps=envpeaks{i}.v2012_height_base_width_ratio;
|
bleeck@4
|
159
|
bleeck@4
|
160 if i==1
|
bleeck@4
|
161 plot(t,ypeak,'Marker','o','Markerfacecolor','b','MarkeredgeColor','b','MarkerSize',10);
|
bleeck@4
|
162 text(t,ypeak*1.05,sprintf('%3.0f Hz: %4.2f ',1/t,ps),'VerticalAlignment','bottom','HorizontalAlignment','center','color','b','Fontsize',12);
|
bleeck@4
|
163 else
|
bleeck@4
|
164 plot(t,ypeak,'Marker','o','Markerfacecolor','g','MarkeredgeColor','w','MarkerSize',5);
|
bleeck@4
|
165 text(t,ypeak*1.05,sprintf('%3.0f Hz: %4.2f ',1/t,ps),'VerticalAlignment','bottom','HorizontalAlignment','center','color','g','Fontsize',12);
|
bleeck@4
|
166 end
|
bleeck@4
|
167 plot(envpeaks{i}.left.t,envpeaks{i}.left.y,'Marker','o','Markerfacecolor','r','MarkeredgeColor','r','MarkerSize',5);
|
bleeck@4
|
168 plot(envpeaks{i}.right.t,envpeaks{i}.right.y,'Marker','o','Markerfacecolor','r','MarkeredgeColor','r','MarkerSize',5);
|
bleeck@4
|
169
|
bleeck@4
|
170
|
bleeck@4
|
171 ybase=envpeaks{i}.v2012_base_where_widths;
|
bleeck@4
|
172 line([t t],[ybase ypeak],'color','m');
|
bleeck@4
|
173 line([envpeaks{i}.left.t envpeaks{i}.right.t],[ybase ybase],'color','m');
|
bleeck@4
|
174
|
bleeck@4
|
175 end
|
bleeck@4
|
176
|
bleeck@4
|
177 % set(gca,'xscale','log')
|
bleeck@4
|
178 set(gca,'xlim',[0.001 0.03])
|
bleeck@4
|
179
|
bleeck@4
|
180 fres=[500 300 200 150 100 70 50 20];
|
bleeck@4
|
181 set(gca,'xtick',1./fres);
|
bleeck@4
|
182 set(gca,'xticklabel',fres);
|
bleeck@4
|
183 xlabel('Frequency (Hz)')
|
bleeck@4
|
184 ylabel('arbitrary normalized units')
|
bleeck@4
|
185
|
bleeck@4
|
186 % current_time=options.current_time*1000;
|
bleeck@4
|
187 % y=get(gca,'ylim');
|
bleeck@4
|
188 % y=y(2);
|
bleeck@4
|
189 % text(700,y,sprintf('%3.0f ms',current_time),'verticalalignment','top');
|
bleeck@4
|
190
|
bleeck@4
|
191 % for i=1:length(envpeaks)
|
bleeck@4
|
192 % height_width_ratio=envpeaks{i}.height_width_ratio;
|
bleeck@4
|
193 % if i <4
|
bleeck@4
|
194 % line([envpeaks{i}.t envpeaks{i}.x],[envpeaks{i}.y envpeaks{i}.y*(1-height_width_ratio)],'Color','r');
|
bleeck@4
|
195 % line([envpeaks{i}.where_widths(1) envpeaks{i}.where_widths(2)],[envpeaks{i}.y*(1-height_width_ratio) envpeaks{i}.y*(1-height_width_ratio)],'Color','r');
|
bleeck@4
|
196 % x=envpeaks{i}.t;
|
bleeck@4
|
197 % fre=1/envpeaks{i}.t;
|
bleeck@4
|
198 % y=envpeaks{i}.y;
|
bleeck@4
|
199 % text(x,y*1.05,sprintf('%3.0fHz: %2.2f',fre,height_width_ratio),'HorizontalAlignment','center');
|
bleeck@4
|
200 % end
|
bleeck@4
|
201 % end
|
bleeck@4
|
202 end
|
bleeck@4
|
203
|
bleeck@4
|
204
|
bleeck@4
|
205 % and return the final result, only highest peak
|
bleeck@4
|
206 peaks2=sortstruct(envpeaks,'v2012_height_base_width_ratio');
|
bleeck@4
|
207 result.free.ps=peaks2{1}.v2012_height_base_width_ratio;
|
bleeck@4
|
208 result.free.fre=1/peaks2{1}.t;
|
bleeck@4
|
209
|
bleeck@4
|
210
|
bleeck@4
|
211
|
bleeck@4
|
212 %
|
bleeck@4
|
213 %
|
bleeck@4
|
214 % % nr 2: height to width of highest peak
|
bleeck@4
|
215 % for i=1:length(envpeaks) % construct all maxima
|
bleeck@4
|
216 % % where=bin2time(smooth_sig,envpeaks{i}.x);
|
bleeck@4
|
217 % where=envpeaks{i}.t;
|
bleeck@4
|
218 % [~,height,breit,where_widths]=qvalue(smooth_sig,where,height_width_ratio);
|
bleeck@4
|
219 % width=time2bin(smooth_sig,breit);
|
bleeck@4
|
220 % if width>0
|
bleeck@4
|
221 % envpeaks{i}.height_width_ratio=height/width;
|
bleeck@4
|
222 % else
|
bleeck@4
|
223 % envpeaks{i}.height_width_ratio=0;
|
bleeck@4
|
224 % end
|
bleeck@4
|
225 % envpeaks{i}.width=width;
|
bleeck@4
|
226 % envpeaks{i}.where_widths=where_widths;
|
bleeck@4
|
227 % envpeaks{i}.peak_base_height_y=height*(1-height_width_ratio);
|
bleeck@4
|
228 % end
|
bleeck@4
|
229 % % and return the results
|
bleeck@4
|
230 % % result.free.height_width_ratio=envpeaks{1}.height_width_ratio;
|
bleeck@4
|
231
|
bleeck@4
|
232 %
|
bleeck@4
|
233 % % nr 3: height of highest / right neigbour (right when time is towards
|
bleeck@4
|
234 % % left, sorry)
|
bleeck@4
|
235 % for i=1:length(envpeaks) % construct all maxima
|
bleeck@4
|
236 % left=envpeaks{i}.left;
|
bleeck@4
|
237 % if isfield(left,'y') && left.y>0
|
bleeck@4
|
238 % envpeaks{i}.neigbouring_ratio=result.free.highest_peak_hight/left.y;
|
bleeck@4
|
239 % else
|
bleeck@4
|
240 % envpeaks{i}.neigbouring_ratio=0;
|
bleeck@4
|
241 % end
|
bleeck@4
|
242 % end
|
bleeck@4
|
243 % result.free.neigbouring_ratio=envpeaks{1}.neigbouring_ratio;
|
bleeck@4
|
244
|
bleeck@4
|
245
|
bleeck@4
|
246 target_frequency=options.ps_options.target_frequency;
|
bleeck@4
|
247 % now find all values for the fixed pitch strengh in target_frequency
|
bleeck@4
|
248 if target_frequency>0 % only, when wanted
|
bleeck@4
|
249 min_fre=target_frequency/options.ps_options.allowed_frequency_deviation;
|
bleeck@4
|
250 max_fre=target_frequency*options.ps_options.allowed_frequency_deviation;
|
bleeck@4
|
251
|
bleeck@4
|
252 for i=1:length(envpeaks) % look through all peaks, which one we need
|
bleeck@4
|
253 fre_peak=1/envpeaks{i}.t;
|
bleeck@4
|
254 if fre_peak > min_fre && fre_peak < max_fre
|
bleeck@4
|
255 % we assume for the moment, that we only have one allowed here
|
bleeck@4
|
256 % nr 1: height
|
bleeck@4
|
257 result.fixed.highest_peak_frequency=fre_peak;
|
bleeck@4
|
258 result.fixed.highest_peak_hight=envpeaks{i}.y;
|
bleeck@4
|
259 result.fixed.height_width_ratio=envpeaks{i}.height_width_ratio;
|
bleeck@4
|
260 result.fixed.neigbouring_ratio=envpeaks{i}.neigbouring_ratio;
|
bleeck@4
|
261 end
|
bleeck@4
|
262 end
|
bleeck@4
|
263 end
|
bleeck@4
|
264
|
bleeck@4
|
265 result.peaks =envpeaks;
|
bleeck@4
|
266
|
bleeck@4
|
267
|
bleeck@4
|
268
|
bleeck@4
|
269 return
|
bleeck@4
|
270
|
bleeck@4
|
271
|
bleeck@4
|
272
|
bleeck@4
|
273
|
bleeck@4
|
274
|
bleeck@4
|
275 % kucke, ob sich das erste Maxima überlappt. Falls ja, nochmal
|
bleeck@4
|
276 % berechnen mit niedriger Lowpass frequenz
|
bleeck@4
|
277 % nr_peaks=length(envpeaks);
|
bleeck@4
|
278 % if nr_peaks==1
|
bleeck@4
|
279 % peak_found=1;
|
bleeck@4
|
280 % continue
|
bleeck@4
|
281 % end
|
bleeck@4
|
282 % xleft=envpeaks{1}.where_widths(1);
|
bleeck@4
|
283 % xright=envpeaks{1}.where_widths(2);
|
bleeck@4
|
284 % for i=2:nr_peaks %
|
bleeck@4
|
285 % xnull=envpeaks{i}.x;
|
bleeck@4
|
286 % if xnull < xleft && xnull > xright
|
bleeck@4
|
287 % peak_found=0;
|
bleeck@4
|
288 % current_lowpass_frequency=current_lowpass_frequency/2;
|
bleeck@4
|
289 % if current_lowpass_frequency<62.5
|
bleeck@4
|
290 % return
|
bleeck@4
|
291 % end
|
bleeck@4
|
292 % break
|
bleeck@4
|
293 % end
|
bleeck@4
|
294 % % wenn noch hier, dann ist alles ok
|
bleeck@4
|
295 % peak_found=1;
|
bleeck@4
|
296 % end
|
bleeck@4
|
297 % end
|
bleeck@4
|
298
|
bleeck@4
|
299
|
bleeck@4
|
300 % reduce the peaks to the relevant ones:
|
bleeck@4
|
301 % through out all with pitchstrength smaller then threshold
|
bleeck@4
|
302 % count=1;
|
bleeck@4
|
303 % min_ps=ps_threshold*envpeaks{1}.pitchstrength;
|
bleeck@4
|
304 % for i=1:length(envpeaks)
|
bleeck@4
|
305 % if envpeaks{i}.pitchstrength>min_ps
|
bleeck@4
|
306 % rpeaks{count}=envpeaks{i};
|
bleeck@4
|
307 % count=count+1;
|
bleeck@4
|
308 % end
|
bleeck@4
|
309 % end
|
bleeck@4
|
310
|
bleeck@4
|
311
|
bleeck@4
|
312 % % final result for the full set
|
bleeck@4
|
313 % result.final_pitchstrength=rpeaks{1}.pitchstrength;
|
bleeck@4
|
314 % result.final_dominant_frequency=rpeaks{1}.fre;
|
bleeck@4
|
315 % result.final_dominant_time=rpeaks{1}.t;
|
bleeck@4
|
316 % result.smoothed_signal=smooth_sig;
|
bleeck@4
|
317 % result.peaks=rpeaks;
|
bleeck@4
|
318 % % return
|
bleeck@4
|
319
|
bleeck@4
|
320 % Neuberechnung der Pitchstrength für peaks, die das Kriterium der
|
bleeck@4
|
321 % Höhe zu Breite nicht erfüllen
|
bleeck@4
|
322 % for i=1:length(rpeaks) % construct all maxima
|
bleeck@4
|
323 % where=bin2time(smooth_sig,rpeaks{i}.x);
|
bleeck@4
|
324 % [dummy,height,breit,where_widths]=qvalue(smooth_sig,where,heighttowidthminimum);
|
bleeck@4
|
325 % width=time2bin(smooth_sig,breit);
|
bleeck@4
|
326 %
|
bleeck@4
|
327 % xleft=where_widths(2);
|
bleeck@4
|
328 % xright=where_widths(1);
|
bleeck@4
|
329 % left_peak=rpeaks{i}.left;
|
bleeck@4
|
330 % right_peak=rpeaks{i}.right;
|
bleeck@4
|
331 %
|
bleeck@4
|
332 %
|
bleeck@4
|
333 % xnull=rpeaks{i}.x;
|
bleeck@4
|
334 % if xleft<left_peak.x || xright>right_peak.x
|
bleeck@4
|
335 % t_xnull=bin2time(smooth_sig,xnull);
|
bleeck@4
|
336 % [val,height,breit,widthvals,base_peak_y]=qvalue2(smooth_sig,t_xnull);
|
bleeck@4
|
337 % width=time2bin(smooth_sig,breit);
|
bleeck@4
|
338 % if width>0
|
bleeck@4
|
339 % rpeaks{i}.pitchstrength=height/width;
|
bleeck@4
|
340 % else
|
bleeck@4
|
341 % rpeaks{i}.pitchstrength=0;
|
bleeck@4
|
342 % end
|
bleeck@4
|
343 % rpeaks{i}.where_widths=time2bin(smooth_sig,widthvals);
|
bleeck@4
|
344 % rpeaks{i}.width=width;
|
bleeck@4
|
345 % rpeaks{i}.peak_base_height_y=base_peak_y;
|
bleeck@4
|
346 % end
|
bleeck@4
|
347 % end
|
bleeck@4
|
348
|
bleeck@4
|
349 % sort again all for the highest first!
|
bleeck@4
|
350 % rpeaks=sortstruct(rpeaks,'pitchstrength');
|
bleeck@4
|
351
|
bleeck@4
|
352 return
|
bleeck@4
|
353
|
bleeck@4
|
354
|
bleeck@4
|
355
|
bleeck@4
|
356
|
bleeck@4
|
357
|
bleeck@4
|
358
|
bleeck@4
|
359
|
bleeck@4
|
360
|
bleeck@4
|
361 %%%%%% look for octave relationships
|
bleeck@4
|
362 %
|
bleeck@4
|
363 %
|
bleeck@4
|
364 for i=1:length(rpeaks) % construct all maxima
|
bleeck@4
|
365 % look, if the octave of the pitch is also present.
|
bleeck@4
|
366 fre=rpeaks{i}.fre;
|
bleeck@4
|
367 has_octave=0;
|
bleeck@4
|
368 for j=1:length(rpeaks)
|
bleeck@4
|
369 oct_fre=rpeaks{j}.fre;
|
bleeck@4
|
370 % is the octave there?
|
bleeck@4
|
371 if oct_fre > (2-octave_variability)*fre && oct_fre < (2+octave_variability)*fre
|
bleeck@4
|
372 rpeaks{i}.has_octave=oct_fre;
|
bleeck@4
|
373 rpeaks{i}.octave_peak_nr=j;
|
bleeck@4
|
374
|
bleeck@4
|
375 % add the pss
|
bleeck@4
|
376 % rpeaks{j}.pitchstrength=rpeaks{i}.pitchstrength+rpeaks{j}.pitchstrength;
|
bleeck@4
|
377
|
bleeck@4
|
378 ps_real=rpeaks{j}.pitchstrength;
|
bleeck@4
|
379 ps_oct=rpeaks{i}.pitchstrength;
|
bleeck@4
|
380 hight_oct=rpeaks{j}.y;
|
bleeck@4
|
381 hight_real=rpeaks{i}.y;
|
bleeck@4
|
382
|
bleeck@4
|
383 % if ps_oct>ps_real && hight_oct > hight_real
|
bleeck@4
|
384 % rpeaks{i}.pitchstrength=ps_real-1; % artificially drop down
|
bleeck@4
|
385 % end
|
bleeck@4
|
386
|
bleeck@4
|
387 has_octave=1;
|
bleeck@4
|
388 break
|
bleeck@4
|
389 end
|
bleeck@4
|
390 if ~has_octave
|
bleeck@4
|
391 rpeaks{i}.has_octave=0;
|
bleeck@4
|
392 rpeaks{i}.octave_peak_nr=0;
|
bleeck@4
|
393 end
|
bleeck@4
|
394 end
|
bleeck@4
|
395 end
|
bleeck@4
|
396
|
bleeck@4
|
397 if plot_switch
|
bleeck@4
|
398 figure(2134)
|
bleeck@4
|
399 clf
|
bleeck@4
|
400 hold on
|
bleeck@4
|
401 plot(log_profile,'b')
|
bleeck@4
|
402 plot(smooth_sig,'g')
|
bleeck@4
|
403 for i=1:length(rpeaks)
|
bleeck@4
|
404 time=rpeaks{i}.t;
|
bleeck@4
|
405 x=rpeaks{i}.x;
|
bleeck@4
|
406 y=rpeaks{i}.y;
|
bleeck@4
|
407 plot(x,y,'Marker','o','Markerfacecolor','g','MarkeredgeColor','g','MarkerSize',2);
|
bleeck@4
|
408 time_left=rpeaks{i}.left.t;
|
bleeck@4
|
409 x_left=rpeaks{i}.left.x;
|
bleeck@4
|
410 y_left=rpeaks{i}.left.y;
|
bleeck@4
|
411 time_right=rpeaks{i}.right.t;
|
bleeck@4
|
412 x_right=rpeaks{i}.right.x;
|
bleeck@4
|
413 y_right=rpeaks{i}.right.y;
|
bleeck@4
|
414 plot(x_left,y_left,'Marker','o','Markerfacecolor','r','MarkeredgeColor','r','MarkerSize',2);
|
bleeck@4
|
415 plot(x_right,y_right,'Marker','o','Markerfacecolor','r','MarkeredgeColor','r','MarkerSize',2);
|
bleeck@4
|
416 end
|
bleeck@4
|
417 current_time=options.current_time*1000;
|
bleeck@4
|
418 y=get(gca,'ylim');
|
bleeck@4
|
419 y=y(2);
|
bleeck@4
|
420 text(700,y,sprintf('%3.0f ms',current_time),'verticalalignment','top');
|
bleeck@4
|
421
|
bleeck@4
|
422 for i=1:length(rpeaks)
|
bleeck@4
|
423 pitchstrength=rpeaks{i}.pitchstrength;
|
bleeck@4
|
424 if i <10
|
bleeck@4
|
425 line([rpeaks{i}.x rpeaks{i}.x],[rpeaks{i}.y rpeaks{i}.peak_base_height_y],'Color','m');
|
bleeck@4
|
426 line([rpeaks{i}.where_widths(1) rpeaks{i}.where_widths(2)],[rpeaks{i}.peak_base_height_y rpeaks{i}.peak_base_height_y],'Color','m');
|
bleeck@4
|
427 x=rpeaks{i}.x;
|
bleeck@4
|
428 fre=rpeaks{i}.fre;
|
bleeck@4
|
429 y=rpeaks{i}.y;
|
bleeck@4
|
430 text(x,y*1.05,sprintf('%3.0fHz: %2.2f',fre,pitchstrength),'HorizontalAlignment','center');
|
bleeck@4
|
431 end
|
bleeck@4
|
432 end
|
bleeck@4
|
433 end
|
bleeck@4
|
434 if plot_switch==1
|
bleeck@4
|
435 for i=1:length(rpeaks)
|
bleeck@4
|
436 x=rpeaks{i}.x;
|
bleeck@4
|
437 y=rpeaks{i}.y;
|
bleeck@4
|
438 plot(x,y,'Marker','o','Markerfacecolor','g','MarkeredgeColor','g','MarkerSize',6);
|
bleeck@4
|
439
|
bleeck@4
|
440 % plot the octaves as green lines
|
bleeck@4
|
441 octave=rpeaks{i}.has_octave;
|
bleeck@4
|
442 fre=rpeaks{i}.fre;
|
bleeck@4
|
443 if octave>0
|
bleeck@4
|
444 oct_nr=rpeaks{i}.octave_peak_nr;
|
bleeck@4
|
445 oct_fre=rpeaks{oct_nr}.fre;
|
bleeck@4
|
446
|
bleeck@4
|
447 x=rpeaks{i}.x;
|
bleeck@4
|
448 oct_x=rpeaks{oct_nr}.x;
|
bleeck@4
|
449 y=rpeaks{i}.y;
|
bleeck@4
|
450 oct_y=rpeaks{oct_nr}.y;
|
bleeck@4
|
451 line([x oct_x],[y oct_y],'Color','g','LineStyle','--');
|
bleeck@4
|
452 end
|
bleeck@4
|
453 end
|
bleeck@4
|
454 end
|
bleeck@4
|
455
|
bleeck@4
|
456 % rpeaks=sortstruct(rpeaks,'pitchstrength');
|
bleeck@4
|
457 rpeaks=sortstruct(rpeaks,'y');
|
bleeck@4
|
458
|
bleeck@4
|
459 % final result for the full set
|
bleeck@4
|
460 result.final_pitchstrength=rpeaks{1}.pitchstrength;
|
bleeck@4
|
461 result.final_dominant_frequency=rpeaks{1}.fre;
|
bleeck@4
|
462 result.final_dominant_time=rpeaks{1}.t;
|
bleeck@4
|
463 result.smoothed_signal=smooth_sig;
|
bleeck@4
|
464 result.peaks=rpeaks;
|
bleeck@4
|
465
|
bleeck@4
|
466
|
bleeck@4
|
467
|
bleeck@4
|
468
|
bleeck@4
|
469 function fre=x2fre(sig,x)
|
bleeck@4
|
470 t_log = bin2time(sig,x);
|
bleeck@4
|
471 t=f2f(t_log,0,0.035,0.001,0.035,'linlog');
|
bleeck@4
|
472 fre=1/t;
|