bleeck@4
|
1 % generating function for 'aim-mat'
|
bleeck@4
|
2 %
|
bleeck@4
|
3 % INPUT VALUES:
|
bleeck@4
|
4 %
|
bleeck@4
|
5 % RETURN VALUE:
|
bleeck@4
|
6 %
|
bleeck@4
|
7 %
|
bleeck@4
|
8 % (c) 2003, University of Cambridge, Medical Research Council
|
bleeck@4
|
9 % Christoph Lindner
|
bleeck@4
|
10 % (c) 2011, University of Southampton
|
bleeck@4
|
11 % Maintained by Stefan Bleeck (bleeck@gmail.com)
|
bleeck@4
|
12 % download of current version is on the soundsoftware site:
|
bleeck@4
|
13 % http://code.soundsoftware.ac.uk/projects/aimmat
|
bleeck@4
|
14 % documentation and everything is on http://www.acousticscale.org
|
bleeck@4
|
15
|
bleeck@4
|
16
|
bleeck@4
|
17 function ps_result=genpitchstrength(sai,options)
|
bleeck@4
|
18
|
bleeck@4
|
19 target_frequency=options.target_frequency;
|
bleeck@4
|
20
|
bleeck@4
|
21 if target_frequency > 0
|
bleeck@4
|
22 look_for_target_frequency=1;
|
bleeck@4
|
23 minimum_allowed_frequency=target_frequency/options.allowed_frequency_deviation;
|
bleeck@4
|
24 maximum_allowed_frequency=target_frequency*options.allowed_frequency_deviation;
|
bleeck@4
|
25 else
|
bleeck@4
|
26 look_for_target_frequency=0;
|
bleeck@4
|
27 end
|
bleeck@4
|
28
|
bleeck@4
|
29 if isfield(options,'resolved_harmonic_minimum')
|
bleeck@4
|
30 resolved_harmonic_minimum=options.resolved_harmonic_minimum;
|
bleeck@4
|
31 end
|
bleeck@4
|
32
|
bleeck@4
|
33
|
bleeck@4
|
34 % find out about scaling:
|
bleeck@4
|
35 maxval=-inf;
|
bleeck@4
|
36 maxfreval=-inf;
|
bleeck@4
|
37 maxsumval=-inf;
|
bleeck@4
|
38
|
bleeck@4
|
39 nr_frames=length(sai);
|
bleeck@4
|
40 for ii=1:nr_frames
|
bleeck@4
|
41 maxval=max([maxval getmaximumvalue(sai{ii})]);
|
bleeck@4
|
42 maxsumval=max([maxsumval getscalesumme(sai{ii})]);
|
bleeck@4
|
43 maxfreval=max([maxfreval getscalefrequency(sai{ii})]);
|
bleeck@4
|
44 end
|
bleeck@4
|
45
|
bleeck@4
|
46
|
bleeck@4
|
47 for frame_number=1:nr_frames
|
bleeck@4
|
48 current_frame = sai{frame_number};
|
bleeck@4
|
49 % current_frame = setallmaxvalue(current_frame, maxval);
|
bleeck@4
|
50 frame_start_time(frame_number)=getcurrentframestarttime(current_frame);
|
bleeck@4
|
51 tip(frame_number)=gettimeintervalprofile(current_frame,options);
|
bleeck@4
|
52 end
|
bleeck@4
|
53 frame_duration=frame_start_time(2)-frame_start_time(1);
|
bleeck@4
|
54
|
bleeck@4
|
55 % calculate the averaged tips
|
bleeck@4
|
56 % the first frames are not average, since not long enough time has
|
bleeck@4
|
57 % passed. After that, the relevant last frames are averaged
|
bleeck@4
|
58 tip_time=options.tip_average_time;
|
bleeck@4
|
59 % time for pitch to drop to 1/2 (6dB) --in seconds
|
bleeck@4
|
60 % this means so much per frame
|
bleeck@4
|
61 ps_decay_constant=1-log(2)/(tip_time/frame_duration);
|
bleeck@4
|
62
|
bleeck@4
|
63
|
bleeck@4
|
64 % % and again to sum them up
|
bleeck@4
|
65 % for frame_number=1:nr_frames
|
bleeck@4
|
66 % thisav=mute(tip(frame_number)); % take a copy of the original one
|
bleeck@4
|
67 % figure(1243234)
|
bleeck@4
|
68 % clf
|
bleeck@4
|
69 % hold on
|
bleeck@4
|
70 % count=0;
|
bleeck@4
|
71 % for recent_frames_nr=frame_number-nr_frames_to_average:frame_number
|
bleeck@4
|
72 % if recent_frames_nr > 0
|
bleeck@4
|
73 % thisav=thisav+tip(recent_frames_nr);
|
bleeck@4
|
74 % count=count+1;
|
bleeck@4
|
75 % plot(tip(recent_frames_nr),'g');
|
bleeck@4
|
76 % end
|
bleeck@4
|
77 % end
|
bleeck@4
|
78 % thisav=thisav/count; % the average
|
bleeck@4
|
79 % plot(thisav,'r');
|
bleeck@4
|
80 % average_tip(frame_number)=thisav;
|
bleeck@4
|
81 % end
|
bleeck@4
|
82
|
bleeck@4
|
83 % is it necessary to calculate all, or can we start right at the end?
|
bleeck@4
|
84 % if options.return_only_last==1
|
bleeck@4
|
85 % start_frame=length(sai);
|
bleeck@4
|
86 % else % no we
|
bleeck@4
|
87 start_frame=1;
|
bleeck@4
|
88 % end
|
bleeck@4
|
89
|
bleeck@4
|
90 emptysig=mute(tip(1));
|
bleeck@4
|
91 % mache ein Histogramm für jede Frequenz mit allem Maxima:
|
bleeck@4
|
92 nr_points=getnrpoints(sai{1});
|
bleeck@4
|
93 histo=zeros(1,nr_points);
|
bleeck@4
|
94
|
bleeck@4
|
95 waithand = waitbar(0,'Generating pitch strength');
|
bleeck@4
|
96 for frame_number=start_frame:nr_frames
|
bleeck@4
|
97 % for frame_number=1:10
|
bleeck@4
|
98
|
bleeck@4
|
99 waitbar(frame_number/nr_frames, waithand);
|
bleeck@4
|
100
|
bleeck@4
|
101 current_frame = sai{frame_number};
|
bleeck@4
|
102 current_frame = setallmaxvalue(current_frame, maxval);
|
bleeck@4
|
103 current_frame = setscalesumme(current_frame, maxsumval);
|
bleeck@4
|
104 current_frame = setscalefrequency(current_frame, maxfreval);
|
bleeck@4
|
105
|
bleeck@4
|
106 interval_sig = tip(frame_number);
|
bleeck@4
|
107 % interval_sig = average_tip(frame_number);
|
bleeck@4
|
108 ps_result{frame_number}.frequency_sum = getfrequencysum(current_frame);
|
bleeck@4
|
109 % Normalisation
|
bleeck@4
|
110 interval_sig = interval_sig/getnrpoints( ps_result{frame_number}.frequency_sum);
|
bleeck@4
|
111 ps_result{frame_number}.frequency_sum = ps_result{frame_number}.frequency_sum/getnrpoints(interval_sig)*options.scalefactor;
|
bleeck@4
|
112
|
bleeck@4
|
113 opts.ps_options=options;
|
bleeck@4
|
114 % do all relevant pitch calculations for this frame
|
bleeck@4
|
115 result=find_pitches(interval_sig,opts);
|
bleeck@4
|
116
|
bleeck@4
|
117 ps_result{frame_number}.interval_sum =emptysig;
|
bleeck@4
|
118 ps_result{frame_number}.pitchstrength=0;
|
bleeck@4
|
119
|
bleeck@4
|
120
|
bleeck@4
|
121 % sum all pitches for a histogram
|
bleeck@4
|
122 peaks=result.peaks;
|
bleeck@4
|
123 nr_peaks=length(peaks);
|
bleeck@4
|
124 if nr_peaks>0
|
bleeck@4
|
125 for current_peak=1:nr_peaks
|
bleeck@4
|
126 peak_time=peaks{current_peak}.t;
|
bleeck@4
|
127 peak_x=peaks{current_peak}.x;
|
bleeck@4
|
128 peak_height=peaks{current_peak}.y;
|
bleeck@4
|
129 int_x=round(peak_x);
|
bleeck@4
|
130 histo(int_x)=histo(int_x)+peak_height;
|
bleeck@4
|
131 end
|
bleeck@4
|
132
|
bleeck@4
|
133 shist=signal(histo,getsr(interval_sig));
|
bleeck@4
|
134 shistl=lowpass(shist,400);
|
bleeck@4
|
135 peaks=IPeakPicker(shistl);
|
bleeck@4
|
136
|
bleeck@4
|
137 % ignore the first peak on the left:
|
bleeck@4
|
138 % speaks=sortstruct(peaks,'x');
|
bleeck@4
|
139 % peaks{1}.y=0;
|
bleeck@4
|
140
|
bleeck@4
|
141 speaks=sortstruct(peaks,'y');
|
bleeck@4
|
142
|
bleeck@4
|
143 pitchstrength=speaks{1}.y;
|
bleeck@4
|
144 final_dominant_frequency=1/speaks{1}.t;
|
bleeck@4
|
145 %
|
bleeck@4
|
146 % if mod(frame_number,10)==0
|
bleeck@4
|
147 % figure(43242)
|
bleeck@4
|
148 % if frame_number<30
|
bleeck@4
|
149 % clf;
|
bleeck@4
|
150 % hold on
|
bleeck@4
|
151 % end
|
bleeck@4
|
152 % plot(shist/50);
|
bleeck@4
|
153 % % ax=axis;
|
bleeck@4
|
154 % plot(shistl,'r'); hold on
|
bleeck@4
|
155 % % axis(ax);
|
bleeck@4
|
156 % fre=1/speaks{1}.t;
|
bleeck@4
|
157 % plot(speaks{1}.x,speaks{1}.y,'o','MarkerFaceColor','g','MarkerEdgeColor','w','MarkerSize',10)
|
bleeck@4
|
158 % text(speaks{1}.x,speaks{1}.y,sprintf('%2.0fHz %2.2f',final_dominant_frequency,pitchstrength))
|
bleeck@4
|
159 % for i=2:length(speaks)/2
|
bleeck@4
|
160 % fre=1/speaks{i}.t;
|
bleeck@4
|
161 % plot(speaks{i}.x,speaks{i}.y,'o','MarkerFaceColor','m','MarkerEdgeColor','w','MarkerSize',5)
|
bleeck@4
|
162 % text(speaks{i}.x,speaks{i}.y,sprintf('%2.0fHz %2.2f',fre,speaks{i}.y))
|
bleeck@4
|
163 % end
|
bleeck@4
|
164 % time=frame_number*5;
|
bleeck@4
|
165 % text(speaks{1}.x+400,speaks{1}.y,sprintf('Time: %3.0fms',time));
|
bleeck@4
|
166 % o=0;
|
bleeck@4
|
167 % end
|
bleeck@4
|
168
|
bleeck@4
|
169 ps_result{frame_number}.peaks = speaks;
|
bleeck@4
|
170 ps_result{frame_number}.interval_sum =shistl;
|
bleeck@4
|
171
|
bleeck@4
|
172 if look_for_target_frequency
|
bleeck@4
|
173 count=0;
|
bleeck@4
|
174 for ii=1:length(speaks) % construct all maxima
|
bleeck@4
|
175 fre=1/speaks{ii}.t;
|
bleeck@4
|
176 dist(ii)=abs(target_frequency-fre);
|
bleeck@4
|
177 if fre> minimum_allowed_frequency && fre < maximum_allowed_frequency
|
bleeck@4
|
178 count=count+1;
|
bleeck@4
|
179 allowednumber(count)=ii;
|
bleeck@4
|
180 allowedheights(count)=speaks{ii}.y;
|
bleeck@4
|
181 end
|
bleeck@4
|
182 end
|
bleeck@4
|
183 % [minfredif,nearest_peak_number]=min(dist);
|
bleeck@4
|
184 % fre=1/speaks{nearest_peak_number}.t;
|
bleeck@4
|
185 % is the frequency allowed?
|
bleeck@4
|
186 if count>0
|
bleeck@4
|
187 % if fre< minimum_allowed_frequency || fre > maximum_allowed_frequency
|
bleeck@4
|
188 [highest_ps,best_number]=max(allowedheights);
|
bleeck@4
|
189 best_peak_number=allowednumber(best_number);
|
bleeck@4
|
190
|
bleeck@4
|
191 % gib das Verhältnis der peakstrength zu allen peaks
|
bleeck@4
|
192 % zurück (ohne ihm selbst)
|
bleeck@4
|
193 do_only_relationship=1;
|
bleeck@4
|
194 if do_only_relationship
|
bleeck@4
|
195 count=1;
|
bleeck@4
|
196 for ii=1:length(speaks)
|
bleeck@4
|
197 if ii~=best_peak_number
|
bleeck@4
|
198 allps(count)=speaks{ii}.y;
|
bleeck@4
|
199 count=count+1;
|
bleeck@4
|
200 end
|
bleeck@4
|
201 end
|
bleeck@4
|
202 ps=speaks{best_peak_number}.y/mean(allps);
|
bleeck@4
|
203 ps_result{frame_number}.pitchstrength=ps;
|
bleeck@4
|
204 ps_result{frame_number}.dominant_frequency=1/speaks{best_peak_number}.t;
|
bleeck@4
|
205 else
|
bleeck@4
|
206 ps_result{frame_number}.pitchstrength=speaks{best_peak_number}.y;
|
bleeck@4
|
207 ps_result{frame_number}.dominant_frequency=1/speaks{best_peak_number}.t;
|
bleeck@4
|
208 end
|
bleeck@4
|
209 else % no, nothing there
|
bleeck@4
|
210 % ps_result{frame_number}.interval_sum = result.smoothed_signal;
|
bleeck@4
|
211 ps_result{frame_number}.peaks = [];
|
bleeck@4
|
212 ps_result{frame_number}.dominant_frequency=0;
|
bleeck@4
|
213 ps_result{frame_number}.pitchstrength=0;
|
bleeck@4
|
214 end % frequency allowance
|
bleeck@4
|
215 else % free search was already done!
|
bleeck@4
|
216 ps_result{frame_number}.dominant_frequency=final_dominant_frequency;
|
bleeck@4
|
217 ps_result{frame_number}.pitchstrength=pitchstrength;
|
bleeck@4
|
218 end % look for target frequency
|
bleeck@4
|
219 else % no peaks found
|
bleeck@4
|
220 ps_result{frame_number}.peaks = [];
|
bleeck@4
|
221 ps_result{frame_number}.dominant_frequency=0;
|
bleeck@4
|
222 ps_result{frame_number}.pitchstrength=0;
|
bleeck@4
|
223 end
|
bleeck@4
|
224
|
bleeck@4
|
225 % dynamic decrease of all pitch strengthes
|
bleeck@4
|
226 histo=histo.*ps_decay_constant;
|
bleeck@4
|
227
|
bleeck@4
|
228
|
bleeck@4
|
229 % Peak Picker for FrequencyProfile
|
bleeck@4
|
230 p.dyn_thresh = options.dynamic_threshold_FP;
|
bleeck@4
|
231 p.smooth_sigma = options.smooth_sigma_FP;
|
bleeck@4
|
232 ps_result{frame_number}.peaks_frequency_sum = FPeakPicker(ps_result{frame_number}.frequency_sum, p);
|
bleeck@4
|
233 % ps_result{frame_number}.channel_center_fq = getcf(sai{frame_number});
|
bleeck@4
|
234 ps_result{frame_number}.channel_center_fq = getcf(sai{frame_number});
|
bleeck@4
|
235
|
bleeck@4
|
236 end
|
bleeck@4
|
237 close(waithand);
|
bleeck@4
|
238
|
bleeck@4
|
239
|