annotate aim-mat/modules/usermodule/pitchstrength/genpitchstrength2.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
rev   line source
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