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