Mercurial > hg > aimmat
comparison aim-mat/modules/usermodule/pitchstrength/analyse_timeinterval_profile.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] = analyse_timeinterval_profile(ti_profile, peaks, 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 = analyse_timeinterval_profile(ti_profile,options) | |
17 | |
18 if nargin < 2 | |
19 options=[]; | |
20 end | |
21 | |
22 if isfield(options,'target_frequency') | |
23 end | |
24 | |
25 if ~isfield(options,'options') | |
26 target_frequency=0; | |
27 end | |
28 | |
29 | |
30 % for debug resons | |
31 plot_switch = 1; | |
32 | |
33 | |
34 intsum = ti_profile; | |
35 intsum_vals = getdata(intsum); | |
36 if plot_switch | |
37 minimum_time_interval=0; % in ms | |
38 maximum_time_interval=100; | |
39 figure(654654) | |
40 clf | |
41 tip = intsum_vals; | |
42 tip_x = bin2time(ti_profile, 1:length(tip)); % Get the times | |
43 tip_x = tip_x((tip_x>=(minimum_time_interval/1000)) & tip_x<=(maximum_time_interval/1000)); | |
44 tip = tip(time2bin(ti_profile, tip_x(1)):time2bin(ti_profile, tip_x(end))); | |
45 % tip_x is in ms. Change to Hz | |
46 tip_x = 1./tip_x; | |
47 plot(tip_x, tip, 'b'); | |
48 set(gca,'XScale','log'); | |
49 set(gca,'Ylim', [min(intsum)-10 max(intsum)+10]); | |
50 set(gca,'Xlim', [30 1500]); | |
51 hold on | |
52 end | |
53 if length(peaks)==0 | |
54 % If there is no peak than we just plot the function | |
55 pitchstrength = 0; | |
56 found_frequency = 0; | |
57 return | |
58 end | |
59 | |
60 | |
61 sig=envelope(intsum) | |
62 | |
63 % ++++++++++++ Part one: Peak finding ++++++++++ | |
64 % Calculate the envelope (curve of the peaks) | |
65 | |
66 % sort peaks from low time interval to a heigh one | |
67 % or from left to right | |
68 peaks_lr = sortstruct(peaks,'x'); % | |
69 | |
70 if plot_switch | |
71 px=[];py=[]; | |
72 for i=1:length(peaks) | |
73 px = [px tip_x(peaks{i}.x)]; | |
74 py = [py tip(peaks{i}.x)]; | |
75 end | |
76 plot(px,py,'kx'); | |
77 end | |
78 | |
79 % Create envelope of peaks | |
80 peak_envX = []; | |
81 peak_envY = []; | |
82 for i=1:length(peaks_lr) | |
83 peak_envX = [peak_envX peaks_lr{i}.x]; | |
84 peak_envY = [peak_envY peaks_lr{i}.y]; | |
85 end | |
86 | |
87 if plot_switch | |
88 plot(tip_x(peak_envX), peak_envY, ':k'); | |
89 end | |
90 | |
91 | |
92 % Find Maxima of the envelope | |
93 % create signal | |
94 | |
95 sig=buildfrompoints(sig,xx,yy) | |
96 | |
97 | |
98 peak_envsig = signal(length(peak_envX), 1); | |
99 peak_envsig = setvalues(peak_envsig, peak_envY); | |
100 params = 0; | |
101 peak_env_peaks = PeakPicker(peak_envsig, params); | |
102 % sort peaks of the envelope from low time interval to a heigh one | |
103 % or from left to right | |
104 peaks_env_peaks_lr = sortstruct(peak_env_peaks,'x'); % | |
105 | |
106 if plot_switch | |
107 for i=2:length(peaks_env_peaks_lr) % construct all maxima | |
108 fre=peaks_env_peaks_lr{i}.t; | |
109 plot(fre,gettimevalue(ti_profile,1/fre),'Marker','o','Markerfacecolor','g','MarkeredgeColor','g','MarkerSize',5); | |
110 end | |
111 end | |
112 | |
113 % % Now make sure, that highest peak is not the first peak of envelope | |
114 % peak_oi = peaks{1}; | |
115 % if (peak_oi.x == peak_envX(peaks_env_peaks_lr{1}.x)) | |
116 % % The first Peak is the heighest -> take second highest of envelope | |
117 % if (length(peak_env_peaks)>=2) | |
118 % poix = peak_envX(peak_env_peaks{2}.x); | |
119 % poiy = peak_env_peaks{2}.y; | |
120 % for i=1:length(peaks) | |
121 % if poix==peaks{i}.x | |
122 % peak_oi = peaks{i}; | |
123 % end | |
124 % end | |
125 % end | |
126 % end | |
127 | |
128 | |
129 % Stefans new method: | |
130 % Take the one with the highest contrast | |
131 if length(peaks_env_peaks_lr) > 1 | |
132 for i=2:length(peaks_env_peaks_lr) % construct all maxima | |
133 maxpeak=peaks_env_peaks_lr{i}.y; | |
134 minpeak1=peaks_env_peaks_lr{i}.left.y; | |
135 minpeak2=peaks_env_peaks_lr{i}.right.y; | |
136 minpeak=mean([minpeak1 minpeak2]); | |
137 | |
138 % the definition of pitch strength: Contrast | |
139 % contrast(i)=maxpeak/(mean([minpeak1 minpeak2])); | |
140 | |
141 % the difference between both | |
142 if maxpeak-minpeak > 0 | |
143 contrast(i)=(maxpeak-minpeak)/1000; | |
144 else | |
145 contrast(i)=0; | |
146 end | |
147 if plot_switch | |
148 fre=1/peaks{i}.t; | |
149 plot(fre,gettimevalue(ti_profile,1/fre),'Marker','o','Markerfacecolor','g','MarkeredgeColor','g','MarkerSize',5); | |
150 text(fre,gettimevalue(ti_profile,1/fre)*1.1,sprintf('%2.2f',contrast(i))); | |
151 end | |
152 end | |
153 else % there is only one peak | |
154 maxpeak=peaks{1}.y; | |
155 minpeak1=peaks{1}.left.y; | |
156 minpeak2=peaks{1}.right.y; | |
157 minpeak=mean([minpeak1 minpeak2]); | |
158 if maxpeak-minpeak > 0 | |
159 contrast(1)=(maxpeak-minpeak)/1000; | |
160 else | |
161 contrast(1)=0; | |
162 end | |
163 end | |
164 | |
165 [maxcontrast,wheremax]=max(contrast); | |
166 | |
167 peak_oi=peaks{wheremax}; | |
168 | |
169 pitchstrength= contrast(wheremax); | |
170 found_frequency = 1/peak_oi.t; | |
171 | |
172 if plot_switch | |
173 fre=found_frequency; | |
174 plot(fre,gettimevalue(ti_profile,1/fre),'Marker','o','Markerfacecolor','g','MarkeredgeColor','g','MarkerSize',pitchstrength*10); | |
175 text(fre*1.1,gettimevalue(ti_profile,1/fre)+5, ['highest pitchstrength found at ' num2str(round(fre)) 'Hz: ' num2str(fround(pitchstrength,2)) ],'VerticalAlignment','bottom','HorizontalAlignment','center','color','g','Fontsize',12); | |
176 end | |
177 | |
178 return | |
179 | |
180 | |
181 | |
182 | |
183 % maxpeak=maxstruct(peaks,'y'); | |
184 | |
185 if length(peaks_env_peaks_lr)>1 | |
186 for i=1:length(peaks) | |
187 % If second highes peak==peak with smallest time intervall -> take | |
188 % third highest !! | |
189 if peak_env_peaks{2}.x == peaks_env_peaks_lr{1}.x | |
190 poix = peak_envX(peak_env_peaks{3}.x); | |
191 else | |
192 poix = peak_envX(peak_env_peaks{2}.x); | |
193 end | |
194 if peaks{i}.x==poix | |
195 peak_oi = peaks{i}; | |
196 end | |
197 end | |
198 else | |
199 % pure sinusoid ??? | |
200 dominant_time = 0 | |
201 pitchstrength = 0.001; | |
202 return | |
203 end | |
204 | |
205 | |
206 | |
207 % Stefan's method on HCL | |
208 % Take second peak of envelope from short time intervals | |
209 if length(peaks_env_peaks_lr)>1 | |
210 for i=1:length(peaks) | |
211 % If second highes peak==peak with smallest time intervall -> take | |
212 % third highest !! | |
213 if peak_env_peaks{2}.x == peaks_env_peaks_lr{1}.x | |
214 poix = peak_envX(peak_env_peaks{3}.x); | |
215 else | |
216 poix = peak_envX(peak_env_peaks{2}.x); | |
217 end | |
218 if peaks{i}.x==poix | |
219 peak_oi = peaks{i}; | |
220 end | |
221 end | |
222 else | |
223 % pure sinusoid ??? | |
224 dominant_time = 0 | |
225 pitchstrength = 0.001; | |
226 return | |
227 end | |
228 | |
229 if plot_switch | |
230 plot(tip_x(peak_oi.x), peak_oi.y, 'ro'); | |
231 end | |
232 | |
233 | |
234 | |
235 | |
236 | |
237 % peak_oi contains the peak for quantification | |
238 | |
239 | |
240 % ++++++++++++ Part two: Quantification ++++++++++ | |
241 | |
242 % **** First method | |
243 % pitchstrength is mean of sum / mean of peaks | |
244 % psum = 0; | |
245 % for i = 1:length(peaks) | |
246 % psum = psum+peaks{i}.y; | |
247 % end | |
248 % psum = psum / length(peaks); | |
249 % pitchstrength = psum/peaks{1}.y; | |
250 % dominant_time = peaks{1}.x /getsr(ti_profile); | |
251 % if plot_switch | |
252 % hold off | |
253 % plot(ti_profile); | |
254 % hold on; | |
255 % plot(peaks{1}.x, peaks{1}.y, 'ko'); | |
256 % end | |
257 | |
258 % % ***** Second method | |
259 % % Heigh of neighbour peak / highest peak | |
260 % % First Peaks is the highest as pitchstrength of Peak Picker | |
261 % % Find lower neighbour (with shorter time interval) | |
262 % ioi=1; % index of interest | |
263 % dist = inf; | |
264 % for i=1:length(peaks) | |
265 % d = peak_oi.x - peaks{i}.x; | |
266 % if ((d<dist)&(d>0)) | |
267 % ioi = i; | |
268 % dist = d; | |
269 % end | |
270 % end | |
271 % pitchstrength = peaks{ioi}.y/ peak_oi.y; | |
272 % dominant_time = peak_oi.x /getsr(ti_profile); | |
273 % if plot_switch | |
274 % hold on; | |
275 % plot(peak_oi.x , peak_oi.y , 'ko'); | |
276 % plot(peaks{ioi}.x, peaks{ioi}.y, 'go'); | |
277 % end | |
278 | |
279 % % Third Method: | |
280 % Peak to mean valley ration - good with HCL | |
281 pitchstrength= mean([peak_oi.left.y peak_oi.right.y])/peak_oi.y; | |
282 dominant_time = peak_oi.x /getsr(ti_profile); | |
283 | |
284 % Adaptation | |
285 %pitchstrength = 1-pitchstrength; | |
286 | |
287 % +++++++++++++ Histogram of distances between two peaks ++++++++++ | |
288 | |
289 % | |
290 max_thresh = 1; %0.98; | |
291 % The linear TIP | |
292 | |
293 % Test if all other Peaks ar multiple of the highest peak | |
294 | |
295 % Start with the first peak | |
296 % Test how many peaks are mutiple of the first peak | |
297 %---x---x---x---x---x---x | |
298 % Take first peak of envelope. | |
299 poix = peak_envX(peak_env_peaks{1}.x); | |
300 for i=1:length(peaks_lr) | |
301 if peaks_lr {i}.x==poix | |
302 peak_first = peaks_lr{i}; | |
303 first_i=i; | |
304 end | |
305 end | |
306 nomult = 0; % Number of multible | |
307 max_delta = 0.1; % | |
308 for i=first_i:length(peaks_lr) | |
309 f = peaks_lr{i}.t / peak_first.t; | |
310 if abs(round(f)-f)<max_delta | |
311 nomult=nomult+1; | |
312 end | |
313 end | |
314 nomult; | |
315 | |
316 if plot_switch | |
317 figure(savecf) | |
318 end | |
319 | |
320 %---x---x---x---x---x---x | |
321 | |
322 % is there is a priori information? | |
323 % if (nargin>2) | |
324 % dominant_time = mb(h_index) / getsr(ti_profile); | |
325 % pitchstrength = 0; | |
326 % return | |
327 % end | |
328 | |
329 | |
330 | |
331 % ------------ subfunctions --------------------- | |
332 | |
333 % turns a vector (row) upside down | |
334 function y=upsidedown(x) | |
335 y=[]; | |
336 for i=length(x):-1:1 | |
337 y=[y x(i)]; | |
338 end |