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