comparison aim-mat/modules/usermodule/pitchstrength/find_pitches2.m @ 4:537f939baef0 tip

various bug fixes and changed copyright message
author Stefan Bleeck <bleeck@gmail.com>
date Tue, 16 Aug 2011 14:37:17 +0100
parents
children
comparison
equal deleted inserted replaced
3:20ada0af3d7d 4:537f939baef0
1 % function [pitchstrength, dominant_time] = find_pitches(profile, , a_priori, fqp_fq)
2 %
3 % To analyse the time interval profile of the auditory image
4 %
5 % INPUT VALUES:
6 %
7 % RETURN VALUE:
8 %
9
10 % (c) 2011, University of Southampton
11 % Maintained by Stefan Bleeck (bleeck@gmail.com)
12 % download of current version is on the soundsoftware site:
13 % http://code.soundsoftware.ac.uk/projects/aimmat
14 % documentation and everything is on http://www.acousticscale.org
15
16 function result = find_pitches(profile,options)
17
18 plot_switch =0;
19
20 if nargin < 2
21 options=[];
22 end
23 %
24
25 % peaks must be higher then this of the maximum to be recognised
26 ps_threshold=0.1;
27 heighttowidthminimum=0.3; % height of peak, where the width is measured
28 octave_variability=0.35; % in percent, when the octave is acepted as such
29
30
31
32 % preliminary return values.
33 result.final_pitchstrength=0;
34 result.final_dominant_frequency=0;
35 result.final_dominant_time=0;
36 result.smoothed_signal=[];
37 result.peaks = [];
38
39 % change the scaling to logarithm, before doing anything else:
40 log_profile=logsigx(profile,0.001,0.035);
41
42
43 peak_found=0;
44 current_lowpass_frequency=500;
45
46 while ~peak_found
47
48 smooth_sig=lowpass(log_profile,current_lowpass_frequency);
49 envpeaks = IPeakPicker(smooth_sig,0.01);
50
51 if isempty(envpeaks) % only, when there is no signal
52 return
53 end
54
55 % finde den peak mit der höchsten Pitschstrength
56 for i=1:length(envpeaks) % construct all maxima
57 where=bin2time(smooth_sig,envpeaks{i}.x);
58 [dummy,height,breit,where_widths]=qvalue(smooth_sig,where,heighttowidthminimum);
59 width=time2bin(smooth_sig,breit);
60 if width>0
61 envpeaks{i}.pitchstrength=height/width;
62 else
63 envpeaks{i}.pitchstrength=0;
64 end
65 envpeaks{i}.width=width;
66 envpeaks{i}.where_widths=where_widths;
67 envpeaks{i}.peak_base_height_y=height*(1-heighttowidthminimum);
68 end
69
70 % sort all for the highest first!
71 % envpeaks=sortstruct(envpeaks,'pitchstrength');
72 envpeaks=sortstruct(envpeaks,'y');
73
74 if plot_switch
75 figure(2134)
76 clf
77 hold on
78 plot(log_profile,'b')
79 plot(smooth_sig,'g')
80 for i=1:length(envpeaks)
81 time=envpeaks{i}.t;
82 x=envpeaks{i}.x;
83 y=envpeaks{i}.y;
84 plot(x,y,'Marker','o','Markerfacecolor','g','MarkeredgeColor','g','MarkerSize',2);
85 time_left=envpeaks{i}.left.t;
86 x_left=envpeaks{i}.left.x;
87 y_left=envpeaks{i}.left.y;
88 time_right=envpeaks{i}.right.t;
89 x_right=envpeaks{i}.right.x;
90 y_right=envpeaks{i}.right.y;
91 plot(x_left,y_left,'Marker','o','Markerfacecolor','r','MarkeredgeColor','r','MarkerSize',2);
92 plot(x_right,y_right,'Marker','o','Markerfacecolor','r','MarkeredgeColor','r','MarkerSize',2);
93 end
94 current_time=options.current_time*1000;
95 y=get(gca,'ylim');
96 y=y(2);
97 text(700,y,sprintf('%3.0f ms',current_time),'verticalalignment','top');
98
99 for i=1:length(envpeaks)
100 pitchstrength=envpeaks{i}.pitchstrength;
101 if i <4
102 line([envpeaks{i}.x envpeaks{i}.x],[envpeaks{i}.y envpeaks{i}.y*(1-heighttowidthminimum)],'Color','r');
103 line([envpeaks{i}.where_widths(1) envpeaks{i}.where_widths(2)],[envpeaks{i}.y*(1-heighttowidthminimum) envpeaks{i}.y*(1-heighttowidthminimum)],'Color','r');
104 x=envpeaks{i}.x;
105 fre=envpeaks{i}.fre;
106 y=envpeaks{i}.y;
107 text(x,y*1.05,sprintf('%3.0fHz: %2.2f',fre,pitchstrength),'HorizontalAlignment','center');
108 end
109 end
110 end
111
112 % kucke, ob sich das erste Maxima überlappt. Falls ja, nochmal
113 % berechnen mit niedriger Lowpass frequenz
114 nr_peaks=length(envpeaks);
115 if nr_peaks==1
116 peak_found=1;
117 continue
118 end
119 xleft=envpeaks{1}.where_widths(1);
120 xright=envpeaks{1}.where_widths(2);
121 for i=2:nr_peaks %
122 xnull=envpeaks{i}.x;
123 if xnull < xleft && xnull > xright
124 peak_found=0;
125 current_lowpass_frequency=current_lowpass_frequency/2;
126 if current_lowpass_frequency<62.5
127 return
128 end
129 break
130 end
131 % wenn noch hier, dann ist alles ok
132 peak_found=1;
133 end
134 end
135
136
137 % reduce the peaks to the relevant ones:
138 % through out all with pitchstrength smaller then threshold
139 count=1;
140 min_ps=ps_threshold*envpeaks{1}.pitchstrength;
141 for i=1:length(envpeaks)
142 if envpeaks{i}.pitchstrength>min_ps
143 rpeaks{count}=envpeaks{i};
144 count=count+1;
145 end
146 end
147
148
149 % final result for the full set
150 result.final_pitchstrength=rpeaks{1}.pitchstrength;
151 result.final_dominant_frequency=rpeaks{1}.fre;
152 result.final_dominant_time=rpeaks{1}.t;
153 result.smoothed_signal=smooth_sig;
154 result.peaks=rpeaks;
155 % return
156
157 % Neuberechnung der Pitchstrength für peaks, die das Kriterium der
158 % Höhe zu Breite nicht erfüllen
159 for i=1:length(rpeaks) % construct all maxima
160 where=bin2time(smooth_sig,rpeaks{i}.x);
161 [dummy,height,breit,where_widths]=qvalue(smooth_sig,where,heighttowidthminimum);
162 width=time2bin(smooth_sig,breit);
163
164 xleft=where_widths(2);
165 xright=where_widths(1);
166 left_peak=rpeaks{i}.left;
167 right_peak=rpeaks{i}.right;
168
169
170 xnull=rpeaks{i}.x;
171 if xleft<left_peak.x || xright>right_peak.x
172 t_xnull=bin2time(smooth_sig,xnull);
173 [val,height,breit,widthvals,base_peak_y]=qvalue2(smooth_sig,t_xnull);
174 width=time2bin(smooth_sig,breit);
175 if width>0
176 rpeaks{i}.pitchstrength=height/width;
177 else
178 rpeaks{i}.pitchstrength=0;
179 end
180 rpeaks{i}.where_widths=time2bin(smooth_sig,widthvals);
181 rpeaks{i}.width=width;
182 rpeaks{i}.peak_base_height_y=base_peak_y;
183 end
184 end
185
186 % sort again all for the highest first!
187 % rpeaks=sortstruct(rpeaks,'pitchstrength');
188
189 % return
190 %%%%%% look for octave relationships
191 %
192 %
193 for i=1:length(rpeaks) % construct all maxima
194 % look, if the octave of the pitch is also present.
195 fre=rpeaks{i}.fre;
196 has_octave=0;
197 for j=1:length(rpeaks)
198 oct_fre=rpeaks{j}.fre;
199 % is the octave there?
200 if oct_fre > (2-octave_variability)*fre && oct_fre < (2+octave_variability)*fre
201 rpeaks{i}.has_octave=oct_fre;
202 rpeaks{i}.octave_peak_nr=j;
203
204 % add the pss
205 % rpeaks{j}.pitchstrength=rpeaks{i}.pitchstrength+rpeaks{j}.pitchstrength;
206
207 ps_real=rpeaks{j}.pitchstrength;
208 ps_oct=rpeaks{i}.pitchstrength;
209 hight_oct=rpeaks{j}.y;
210 hight_real=rpeaks{i}.y;
211
212 % if ps_oct>ps_real && hight_oct > hight_real
213 % rpeaks{i}.pitchstrength=ps_real-1; % artificially drop down
214 % end
215
216 has_octave=1;
217 break
218 end
219 if ~has_octave
220 rpeaks{i}.has_octave=0;
221 rpeaks{i}.octave_peak_nr=0;
222 end
223 end
224 end
225
226 if plot_switch
227 figure(2134)
228 clf
229 hold on
230 plot(log_profile,'b')
231 plot(smooth_sig,'g')
232 for i=1:length(rpeaks)
233 time=rpeaks{i}.t;
234 x=rpeaks{i}.x;
235 y=rpeaks{i}.y;
236 plot(x,y,'Marker','o','Markerfacecolor','g','MarkeredgeColor','g','MarkerSize',2);
237 time_left=rpeaks{i}.left.t;
238 x_left=rpeaks{i}.left.x;
239 y_left=rpeaks{i}.left.y;
240 time_right=rpeaks{i}.right.t;
241 x_right=rpeaks{i}.right.x;
242 y_right=rpeaks{i}.right.y;
243 plot(x_left,y_left,'Marker','o','Markerfacecolor','r','MarkeredgeColor','r','MarkerSize',2);
244 plot(x_right,y_right,'Marker','o','Markerfacecolor','r','MarkeredgeColor','r','MarkerSize',2);
245 end
246 current_time=options.current_time*1000;
247 y=get(gca,'ylim');
248 y=y(2);
249 text(700,y,sprintf('%3.0f ms',current_time),'verticalalignment','top');
250
251 for i=1:length(rpeaks)
252 pitchstrength=rpeaks{i}.pitchstrength;
253 if i <10
254 line([rpeaks{i}.x rpeaks{i}.x],[rpeaks{i}.y rpeaks{i}.peak_base_height_y],'Color','m');
255 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');
256 x=rpeaks{i}.x;
257 fre=rpeaks{i}.fre;
258 y=rpeaks{i}.y;
259 text(x,y*1.05,sprintf('%3.0fHz: %2.2f',fre,pitchstrength),'HorizontalAlignment','center');
260 end
261 end
262 end
263 if plot_switch==1
264 for i=1:length(rpeaks)
265 x=rpeaks{i}.x;
266 y=rpeaks{i}.y;
267 plot(x,y,'Marker','o','Markerfacecolor','g','MarkeredgeColor','g','MarkerSize',6);
268
269 % plot the octaves as green lines
270 octave=rpeaks{i}.has_octave;
271 fre=rpeaks{i}.fre;
272 if octave>0
273 oct_nr=rpeaks{i}.octave_peak_nr;
274 oct_fre=rpeaks{oct_nr}.fre;
275
276 x=rpeaks{i}.x;
277 oct_x=rpeaks{oct_nr}.x;
278 y=rpeaks{i}.y;
279 oct_y=rpeaks{oct_nr}.y;
280 line([x oct_x],[y oct_y],'Color','g','LineStyle','--');
281 end
282 end
283 end
284
285 % rpeaks=sortstruct(rpeaks,'pitchstrength');
286 rpeaks=sortstruct(rpeaks,'y');
287
288 % final result for the full set
289 result.final_pitchstrength=rpeaks{1}.pitchstrength;
290 result.final_dominant_frequency=rpeaks{1}.fre;
291 result.final_dominant_time=rpeaks{1}.t;
292 result.smoothed_signal=smooth_sig;
293 result.peaks=rpeaks;
294
295
296
297
298 function fre=x2fre(sig,x)
299 t_log = bin2time(sig,x);
300 t=f2f(t_log,0,0.035,0.001,0.035,'linlog');
301 fre=1/t;