annotate aim-mat/gui/adaptedspecgramdemo.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 20ada0af3d7d
children
rev   line source
tomwalters@0 1 function out=adaptedspecgramdemo(y,Fs,t_min,t_max)
tomwalters@0 2 %SPECGRAMDEMO Spectrogram Demo
tomwalters@0 3 % SPECGRAMDEMO(y,Fs) displays a spectrogram of signal y, assuming
tomwalters@0 4 % a sample rate of Fs Hz. If y is specified but Fs is not,
tomwalters@0 5 % a sample rate of 1 Hz is assumed. If no input arguments
tomwalters@0 6 % are supplied, y and Fs are taken from the default data file
tomwalters@0 7 % "mtlb.mat."
tomwalters@0 8 %
tomwalters@0 9 % Context menus and context-sensitive help are enabled throughout
tomwalters@0 10 % the GUI. Explore the visualization options by right-clicking
tomwalters@0 11 % on various GUI items including the spectrogram, the colorbar,
tomwalters@0 12 % etc. For example, the panner may be zoomed by dragging the
tomwalters@0 13 % mouse on the left- and right-hand edges of the highlighted
tomwalters@0 14 % zoom region. Right-clicking the highlighted zoom area brings
tomwalters@0 15 % up a menu for focusing in on the zoom region, and provides
tomwalters@0 16 % a link to context help.
tomwalters@0 17 %
tomwalters@0 18 % See also SPECGRAM, SPTOOL, FDATOOL.
tomwalters@0 19
tomwalters@0 20 % Author: D. Orofino
tomwalters@0 21 % Copyright 1988-2002 The MathWorks, Inc.
tomwalters@0 22 % $orginal Revision: 1.11 $ $orginal Date: 2002/05/17 14:17:56 $
tomwalters@0 23 %
tomwalters@0 24 %
tomwalters@0 25 % adapted by Stefan Bleeck 5.3.2003 to give back the selected time.
bleeck@3 26 % bleeck@gmail.com
tomwalters@0 27
tomwalters@0 28 %%%%%%%%%%%%%%%%%%%%%%%%%%
tomwalters@0 29 % inserted by S.Bleeck
tomwalters@0 30 global tmin;
tomwalters@0 31 global tmax;
tomwalters@0 32 if nargin<4
tomwalters@0 33 t_max=length(y)/Fs;
tomwalters@0 34 end
tomwalters@0 35 if nargin<3
tomwalters@0 36 t_min=0;
tomwalters@0 37 end
tomwalters@0 38 tmin=0;
tomwalters@0 39 tmax=length(y);
tomwalters@0 40 %%%%%%%%%%%%%%%%%%%%%%%%%%
tomwalters@0 41
tomwalters@0 42 if nargin<1,
tomwalters@0 43 default_file = 'mtlb.mat';
tomwalters@0 44 fprintf(['Loading demo file (%s).\n\n'],default_file);
tomwalters@0 45 s = load(default_file);
tomwalters@0 46 y = s.mtlb; % default dataset
tomwalters@0 47 Fs = s.Fs;
tomwalters@0 48 elseif nargin<2,
tomwalters@0 49 Fs=1; % default sample rate
tomwalters@0 50 end
tomwalters@0 51
tomwalters@0 52 create_gui(y,Fs,t_min,t_max);
tomwalters@0 53
tomwalters@0 54
tomwalters@0 55 %%%%%%%%%%%%%%%%%%%%%%%%%%
tomwalters@0 56 % inserted by S.Bleeck
tomwalters@0 57 out.start=tmin/Fs;
tomwalters@0 58 out.duration=tmax/Fs-tmin/Fs;
tomwalters@0 59 %%%%%%%%%%%%%%%%%%%%%%%%%%
tomwalters@0 60
tomwalters@0 61
tomwalters@0 62
tomwalters@0 63 %---------------------------------------------------------------
tomwalters@0 64 function zoom_in(hco,eventStruct,hfig)
tomwalters@0 65
tomwalters@0 66 if nargin<3, hfig=gcbf; end
tomwalters@0 67
tomwalters@0 68 ud = get(hfig,'userdata');
tomwalters@0 69
tomwalters@0 70 % Get "pixel spacing" of image content
tomwalters@0 71 im_xdata = get(ud.himage,'xdata');
tomwalters@0 72 im_dx = im_xdata(2)-im_xdata(1);
tomwalters@0 73
tomwalters@0 74 % Get current axis limit
tomwalters@0 75 xlim = get(ud.hax(1),'xlim');
tomwalters@0 76 xlim_ctr = sum(xlim)/2;
tomwalters@0 77 dxlim = diff(xlim);
tomwalters@0 78
tomwalters@0 79 % If current axis limits will only show 1 pixel width,
tomwalters@0 80 % don't bother zooming in any further:
tomwalters@0 81 if dxlim <= im_dx, return; end
tomwalters@0 82
tomwalters@0 83 % Shrink limits 50% toward center of current limits:
tomwalters@0 84 new_xlim = (xlim + xlim_ctr)/2;
tomwalters@0 85 % Update the spectrogram and time slice axes:
tomwalters@0 86 set(ud.hax(1),'xlim',new_xlim); % [1 3] xxxx
tomwalters@0 87
tomwalters@0 88 % Update the thumbnail:
tomwalters@0 89 set(ud.hthumb,'xdata',new_xlim([1 2 2 1 1]));
tomwalters@0 90
tomwalters@0 91 % update the audio selection to be played
tomwalters@0 92 set_audio_selection(hfig, new_xlim * ud.Fs);
tomwalters@0 93
tomwalters@0 94 % Update zoom signal, if enabled:
tomwalters@0 95 % xxx plot_signal_zoom(hfig);
tomwalters@0 96
tomwalters@0 97 %---------------------------------------------------------------
tomwalters@0 98 function zoom_out(hco,eventStruct,hfig)
tomwalters@0 99
tomwalters@0 100 % Zooming is relative to the current focus window
tomwalters@0 101 % We will not zoom out beyond the current focus window
tomwalters@0 102
tomwalters@0 103 if nargin<3, hfig=gcbf; end
tomwalters@0 104 ud = get(hfig,'userdata');
tomwalters@0 105
tomwalters@0 106 % Get current spectrogram axis limit (= thumbnail limits)
tomwalters@0 107 thumb_xlim = get(ud.hax(1),'xlim'); % thumb limits = spectrogram limits
tomwalters@0 108 thumb_dx = diff(thumb_xlim);
tomwalters@0 109
tomwalters@0 110 % If spectrogram axis limits >= focus window limits,
tomwalters@0 111 % don't bother zooming out any further:
tomwalters@0 112 hax_time = ud.hax(2);
tomwalters@0 113 focus_xlim = get(hax_time,'xlim'); % = panner xlim
tomwalters@0 114 focus_dx = focus_xlim(2)-focus_xlim(1);
tomwalters@0 115 if thumb_dx >= focus_dx, return; end
tomwalters@0 116
tomwalters@0 117 % Grow limits 50% away from center of current limits:
tomwalters@0 118 new_xlim = thumb_xlim + [-thumb_dx thumb_dx]/2;
tomwalters@0 119 if new_xlim(1)<focus_xlim(1), new_xlim(1)=focus_xlim(1); end
tomwalters@0 120 if new_xlim(2)>focus_xlim(2), new_xlim(2)=focus_xlim(2); end
tomwalters@0 121
tomwalters@0 122 % Update the thumbnail:
tomwalters@0 123 set(ud.hthumb,'xdata',new_xlim([1 2 2 1 1]));
tomwalters@0 124
tomwalters@0 125 % Sync the spectrogram and time slice axes to the thumbnail:
tomwalters@0 126 set(ud.hax(1),'xlim',new_xlim); % [1 3] xxxx
tomwalters@0 127
tomwalters@0 128 % update the audio selection to be played
tomwalters@0 129 set_audio_selection(hfig, new_xlim * ud.Fs);
tomwalters@0 130
tomwalters@0 131 % Update zoom signal, if enabled:
tomwalters@0 132 % xxx plot_signal_zoom(hfig);
tomwalters@0 133
tomwalters@0 134 %---------------------------------------------------------------
tomwalters@0 135 function zoom_full(hco,eventStruct,hfig)
tomwalters@0 136
tomwalters@0 137 if nargin<3, hfig=gcbf; end
tomwalters@0 138 ud = get(hfig,'userdata');
tomwalters@0 139
tomwalters@0 140 focusTimeReset(hfig); % reset focus window to full extent
tomwalters@0 141
tomwalters@0 142 % Get time range of full spectrogram
tomwalters@0 143 im_xdata = get(ud.himage,'xdata');
tomwalters@0 144
tomwalters@0 145 % Grow limits 50% away from center of current limits:
tomwalters@0 146 new_xlim(1)=im_xdata(1);
tomwalters@0 147 new_xlim(2)=im_xdata(end);
tomwalters@0 148
tomwalters@0 149 % Update the spectrogram and time slice axes:
tomwalters@0 150 set(ud.hax([1 3]),'xlim',new_xlim);
tomwalters@0 151
tomwalters@0 152 % Update the thumbnail:
tomwalters@0 153 set(ud.hthumb,'xdata',new_xlim([1 2 2 1 1]));
tomwalters@0 154
tomwalters@0 155 % update the audio selection to be played
tomwalters@0 156 set_audio_selection(hfig, new_xlim * ud.Fs);
tomwalters@0 157
tomwalters@0 158 % Update zoom signal, if enabled:
tomwalters@0 159 % xxx plot_signal_zoom(hfig);
tomwalters@0 160
tomwalters@0 161 %---------------------------------------------------------------
tomwalters@0 162 function top_plot_toggle
tomwalters@0 163
tomwalters@0 164 % XXX UNUSED?
tomwalters@0 165
tomwalters@0 166 hfig=gcbf;
tomwalters@0 167 ud=get(hfig,'userdata');
tomwalters@0 168
tomwalters@0 169 if strcmp(ud.plot.top,'spectrogram_time_slice'),
tomwalters@0 170 newMode='signal_zoom';
tomwalters@0 171 else
tomwalters@0 172 newMode='spectrogram_time_slice';
tomwalters@0 173 end
tomwalters@0 174 ud.plot.top=newMode;
tomwalters@0 175 set(hfig,'userdata',ud);
tomwalters@0 176
tomwalters@0 177 hax_tslice = ud.hax(3);
tomwalters@0 178
tomwalters@0 179 if strcmp(newMode,'signal_zoom'),
tomwalters@0 180 t = (0:length(ud.y)-1)/ud.Fs;
tomwalters@0 181 set(ud.htslice_line,'xdata',t, 'ydata', ud.y);
tomwalters@0 182 set(hax_tslice,'xlim',[0 max(t)],'ylimmode','auto');
tomwalters@0 183 else
tomwalters@0 184 % xxx
tomwalters@0 185 set(ud.htslice_line,'ydata', get_spec_tslice(hfig), ...
tomwalters@0 186 'xdata',ud.t);
tomwalters@0 187
tomwalters@0 188 b = get(ud.himage,'cdata');
tomwalters@0 189 blim = [min(b(:)) max(b(:))];
tomwalters@0 190 spec_xlim = [0 max(ud.t)];
tomwalters@0 191 set(hax_tslice, 'xlim',spec_xlim, 'ylim',blim);
tomwalters@0 192 end
tomwalters@0 193
tomwalters@0 194 % Update the top plot (Time slice)
tomwalters@0 195 %update_top_plot(hfig);
tomwalters@0 196
tomwalters@0 197 %---------------------------------------------------------------
tomwalters@0 198 function left_plot_toggle
tomwalters@0 199 % Define the newMode flag in ud.plot.left
tomwalters@0 200
tomwalters@0 201 hfig = gcbf;
tomwalters@0 202 ud = get(hfig,'userdata');
tomwalters@0 203
tomwalters@0 204 if strcmp(ud.plot.left,'spectrogram_freq_slice'),
tomwalters@0 205 newMode = 'signal_psd';
tomwalters@0 206 else
tomwalters@0 207 newMode = 'spectrogram_freq_slice';
tomwalters@0 208 end
tomwalters@0 209 ud.plot.left = newMode;
tomwalters@0 210 set(hfig,'userdata',ud);
tomwalters@0 211
tomwalters@0 212 % Update the left plot (Frequency slice and PSD)
tomwalters@0 213 update_left_plot(hfig);
tomwalters@0 214
tomwalters@0 215 %---------------------------------------------------------------
tomwalters@0 216 function set_crosshairs(hfig,x,y)
tomwalters@0 217
tomwalters@0 218 % Get current point in axis ASAP:
tomwalters@0 219 %hfig = gcbf;
tomwalters@0 220 ud = get(hfig,'userdata');
tomwalters@0 221
tomwalters@0 222 % Update cache
tomwalters@0 223 ud.crosshair.xctr = x;
tomwalters@0 224 if nargin == 3,
tomwalters@0 225 ud.crosshair.yctr = y;
tomwalters@0 226 else
tomwalters@0 227 y = ud.crosshair.yctr;
tomwalters@0 228 end
tomwalters@0 229 set(hfig,'userdata',ud);
tomwalters@0 230
tomwalters@0 231 % Update crosshairs
tomwalters@0 232 set([ud.hspec_y ud.htime_y ud.htslice_y], 'xdata',[x x]);
tomwalters@0 233 set([ud.hspec_x ud.hfreq_x], 'ydata',[y y]);
tomwalters@0 234
tomwalters@0 235 % Update readouts
tomwalters@0 236 update_time_readout(hfig);
tomwalters@0 237 update_freq_readout(hfig);
tomwalters@0 238 update_dB_readout(hfig);
tomwalters@0 239 update_cmap_ptr(hfig);
tomwalters@0 240
tomwalters@0 241 % For the VERTICAL and H/V crosshairs,
tomwalters@0 242 % update the freq slice display:
tomwalters@0 243 if strcmp(ud.plot.left,'spectrogram_freq_slice'),
tomwalters@0 244 set(ud.hfreq_line,'xdata', get_spec_freq(hfig));
tomwalters@0 245 end
tomwalters@0 246
tomwalters@0 247 % For the HORIZONTAL and H/V crosshairs,
tomwalters@0 248 % update the time slice display:
tomwalters@0 249 if strcmp(ud.plot.top,'spectrogram_time_slice'),
tomwalters@0 250 set(ud.htslice_line,'ydata', get_spec_tslice(hfig));
tomwalters@0 251 end
tomwalters@0 252
tomwalters@0 253 %---------------------------------------------------------------
tomwalters@0 254 function center_cross(hco,eventStruct)
tomwalters@0 255
tomwalters@0 256 hfig = gcbf;
tomwalters@0 257 ud = get(hfig,'userdata');
tomwalters@0 258
tomwalters@0 259 % Determine center of spectrogram axis:
tomwalters@0 260 xlim=get(ud.hax(1),'xlim');
tomwalters@0 261 ylim=get(ud.hax(1),'ylim');
tomwalters@0 262
tomwalters@0 263 set_crosshairs(hfig,mean(xlim),mean(ylim));
tomwalters@0 264 update_cmap_ptr(hfig);
tomwalters@0 265
tomwalters@0 266 %---------------------------------------------------------------
tomwalters@0 267 function wbmotion_thumb(hco,eventStruct)
tomwalters@0 268 % thumbnail motion
tomwalters@0 269
tomwalters@0 270 % Get current point in axis ASAP:
tomwalters@0 271 hfig = gcbf;
tomwalters@0 272 ud = get(hfig,'userdata');
tomwalters@0 273 hax = ud.hax(2);
tomwalters@0 274 cp = get(hax,'currentpoint');
tomwalters@0 275 curr_x = cp(1,1);
tomwalters@0 276
tomwalters@0 277 xdata = get(ud.hthumb,'xdata');
tomwalters@0 278 xmotion = curr_x - ud.thumb.origPt;
tomwalters@0 279 width = ud.thumb.width;
tomwalters@0 280 xdata = ud.thumb.xdata + xmotion;
tomwalters@0 281
tomwalters@0 282 % Constrain to axis limits, so we don't lose cursor:
tomwalters@0 283 xlim=get(hax,'xlim');
tomwalters@0 284 min_xdata = min(xdata);
tomwalters@0 285 max_xdata = max(xdata);
tomwalters@0 286 if min_xdata < xlim(1),
tomwalters@0 287 xdata=[xlim(1) xlim([1 1])+width xlim([1 1])];
tomwalters@0 288 elseif max_xdata > xlim(2),
tomwalters@0 289 xdata = [xlim(2)-width xlim([2 2]) xlim([2 2])-width];
tomwalters@0 290 end
tomwalters@0 291
tomwalters@0 292 % If the patch is larger than the zoom window
tomwalters@0 293 if min(xdata)<=xlim(1) & max(xdata)>=xlim(2),
tomwalters@0 294 % error('wbmotion_thumb: xdata is out of bounds');
tomwalters@0 295 return
tomwalters@0 296 end
tomwalters@0 297
tomwalters@0 298 % Update the thumbnail:
tomwalters@0 299 set(ud.hthumb,'xdata',xdata);
tomwalters@0 300
tomwalters@0 301 % Scroll the spectrogram and time-slice axes:
tomwalters@0 302 % xxxx
tomwalters@0 303 set(ud.hax([1]),'xlim',xdata(1:2)); % [1 3] xxx
tomwalters@0 304
tomwalters@0 305 % update the audio selection to be played
tomwalters@0 306 set_audio_selection(hfig, xdata(1:2) * ud.Fs);
tomwalters@0 307
tomwalters@0 308 %if strcmp(ud.plot.top,'spectrogram_time_slice'),
tomwalters@0 309 % set(ud.htslice_line,'ydata', get_spec_tslice(hfig)); % xxxx
tomwalters@0 310 %end
tomwalters@0 311
tomwalters@0 312 %---------------------------------------------------------------
tomwalters@0 313 function wbmotion_thumbleft(hco,eventStruct)
tomwalters@0 314 % thumbnail LEFT motion
tomwalters@0 315
tomwalters@0 316 % Get current point in axis ASAP:
tomwalters@0 317 hfig = gcbf;
tomwalters@0 318 ud = get(hfig,'userdata');
tomwalters@0 319
tomwalters@0 320 % current object may be either the patch, or the signal line
tomwalters@0 321 hax = ud.hax(2);
tomwalters@0 322 cp = get(hax,'currentpoint');
tomwalters@0 323 curr_x = cp(1,1);
tomwalters@0 324
tomwalters@0 325 xdata = get(ud.hthumb,'xdata');
tomwalters@0 326 xmotion = curr_x - ud.thumb.origPt;
tomwalters@0 327 width = ud.thumb.width;
tomwalters@0 328 xdata = ud.thumb.xdata;
tomwalters@0 329 xdata([1 4 5]) = xdata([1 4 5]) + xmotion;
tomwalters@0 330
tomwalters@0 331 % Constrain to axis limits, so we don't lose cursor:
tomwalters@0 332 xlim = get(hax,'xlim');
tomwalters@0 333 min_xdata = min(xdata);
tomwalters@0 334 if min_xdata < xlim(1),
tomwalters@0 335 xdata=[xlim(1) xdata([2 3])' xlim([1 1])];
tomwalters@0 336 elseif min_xdata >= xdata(2),
tomwalters@0 337 xdata = ud.thumb.xdata;
tomwalters@0 338 end
tomwalters@0 339
tomwalters@0 340 % Update the thumbnail:
tomwalters@0 341 set(ud.hthumb,'xdata',xdata);
tomwalters@0 342
tomwalters@0 343 % Scroll the spectrogram:
tomwalters@0 344 set(ud.hax(1),'xlim',xdata(1:2));
tomwalters@0 345
tomwalters@0 346 % update the audio selection to be played
tomwalters@0 347 set_audio_selection(hfig, xdata(1:2) * ud.Fs);
tomwalters@0 348
tomwalters@0 349 %---------------------------------------------------------------
tomwalters@0 350 function wbmotion_thumbright(hco,eventStruct)
tomwalters@0 351 % thumbnail RIGHT motion
tomwalters@0 352
tomwalters@0 353 % Get current point in axis ASAP:
tomwalters@0 354 hfig = gcbf;
tomwalters@0 355 ud = get(hfig,'userdata');
tomwalters@0 356
tomwalters@0 357 hax = ud.hax(2);
tomwalters@0 358 cp = get(hax,'currentpoint');
tomwalters@0 359 curr_x = cp(1,1);
tomwalters@0 360
tomwalters@0 361 xdata = get(ud.hthumb,'xdata');
tomwalters@0 362 xmotion = curr_x - ud.thumb.origPt;
tomwalters@0 363 width = ud.thumb.width;
tomwalters@0 364 xdata = ud.thumb.xdata;
tomwalters@0 365 xdata([2 3]) = xdata([2 3]) + xmotion;
tomwalters@0 366
tomwalters@0 367 % Constrain to axis limits, so we don't lose cursor:
tomwalters@0 368 xlim = get(hax,'xlim');
tomwalters@0 369 max_xdata = max(xdata);
tomwalters@0 370 if max_xdata > xlim(2),
tomwalters@0 371 xdata([2:3]) = xlim(2);
tomwalters@0 372 elseif max_xdata <= xdata(1),
tomwalters@0 373 xdata = ud.thumb.xdata;
tomwalters@0 374 end
tomwalters@0 375
tomwalters@0 376 % Update the thumbnail:
tomwalters@0 377 set(ud.hthumb,'xdata',xdata);
tomwalters@0 378
tomwalters@0 379 % Scroll the spectrogram:
tomwalters@0 380 set(ud.hax(1),'xlim',xdata(1:2));
tomwalters@0 381
tomwalters@0 382 % update the audio selection to be played
tomwalters@0 383 set_audio_selection(hfig, xdata(1:2) * ud.Fs);
tomwalters@0 384
tomwalters@0 385 %---------------------------------------------------------------
tomwalters@0 386 function wbup_thumb(hco,eventStruct)
tomwalters@0 387
tomwalters@0 388 % set spectrogram and time-slice xlims
tomwalters@0 389 hfig = gcbf;
tomwalters@0 390 ud = get(hfig,'userdata');
tomwalters@0 391 xdata = get(ud.hthumb,'xdata');
tomwalters@0 392 xlim = [min(xdata) max(xdata)];
tomwalters@0 393
tomwalters@0 394 % Commented out, due to flash:
tomwalters@0 395 %set(ud.hax([1 3]),'xlim',xlim);
tomwalters@0 396 %
tomwalters@0 397 % This is fine:
tomwalters@0 398 %set(ud.hax(1),'xlim',xlim);
tomwalters@0 399 %
tomwalters@0 400 % xxx the following line causes flash in the spect image
tomwalters@0 401 % this is the time-slice axis:
tomwalters@0 402 % xxx xxx BAD NEWS!
tomwalters@0 403 % why does this affect the spectrogram axis? (overlap? clipping?)
tomwalters@0 404 %set(ud.hax(3),'xlim',xlim);
tomwalters@0 405
tomwalters@0 406 changePtr(gcbf,'hand');
tomwalters@0 407 install_cursorfcns(gcbf,'thumb');
tomwalters@0 408
tomwalters@0 409 % Turn back on image axis visibility,
tomwalters@0 410 % which was turned off during wbdown_thumb
tomwalters@0 411 % so that it does not flash while panning:
tomwalters@0 412 % xxx
tomwalters@0 413 % Leave off!
tomwalters@0 414 %set(ud.hax(1),'vis','on');
tomwalters@0 415 %
tomwalters@0 416 % Turn on crosshair visibility, which was shut off
tomwalters@0 417 % during thumbnail panning (wbdown_thumb):
tomwalters@0 418 set([ud.hspec_y ud.hspec_x ud.htslice_y],'vis','on');
tomwalters@0 419
tomwalters@0 420 %---------------------------------------------------------------
tomwalters@0 421 function wbup_thumbleft(hco,eventStruct)
tomwalters@0 422 % set spectrogram and time-slice xlims
tomwalters@0 423 hfig = gcbf;
tomwalters@0 424 ud = get(hfig,'userdata');
tomwalters@0 425 xdata = get(ud.hthumb,'xdata');
tomwalters@0 426 xlim = [min(xdata) max(xdata)];
tomwalters@0 427
tomwalters@0 428 % Commented out, due to flash:
tomwalters@0 429 %set(ud.hax([1 3]),'xlim',xlim);
tomwalters@0 430 %
tomwalters@0 431 % This is fine:
tomwalters@0 432 set(ud.hax(1),'xlim',xlim);
tomwalters@0 433 %
tomwalters@0 434 % xxx the following line causes flash in the spect image
tomwalters@0 435 % this is the time-slice axis:
tomwalters@0 436 % xxx xxx xxx
tomwalters@0 437 %set(ud.hax(3),'xlim',xlim);
tomwalters@0 438
tomwalters@0 439 changePtr(gcbf,'ldrag');
tomwalters@0 440 install_cursorfcns(gcbf,'thumbleft');
tomwalters@0 441
tomwalters@0 442 % Turn on crosshair visibility, which was shut off
tomwalters@0 443 % during thumbnail panning (wbdown_thumb):
tomwalters@0 444 set([ud.hspec_y ud.hspec_x],'vis','on');
tomwalters@0 445
tomwalters@0 446 %---------------------------------------------------------------
tomwalters@0 447 function wbup_thumbright(hco,eventStruct)
tomwalters@0 448 % set spectrogram and time-slice xlims
tomwalters@0 449 hfig = gcbf;
tomwalters@0 450 ud = get(hfig,'userdata');
tomwalters@0 451 xdata = get(ud.hthumb,'xdata');
tomwalters@0 452 xlim = [min(xdata) max(xdata)];
tomwalters@0 453
tomwalters@0 454 % Commented out, due to flash:
tomwalters@0 455 %set(ud.hax([1 3]),'xlim',xlim);
tomwalters@0 456 %
tomwalters@0 457 % This is fine:
tomwalters@0 458 set(ud.hax(1),'xlim',xlim);
tomwalters@0 459 %
tomwalters@0 460 % xxx the following line causes flash in the spect image
tomwalters@0 461 % this is the time-slice axis:
tomwalters@0 462 % xxx xxx
tomwalters@0 463 %set(ud.hax(3),'xlim',xlim);
tomwalters@0 464
tomwalters@0 465 changePtr(gcbf,'rdrag');
tomwalters@0 466 install_cursorfcns(gcbf,'thumbright');
tomwalters@0 467
tomwalters@0 468 % Turn on crosshair visibility, which was shut off
tomwalters@0 469 % during thumbnail panning (wbdown_thumb):
tomwalters@0 470 set([ud.hspec_y ud.hspec_x],'vis','on');
tomwalters@0 471
tomwalters@0 472 %---------------------------------------------------------------
tomwalters@0 473 function update_status(hfig,str)
tomwalters@0 474 % UPDATE_STATUS Update status text.
tomwalters@0 475
tomwalters@0 476 % If str is not a string, skip
tomwalters@0 477 % -1 is often used to "skip" the update
tomwalters@0 478 if ischar(str),
tomwalters@0 479 ud = get(hfig,'userdata');
tomwalters@0 480 set(ud.htext_status,'string',str);
tomwalters@0 481 end
tomwalters@0 482
tomwalters@0 483 %---------------------------------------------------------------
tomwalters@0 484 function play_sound(hco, eventStruct)
tomwalters@0 485 % PLAY_SOUND Play the selected sound segment
tomwalters@0 486
tomwalters@0 487 hfig = gcbf;
tomwalters@0 488 ud = get(hfig,'userdata');
tomwalters@0 489 y = get(ud.htime_plot,'ydata');
tomwalters@0 490 Fs = ud.Fs;
tomwalters@0 491
tomwalters@0 492 xdata=get(ud.hthumb,'xdata');
tomwalters@0 493 xlim=[min(xdata) max(xdata)];
tomwalters@0 494 xidx=floor(xlim*Fs)+1;
tomwalters@0 495 if xidx(1)<1, xidx(1)=1; end
tomwalters@0 496 if xidx(2)>length(y), xidx(2)=length(y); end
tomwalters@0 497
tomwalters@0 498 % Normalize sound and play:
tomwalters@0 499 mx=max(abs(y));
tomwalters@0 500 try
tomwalters@0 501 wavplay(y(xidx(1):xidx(2))./mx,Fs,'sync');
tomwalters@0 502 catch
tomwalters@0 503 msg = lasterr;
tomwalters@0 504 errordlg(msg,'Audio Playback Error','modal');
tomwalters@0 505 end
tomwalters@0 506
tomwalters@0 507 %---------------------------------------------------------------
tomwalters@0 508 % called by audioplayer during playback (if audioplayer enabled)
tomwalters@0 509 function update_audio_position(hco, eventStruct)
tomwalters@0 510 if hco.isplaying, % only do this if playback is in progress
tomwalters@0 511 currentPosition = get(hco, 'CurrentSample') / get(hco, 'SampleRate');
tomwalters@0 512 set_crosshairs(get(hco, 'UserData'), currentPosition);
tomwalters@0 513 end
tomwalters@0 514
tomwalters@0 515 %---------------------------------------------------------------
tomwalters@0 516 % utility to easily set playback boundaries
tomwalters@0 517 function set_audio_selection(hfig, selectionPair)
tomwalters@0 518 %%%%%%%%%%%%%%%%%%%%%%%%%%
tomwalters@0 519 % inserted by S.Bleeck
tomwalters@0 520 global tmin;
tomwalters@0 521 global tmax;
tomwalters@0 522 %%%%%%%%%%%%%%%%%%%%%%%%%%
tomwalters@0 523 if ~ isempty(getappdata(hfig, 'audioSelection')), % only do this if audioplayer enabled
tomwalters@0 524 selection.inPoint = selectionPair(1);
tomwalters@0 525 if selection.inPoint < 1, selection.inPoint = 1; end
tomwalters@0 526 selection.outPoint = selectionPair(2);
tomwalters@0 527 setappdata(hfig, 'audioSelection', selection);
tomwalters@0 528 %%%%%%%%%%%%%%%%%%%%%%%%%%
tomwalters@0 529 % inserted by S.Bleeck
tomwalters@0 530 % set the global times, so that we can pick them up
tomwalters@0 531 tmin=selection.inPoint;
tomwalters@0 532 tmax=selection.outPoint;
tomwalters@0 533 %%%%%%%%%%%%%%%%%%%%%%%%%%
tomwalters@0 534 end
tomwalters@0 535
tomwalters@0 536 %---------------------------------------------------------------
tomwalters@0 537 % used to set the "put back position" of the vertical crosshair
tomwalters@0 538 function start_function(hobj, eventStruct)
tomwalters@0 539 hfig = get(hobj, 'UserData');
tomwalters@0 540 ud = get(hfig,'userdata');
tomwalters@0 541 set(hobj, 'StopFcn', {@stop_function, ud.crosshair.xctr});
tomwalters@0 542
tomwalters@0 543 %---------------------------------------------------------------
tomwalters@0 544 % when playback has completed, puts back the vertical crosshair
tomwalters@0 545 % to where it was when playback was initiated
tomwalters@0 546 function stop_function(hobj, eventStruct, where)
tomwalters@0 547 while isplaying(hobj), pause(0); end % let playback complete
tomwalters@0 548 if get(hobj, 'CurrentSample') == 1, % if paused, don't put it back
tomwalters@0 549 set_crosshairs(get(hobj, 'UserData'), where);
tomwalters@0 550 end
tomwalters@0 551
tomwalters@0 552 %---------------------------------------------------------------
tomwalters@0 553 function set_cmap_limits(hfig, new_dr)
tomwalters@0 554 % Set new colormap limits
tomwalters@0 555
tomwalters@0 556 ud = get(hfig,'userdata');
tomwalters@0 557 hax_spec = ud.hax(1);
tomwalters@0 558 hax_cbar = ud.hax(5);
tomwalters@0 559 himage_cbar = ud.himage_cbar;
tomwalters@0 560
tomwalters@0 561 % Set new dynamic range limits into spectrogram image
tomwalters@0 562 set(hax_spec,'clim',new_dr);
tomwalters@0 563
tomwalters@0 564 % colorbar is 1:256
tomwalters@0 565 % actual spectrogram dynamic range is orig_dr
tomwalters@0 566 % new spectrogram dynamic range is new_dr
tomwalters@0 567 orig_dr = get(himage_cbar,'ydata');
tomwalters@0 568 diff_dr = new_dr - orig_dr;
tomwalters@0 569 cmapIndices_per_dB = 256./diff(orig_dr); % a constant
tomwalters@0 570 diff_clim = diff_dr .* cmapIndices_per_dB;
tomwalters@0 571 cbar_clim = [1 256] + diff_clim;
tomwalters@0 572 set(himage_cbar,'cdatamapping','scaled'); % do during creation
tomwalters@0 573 set(hax_cbar,'clim',cbar_clim);
tomwalters@0 574
tomwalters@0 575 %---------------------------------------------------------------
tomwalters@0 576 function reset_cmap_limits(hco,eventStruct)
tomwalters@0 577 % Reset colormap limits to dynamic range of spectrogram data
tomwalters@0 578
tomwalters@0 579 hfig = gcbf;
tomwalters@0 580 ud = get(hfig,'userdata');
tomwalters@0 581 orig_dr = get(ud.himage_cbar,'ydata');
tomwalters@0 582 set_cmap_limits(hfig, orig_dr);
tomwalters@0 583
tomwalters@0 584 %---------------------------------------------------------------
tomwalters@0 585 function manual_cmap_limits(hco,eventStruct,hfig)
tomwalters@0 586 % manual_cmap_limits Manual change to colormap dynamic range limits
tomwalters@0 587
tomwalters@0 588 if nargin<3,
tomwalters@0 589 hfig = gcbf;
tomwalters@0 590 end
tomwalters@0 591 ud = get(hfig,'userdata');
tomwalters@0 592 hax_spec = ud.hax(1);
tomwalters@0 593
tomwalters@0 594 % Prompt for changes to cmap limits:
tomwalters@0 595 clim = get(hax_spec,'clim');
tomwalters@0 596 % 'dB value of first color in colormap:'
tomwalters@0 597 % 'dB value of last color in colormap:'
tomwalters@0 598 prompt={'Value of top color in colormap (dB):', ...
tomwalters@0 599 'Value of bottom color in colormap (dB):'};
tomwalters@0 600 def = {num2str(clim(2)), num2str(clim(1))};
tomwalters@0 601 dlgTitle='Adjust dynamic range of colormap';
tomwalters@0 602 lineNo=1;
tomwalters@0 603 strs=inputdlg(prompt,dlgTitle,lineNo,def);
tomwalters@0 604 if isempty(strs),
tomwalters@0 605 return
tomwalters@0 606 end
tomwalters@0 607 new_dr = [str2num(strs{2}) str2num(strs{1})];
tomwalters@0 608
tomwalters@0 609 set_cmap_limits(hfig,new_dr);
tomwalters@0 610
tomwalters@0 611 %---------------------------------------------------------------
tomwalters@0 612 function wbmotion_cmap(hco,eventStruct)
tomwalters@0 613 % WBMOTION_CMAP Graphical change to colormap dynamic range limits
tomwalters@0 614
tomwalters@0 615 hfig = gcbf;
tomwalters@0 616 ud = get(hfig,'userdata');
tomwalters@0 617 hax_spec = ud.hax(1);
tomwalters@0 618 hax_cbar = ud.hax(5);
tomwalters@0 619
tomwalters@0 620 % Determine cursor starting and current points ASAP:
tomwalters@0 621 cp = get(hax_cbar,'CurrentPoint');
tomwalters@0 622 newPt = cp(1,2); % y-coord only
tomwalters@0 623 dy = newPt - ud.cbar.origPt;
tomwalters@0 624
tomwalters@0 625 % if SelectionType was normal,
tomwalters@0 626 % update top or bottom of colorbar, only,
tomwalters@0 627 % depending on whether user started drag
tomwalters@0 628 % in the top or bottom of bar, respectively.
tomwalters@0 629 % if SelectionType was extend,
tomwalters@0 630 % update both top AND bottom of bar simultaneously,
tomwalters@0 631 % translating colormap region.
tomwalters@0 632 if strcmp(ud.cbar.SelectionType,'extend'),
tomwalters@0 633 change_dr = [dy dy];
tomwalters@0 634 else
tomwalters@0 635 if ud.cbar.StartInTop,
tomwalters@0 636 change_dr = [0 dy];
tomwalters@0 637 else
tomwalters@0 638 change_dr = [dy 0];
tomwalters@0 639 end
tomwalters@0 640 end
tomwalters@0 641 new_dr = ud.cbar.starting_dr + change_dr;
tomwalters@0 642 if diff(new_dr)<=0,
tomwalters@0 643 new_dr = ud.cbar.starting_dr;
tomwalters@0 644 end
tomwalters@0 645
tomwalters@0 646 % Colorbar range is 1 to 256.
tomwalters@0 647 % Actual spectrogram dynamic range is orig_dr
tomwalters@0 648 % New spectrogram dynamic range is new_dr
tomwalters@0 649 orig_dr = get(ud.himage_cbar,'ydata'); % a constant
tomwalters@0 650 cmapIndices_per_dB = 256./diff(orig_dr); % a constant
tomwalters@0 651 diff_dr = new_dr - orig_dr;
tomwalters@0 652 diff_clim = diff_dr .* cmapIndices_per_dB;
tomwalters@0 653 cbar_clim = [1 256] + diff_clim;
tomwalters@0 654
tomwalters@0 655 if diff(cbar_clim)>0,
tomwalters@0 656 % Protect against poor choice of values
tomwalters@0 657 set(hax_cbar,'clim',cbar_clim,'userdata',new_dr);
tomwalters@0 658 end
tomwalters@0 659
tomwalters@0 660 % We defer setting the new dynamic range limits
tomwalters@0 661 % into the spectrogram image axis, as it will create
tomwalters@0 662 % too much flash. Instead, on button-up, the new
tomwalters@0 663 % limit is set. See wbup_cmap() for details.
tomwalters@0 664
tomwalters@0 665 % Set new dynamic range limits into spectrogram image
tomwalters@0 666 % Note: userdata could be empty if this is the first entry...
tomwalters@0 667 % xxx
tomwalters@0 668 %set(ud.hax(1),'clim',new_dr);
tomwalters@0 669 set(hax_spec,'clim',new_dr);
tomwalters@0 670
tomwalters@0 671 %---------------------------------------------------------------
tomwalters@0 672 function isChange = changePtr(hfig, newPtr)
tomwalters@0 673
tomwalters@0 674 % Get current pointer name:
tomwalters@0 675 ud = get(hfig,'userdata');
tomwalters@0 676
tomwalters@0 677 % Is this a change in pointer type?
tomwalters@0 678 isChange = ~strcmp(ud.currPtr,newPtr);
tomwalters@0 679 if isChange,
tomwalters@0 680 setptr(hfig, newPtr);
tomwalters@0 681 ud.currPtr = newPtr;
tomwalters@0 682 set(hfig,'userdata',ud);
tomwalters@0 683 end
tomwalters@0 684
tomwalters@0 685 %---------------------------------------------------------------
tomwalters@0 686 function wbmotion_general(hco,eventStruct,hfig)
tomwalters@0 687 % General button motion
tomwalters@0 688 %
tomwalters@0 689 % Determines if cursor is over a crosshair
tomwalters@0 690 % If so, changes pointer and installs crosshair buttondowns
tomwalters@0 691 % If not, changes back to normal cursor and general buttondowns
tomwalters@0 692 % as necessary.
tomwalters@0 693
tomwalters@0 694 if nargin<3,
tomwalters@0 695 hfig = gcbf;
tomwalters@0 696 end
tomwalters@0 697 [isOverHV, isSegmentAxis, isCmapAxis,isTopHalfCmap, isThumb] = ...
tomwalters@0 698 over_crosshair(hfig);
tomwalters@0 699
tomwalters@0 700 if ~any(isOverHV),
tomwalters@0 701 % Not hovering over a crosshair
tomwalters@0 702
tomwalters@0 703 if isSegmentAxis,
tomwalters@0 704 % Over an axis in which we can get a delta-time measurement
tomwalters@0 705 if changePtr(hfig,'crosshair'),
tomwalters@0 706 install_cursorfcns(hfig,'segment');
tomwalters@0 707 end
tomwalters@0 708
tomwalters@0 709 elseif isCmapAxis,
tomwalters@0 710 % Over the colormap axes
tomwalters@0 711 % Install the up/down pointer:
tomwalters@0 712 if isTopHalfCmap,
tomwalters@0 713 if changePtr(hfig,'udrag'),
tomwalters@0 714 update_status(hfig,'Adjust upper dynamic range (shift to translate)');
tomwalters@0 715 install_cursorfcns(hfig,'cmap');
tomwalters@0 716 end
tomwalters@0 717 else
tomwalters@0 718 if changePtr(hfig,'ddrag'),
tomwalters@0 719 update_status(hfig,'Adjust lower dynamic range (shift to translate)');
tomwalters@0 720 install_cursorfcns(hfig,'cmap');
tomwalters@0 721 end
tomwalters@0 722 end
tomwalters@0 723
tomwalters@0 724 elseif any(isThumb),
tomwalters@0 725 % Over thumbnail - isThumb is a 3-element vector, [left center right],
tomwalters@0 726 % indicating whether cursor is over left edge, right edge, or is over
tomwalters@0 727 % the general thumbnail patch itself.
tomwalters@0 728
tomwalters@0 729 % Install appropriate pointer:
tomwalters@0 730 if isThumb(1),
tomwalters@0 731 % Over left edge
tomwalters@0 732 if changePtr(hfig,'ldrag'),
tomwalters@0 733 install_cursorfcns(hfig,'thumbleft');
tomwalters@0 734 end
tomwalters@0 735 elseif isThumb(3),
tomwalters@0 736 % Over right edge
tomwalters@0 737 if changePtr(hfig,'rdrag'),
tomwalters@0 738 install_cursorfcns(hfig,'thumbright');
tomwalters@0 739 end
tomwalters@0 740 else
tomwalters@0 741 % Over general patch region
tomwalters@0 742 if changePtr(hfig,'hand'),
tomwalters@0 743 install_cursorfcns(hfig,'thumb');
tomwalters@0 744 end
tomwalters@0 745 end
tomwalters@0 746
tomwalters@0 747 else
tomwalters@0 748 % Not over a special axes:
tomwalters@0 749 if changePtr(hfig,'arrow'),
tomwalters@0 750 install_cursorfcns(hfig,'general');
tomwalters@0 751 end
tomwalters@0 752 end
tomwalters@0 753
tomwalters@0 754 else
tomwalters@0 755 % Pointer is over a crosshair (vert or horiz or both)
tomwalters@0 756 if all(isOverHV),
tomwalters@0 757 % Over both horiz and vert (near crosshair center):
tomwalters@0 758 if changePtr(hfig,'fleur'),
tomwalters@0 759 install_cursorfcns(hfig,'hvcross');
tomwalters@0 760 end
tomwalters@0 761 elseif isOverHV(1),
tomwalters@0 762 % Over H crosshair
tomwalters@0 763 if changePtr(hfig,'uddrag'),
tomwalters@0 764 install_cursorfcns(hfig,'hcross');
tomwalters@0 765 end
tomwalters@0 766 else
tomwalters@0 767 % Over V crosshair
tomwalters@0 768 if changePtr(hfig,'lrdrag'),
tomwalters@0 769 install_cursorfcns(hfig,'vcross');
tomwalters@0 770 end
tomwalters@0 771 end
tomwalters@0 772 end
tomwalters@0 773
tomwalters@0 774 %---------------------------------------------------------------
tomwalters@0 775 function [y,isSegmentAxis,isCmapAxis,...
tomwalters@0 776 isTopHalfCmap, isThumb] = over_crosshair(hfig)
tomwalters@0 777 % Is the cursor hovering over the crosshairs?
tomwalters@0 778 % There are two crosshairs, one an H-crosshair, the other
tomwalters@0 779 % a V-crosshair. The H and V crosshairs span several
tomwalters@0 780 % different axes.
tomwalters@0 781 %
tomwalters@0 782 % Function returns a 2-element vector, indicating whether
tomwalters@0 783 % the cursor is currently over the H- and/or V-crosshairs.
tomwalters@0 784 % y = [isOverH isOverV]
tomwalters@0 785
tomwalters@0 786 y = [0 0];
tomwalters@0 787 isSegmentAxis = 0;
tomwalters@0 788 isCmapAxis = 0;
tomwalters@0 789 isTopHalfCmap = 0;
tomwalters@0 790 isThumb = [0 0 0]; % left, middle, right regions
tomwalters@0 791
tomwalters@0 792 % First, are we over any axes?
tomwalters@0 793 hax = overAxes(hfig);
tomwalters@0 794 if isempty(hax), return; end % not over an axis
tomwalters@0 795
tomwalters@0 796 % Get current point in axis:
tomwalters@0 797 cp = get(hax,'currentpoint');
tomwalters@0 798 ud = get(hfig,'userdata');
tomwalters@0 799
tomwalters@0 800 % Axis which are "segmentable" have a vertical crosshair
tomwalters@0 801 % e.g., spectrogram and time axes only
tomwalters@0 802 isCmapAxis = (hax==ud.hax(5));
tomwalters@0 803 isSegmentAxis = (hax==ud.hax(1));
tomwalters@0 804
tomwalters@0 805 % Determine if any horiz or vert crosshairs are
tomwalters@0 806 % in this axis ... store as [anyHoriz anyVert]:
tomwalters@0 807 hasHVCrossHairs = [any(hax==ud.hax([1 4])) ...
tomwalters@0 808 any(hax==ud.hax(1:3))];
tomwalters@0 809
tomwalters@0 810 % Is cursor in colormap axis?
tomwalters@0 811 if (isCmapAxis),
tomwalters@0 812 % is cursor in top half of colormap axis?
tomwalters@0 813 orig_dr = get(ud.hax(1),'clim');
tomwalters@0 814 isTopHalfCmap = (cp(1,2) >= sum(orig_dr)/2);
tomwalters@0 815 end
tomwalters@0 816
tomwalters@0 817 if any(hasHVCrossHairs),
tomwalters@0 818 % Get cursor & crosshair positions:
tomwalters@0 819 crosshair_pos = [ud.crosshair.xctr ud.crosshair.yctr];
tomwalters@0 820 cursor_delta = abs(crosshair_pos - cp(1,1:2));
tomwalters@0 821 axis_dx = diff(get(hax,'xlim'));
tomwalters@0 822 axis_dy = diff(get(hax,'ylim'));
tomwalters@0 823 axis_delta = [axis_dx axis_dy];
tomwalters@0 824
tomwalters@0 825 % Is cursor within 1 percent of crosshair centers?
tomwalters@0 826 % Limit test uses the reciprocal of the percentage tolerance
tomwalters@0 827 % 1-percent -> 1 / 0.01 = 100
tomwalters@0 828 % 1.5-percent -> 1 / 0.015 ~= 67
tomwalters@0 829 % 2-percent -> 1 / 0.02 = 50
tomwalters@0 830 %
tomwalters@0 831 % Finally, allow a true result only if the axis
tomwalters@0 832 % has a crosshair of the corresponding type
tomwalters@0 833 %
tomwalters@0 834 y = fliplr(cursor_delta * 67 < axis_delta) & hasHVCrossHairs;
tomwalters@0 835 end
tomwalters@0 836
tomwalters@0 837 % Are we over the thumbnail patch?
tomwalters@0 838 % Check if we're over the time axis:
tomwalters@0 839 if (hax == ud.hax(2)),
tomwalters@0 840 % Get thumb patch limits:
tomwalters@0 841 xdata=get(ud.hthumb,'xdata');
tomwalters@0 842 xlim=[min(xdata) max(xdata)];
tomwalters@0 843
tomwalters@0 844 % Is cursor over general patch area?
tomwalters@0 845 thumb_delta = xlim - cp(1,1);
tomwalters@0 846 isThumb(2) = thumb_delta(1)<=0 & thumb_delta(2)>=0;
tomwalters@0 847
tomwalters@0 848 % Is cursor over left or right thumbnail edge?
tomwalters@0 849 % Use same tolerance as crosshair test:
tomwalters@0 850 axis_dx = diff(get(hax,'xlim'));
tomwalters@0 851 isThumb([1 3]) = (abs(thumb_delta) * 67 < axis_dx);
tomwalters@0 852 end
tomwalters@0 853
tomwalters@0 854 %---------------------------------------------------------------
tomwalters@0 855 function h=overAxes(hfig)
tomwalters@0 856 % overAxes Determine if pointer is currently over an
tomwalters@0 857 % axis of the figure; the axis list comes from the
tomwalters@0 858 % figure UserData (ud.hax).
tomwalters@0 859
tomwalters@0 860 p = get(0,'PointerLocation');
tomwalters@0 861 figPos = get(hfig,'Position');
tomwalters@0 862 if ~isempty(figPos),
tomwalters@0 863 x = (p(1)-figPos(1))/figPos(3);
tomwalters@0 864 y = (p(2)-figPos(2))/figPos(4);
tomwalters@0 865 ud = get(hfig,'userdata');
tomwalters@0 866 for h = ud.hax,
tomwalters@0 867 r = get(h,'Position');
tomwalters@0 868 if (x > r(1)) & (x < r(1)+r(3)) & ...
tomwalters@0 869 (y > r(2)) & (y < r(2)+r(4)),
tomwalters@0 870 return;
tomwalters@0 871 end
tomwalters@0 872 end
tomwalters@0 873 end
tomwalters@0 874 h = [];
tomwalters@0 875 return
tomwalters@0 876
tomwalters@0 877 %---------------------------------------------------------------
tomwalters@0 878 function y=isLeftClick(hfig)
tomwalters@0 879
tomwalters@0 880 % Keywords for key/button combinations:
tomwalters@0 881 % Left Right
tomwalters@0 882 % none: normal alt
tomwalters@0 883 % Shift: extend alt
tomwalters@0 884 % Ctrl: alt alt
tomwalters@0 885 % Double: open alt
tomwalters@0 886
tomwalters@0 887 y=strcmp(get(hfig,'SelectionType'),'normal');
tomwalters@0 888
tomwalters@0 889 %---------------------------------------------------------------
tomwalters@0 890 function wbdown_hcross(hco,eventStruct)
tomwalters@0 891 % window button down in h-crosshair mode
tomwalters@0 892 if ~isLeftClick(gcbf), return; end
tomwalters@0 893 install_cursorfcns(gcbf,'hcross_buttondown');
tomwalters@0 894 wbmotion_cross([],[],'h');
tomwalters@0 895
tomwalters@0 896 %---------------------------------------------------------------
tomwalters@0 897 function wbdown_vcross(hco,eventStruct)
tomwalters@0 898 % window button down in v-crosshair mode
tomwalters@0 899 if ~isLeftClick(gcbf), return; end
tomwalters@0 900 install_cursorfcns(gcbf,'vcross_buttondown');
tomwalters@0 901 wbmotion_cross([],[],'v');
tomwalters@0 902
tomwalters@0 903 %---------------------------------------------------------------
tomwalters@0 904 function wbdown_hvcross(hco,eventStruct)
tomwalters@0 905 % window button down in hv-crosshair mode
tomwalters@0 906 if ~isLeftClick(gcbf), return; end
tomwalters@0 907 install_cursorfcns(gcbf,'hvcross_buttondown');
tomwalters@0 908 wbmotion_cross([],[],'hv');
tomwalters@0 909
tomwalters@0 910 %---------------------------------------------------------------
tomwalters@0 911 function wbdown_segment(hco,eventStruct)
tomwalters@0 912 % window button down in segmentation mode
tomwalters@0 913 if ~isLeftClick(gcbf), return; end
tomwalters@0 914 install_cursorfcns(gcbf,'segment_buttondown');
tomwalters@0 915 wbmotion_segment([],[],gcbf);
tomwalters@0 916
tomwalters@0 917 %---------------------------------------------------------------
tomwalters@0 918 function wbdown_thumb(hco,eventStruct)
tomwalters@0 919 % window button down in thumbnail mode
tomwalters@0 920 if ~isLeftClick(gcbf), return; end
tomwalters@0 921
tomwalters@0 922 % cache y-coord of pointer
tomwalters@0 923 ud = get(gcbf,'userdata');
tomwalters@0 924 hax_time = ud.hax(2);
tomwalters@0 925 cp = get(hax_time,'currentpoint');
tomwalters@0 926 xdata = get(ud.hthumb,'xdata');
tomwalters@0 927 width = max(xdata)-min(xdata);
tomwalters@0 928
tomwalters@0 929 ud.thumb.origPt = cp(1,1); % x-coord only
tomwalters@0 930 ud.thumb.width = width;
tomwalters@0 931 ud.thumb.xdata = xdata;
tomwalters@0 932 set(gcbf,'userdata',ud);
tomwalters@0 933
tomwalters@0 934 changePtr(gcbf,'closedhand');
tomwalters@0 935 install_cursorfcns(gcbf,'thumb_buttondown');
tomwalters@0 936
tomwalters@0 937
tomwalters@0 938 % Turn off image axis visibility,
tomwalters@0 939 % so that it does not flash while panning:
tomwalters@0 940 %
tomwalters@0 941 % xxx off permanently now:
tomwalters@0 942 %set(ud.hax(1),'vis','off');
tomwalters@0 943 %
tomwalters@0 944 % Turn off crosshair visibility:
tomwalters@0 945 set([ud.hspec_y ud.hspec_x ud.htslice_y],'vis','off');
tomwalters@0 946
tomwalters@0 947 %---------------------------------------------------------------
tomwalters@0 948 function wbdown_thumbleft(hco,eventStruct)
tomwalters@0 949
tomwalters@0 950 % window button down in LEFT thumbnail mode
tomwalters@0 951 if ~isLeftClick(gcbf), return; end
tomwalters@0 952
tomwalters@0 953 % cache y-coord of pointer
tomwalters@0 954 ud = get(gcbf,'userdata');
tomwalters@0 955 hax_time = ud.hax(2);
tomwalters@0 956 cp = get(hax_time,'currentpoint');
tomwalters@0 957 xdata = get(ud.hthumb,'xdata');
tomwalters@0 958 width = max(xdata)-min(xdata);
tomwalters@0 959
tomwalters@0 960 ud.thumb.origPt = cp(1,1); % x-coord only
tomwalters@0 961 ud.thumb.width = width;
tomwalters@0 962 ud.thumb.xdata = xdata;
tomwalters@0 963 set(gcbf,'userdata',ud);
tomwalters@0 964
tomwalters@0 965 install_cursorfcns(gcbf,'thumbleft_buttondown');
tomwalters@0 966
tomwalters@0 967 % Turn off crosshair visibility:
tomwalters@0 968 set([ud.hspec_y ud.hspec_x],'vis','off');
tomwalters@0 969
tomwalters@0 970 %---------------------------------------------------------------
tomwalters@0 971 function wbdown_thumbright(hco,eventStruct)
tomwalters@0 972
tomwalters@0 973 % window button down in LEFT thumbnail mode
tomwalters@0 974 if ~isLeftClick(gcbf), return; end
tomwalters@0 975
tomwalters@0 976 % cache y-coord of pointer
tomwalters@0 977 ud = get(gcbf,'userdata');
tomwalters@0 978 hax_time = ud.hax(2);
tomwalters@0 979 cp = get(hax_time,'currentpoint');
tomwalters@0 980 xdata = get(ud.hthumb,'xdata');
tomwalters@0 981 width = max(xdata)-min(xdata);
tomwalters@0 982
tomwalters@0 983 ud.thumb.origPt = cp(1,1); % x-coord only
tomwalters@0 984 ud.thumb.width = width;
tomwalters@0 985 ud.thumb.xdata = xdata;
tomwalters@0 986 set(gcbf,'userdata',ud);
tomwalters@0 987
tomwalters@0 988 install_cursorfcns(gcbf,'thumbright_buttondown');
tomwalters@0 989
tomwalters@0 990 % Turn off crosshair visibility:
tomwalters@0 991 set([ud.hspec_y ud.hspec_x],'vis','off');
tomwalters@0 992
tomwalters@0 993 %----------------------------------------------------
tomwalters@0 994 function wbdown_cmap(hco,eventStruct)
tomwalters@0 995 % window button down in colormap mode
tomwalters@0 996
tomwalters@0 997 hfig = gcbf;
tomwalters@0 998
tomwalters@0 999 % Only allow left (normal) or shift+left (extend)
tomwalters@0 1000 st = get(hfig,'SelectionType');
tomwalters@0 1001 i=strmatch(st,{'normal','extend','open'});
tomwalters@0 1002 if isempty(i), return; end
tomwalters@0 1003
tomwalters@0 1004 if i==3,
tomwalters@0 1005 % open dynamic range menu
tomwalters@0 1006 manual_cmap_limits([],[],hfig);
tomwalters@0 1007 return
tomwalters@0 1008 elseif i==2,
tomwalters@0 1009 % Shift+left button = translate,
tomwalters@0 1010 % show up/down cursor during drag
tomwalters@0 1011 % NOTE: cannot update cursor when shift is pressed
tomwalters@0 1012 % but no mouse button is pressed (no event!)
tomwalters@0 1013 changePtr(hfig,'uddrag'); % xxx
tomwalters@0 1014 end
tomwalters@0 1015
tomwalters@0 1016 ud = get(hfig,'userdata');
tomwalters@0 1017
tomwalters@0 1018 % cache y-coord of pointer
tomwalters@0 1019 hax_cbar = ud.hax(5);
tomwalters@0 1020 cp = get(hax_cbar,'currentpoint');
tomwalters@0 1021 ud.cbar.origPt = cp(1,2); % y-coord only
tomwalters@0 1022 ud.cbar.SelectionType = st; % normal or extend
tomwalters@0 1023
tomwalters@0 1024 % The current clim is in the spectrogram image
tomwalters@0 1025 % We want to know the midpoint of this
tomwalters@0 1026 orig_dr = get(ud.hax(1),'clim');
tomwalters@0 1027 ud.cbar.midPt = sum(orig_dr)/2;
tomwalters@0 1028
tomwalters@0 1029 % Determine if pointer went down in top or bottom
tomwalters@0 1030 % half of colorbar:
tomwalters@0 1031 ud.cbar.StartInTop = (ud.cbar.origPt >= ud.cbar.midPt);
tomwalters@0 1032
tomwalters@0 1033 % Cache original dynamic range:
tomwalters@0 1034 hax_spec = ud.hax(1);
tomwalters@0 1035 ud.cbar.starting_dr = get(hax_spec,'clim');
tomwalters@0 1036 set(hfig,'userdata',ud);
tomwalters@0 1037
tomwalters@0 1038 install_cursorfcns(hfig,'cmap_buttondown');
tomwalters@0 1039
tomwalters@0 1040 % Set initial clim into userdata in case motion
tomwalters@0 1041 % callback not performed (motion updates userdata).
tomwalters@0 1042 % wbup_cmap reads the userdata
tomwalters@0 1043 %
tomwalters@0 1044 % Turn off visibility during drag to prevent flash
tomwalters@0 1045 set(hax_cbar, ...
tomwalters@0 1046 'userdata',ud.cbar.starting_dr, ...
tomwalters@0 1047 'vis','off');
tomwalters@0 1048
tomwalters@0 1049 %---------------------------------------------------------------
tomwalters@0 1050 function wbup_hcross(hco,eventStruct)
tomwalters@0 1051 % window button up in h-crosshair mode
tomwalters@0 1052 install_cursorfcns(gcbf,'hcross');
tomwalters@0 1053 update_cmap_ptr(gcbf);
tomwalters@0 1054
tomwalters@0 1055 %---------------------------------------------------------------
tomwalters@0 1056 function wbup_vcross(hco,eventStruct)
tomwalters@0 1057 % window button up in v-crosshair mode
tomwalters@0 1058 install_cursorfcns(gcbf,'vcross');
tomwalters@0 1059 update_cmap_ptr(gcbf);
tomwalters@0 1060
tomwalters@0 1061 %---------------------------------------------------------------
tomwalters@0 1062 function wbup_hvcross(hco,eventStruct)
tomwalters@0 1063 % window button up in hv-crosshair mode
tomwalters@0 1064 install_cursorfcns(gcbf,'hvcross');
tomwalters@0 1065 update_cmap_ptr(gcbf);
tomwalters@0 1066
tomwalters@0 1067 %---------------------------------------------------------------
tomwalters@0 1068 function wbup_segment(hco,eventStruct)
tomwalters@0 1069 % window button up in segmentation mode
tomwalters@0 1070 install_cursorfcns(gcbf,'segment');
tomwalters@0 1071
tomwalters@0 1072 %---------------------------------------------------------------
tomwalters@0 1073 function wbup_cmap(hco,eventStruct)
tomwalters@0 1074 % window button up in colormap mode
tomwalters@0 1075 install_cursorfcns(gcbf,'cmap');
tomwalters@0 1076
tomwalters@0 1077 % Set new dynamic range limits into spectrogram image
tomwalters@0 1078 % Note: userdata could be empty if this is the first entry...
tomwalters@0 1079 ud = get(gcbf,'userdata');
tomwalters@0 1080 hax_cbar=ud.hax(5);
tomwalters@0 1081 set(ud.hax(1),'clim',get(hax_cbar,'userdata'));
tomwalters@0 1082 set(hax_cbar,'vis','on'); % re-enable axis vis
tomwalters@0 1083
tomwalters@0 1084 % Set new status msg, since it doesn't update
tomwalters@0 1085 % in the install_cursorfcns fcn for cmap callbacks
tomwalters@0 1086 % Do this by calling the general mouse-motion fcn:
tomwalters@0 1087 wbmotion_general([],[]);
tomwalters@0 1088
tomwalters@0 1089 %---------------------------------------------------------------
tomwalters@0 1090 function update_cmap_ptr(hfig)
tomwalters@0 1091 % Update colormap pointer:
tomwalters@0 1092
tomwalters@0 1093 ud = get(hfig,'userdata');
tomwalters@0 1094 v = get_spec_val(hfig); % value in dB
tomwalters@0 1095 dy_tri = ud.crosshair.cbar.dy_tri;
tomwalters@0 1096 set(ud.hcmap_arrow,'ydata', [v+dy_tri v-dy_tri v]);
tomwalters@0 1097
tomwalters@0 1098
tomwalters@0 1099 %---------------------------------------------------------------
tomwalters@0 1100 function [i,j] = get_adjusted_crosshair_idx(hfig)
tomwalters@0 1101 % Find image matrix coordinate pair (j,i) under crosshair.
tomwalters@0 1102 % Adjust crosshair for "half-pixel offset" implicit in image display
tomwalters@0 1103
tomwalters@0 1104 ud=get(hfig,'userdata');
tomwalters@0 1105 xc=ud.crosshair.xctr;
tomwalters@0 1106 yc=ud.crosshair.yctr;
tomwalters@0 1107 himage=ud.himage;
tomwalters@0 1108 im=get(himage,'cdata');
tomwalters@0 1109
tomwalters@0 1110 % Get image pixel size:
tomwalters@0 1111 xdata=get(himage,'xdata');
tomwalters@0 1112 if length(xdata)>1, dx = xdata(2)-xdata(1); else dx=0; end
tomwalters@0 1113
tomwalters@0 1114 ydata=get(himage,'ydata');
tomwalters@0 1115 if length(ydata)>1, dy = ydata(2)-ydata(1); else dy=0; end
tomwalters@0 1116
tomwalters@0 1117 % Remove half a pixel size from apparent cursor position:
tomwalters@0 1118 xc=xc-dx/2;
tomwalters@0 1119 yc=yc-dy/2;
tomwalters@0 1120
tomwalters@0 1121 % Find pixel coordinate under the crosshair:
tomwalters@0 1122 i=find(xc>=xdata);
tomwalters@0 1123 if isempty(i), i=1;
tomwalters@0 1124 else i=i(end)+1;
tomwalters@0 1125 end
tomwalters@0 1126 j=find(yc>=ydata);
tomwalters@0 1127 if isempty(j), j=1;
tomwalters@0 1128 else j=j(end)+1;
tomwalters@0 1129 end
tomwalters@0 1130 sz=size(im);
tomwalters@0 1131 if i>sz(2), i=sz(2); end
tomwalters@0 1132 if j>sz(1), j=sz(1); end
tomwalters@0 1133
tomwalters@0 1134 %---------------------------------------------------------------
tomwalters@0 1135 function v = get_spec_val(hfig)
tomwalters@0 1136
tomwalters@0 1137 ud = get(hfig,'userdata');
tomwalters@0 1138 im = get(ud.himage,'cdata');
tomwalters@0 1139 [i,j] = get_adjusted_crosshair_idx(hfig);
tomwalters@0 1140 v = double(im(j,i)); % Get pixel value in double-precision
tomwalters@0 1141
tomwalters@0 1142 %---------------------------------------------------------------
tomwalters@0 1143 function v = get_spec_freq(hfig)
tomwalters@0 1144
tomwalters@0 1145 ud = get(hfig,'userdata');
tomwalters@0 1146 im = get(ud.himage,'cdata');
tomwalters@0 1147 [i,j] = get_adjusted_crosshair_idx(hfig);
tomwalters@0 1148 v = im(:,i); % Get pixel row in uint8
tomwalters@0 1149
tomwalters@0 1150 %---------------------------------------------------------------
tomwalters@0 1151 function v = get_spec_tslice(hfig)
tomwalters@0 1152
tomwalters@0 1153 ud = get(hfig,'userdata');
tomwalters@0 1154 im = get(ud.himage,'cdata');
tomwalters@0 1155 [i,j] = get_adjusted_crosshair_idx(hfig);
tomwalters@0 1156 v = im(j,:); % Get pixel column
tomwalters@0 1157
tomwalters@0 1158 %---------------------------------------------------------------
tomwalters@0 1159 function update_time_readout(hfig,diffTime)
tomwalters@0 1160
tomwalters@0 1161 % xxx
tomwalters@0 1162
tomwalters@0 1163 ud = get(hfig,'userdata');
tomwalters@0 1164 if nargin<2,
tomwalters@0 1165 t=ud.crosshair.xctr;
tomwalters@0 1166 prefix='';
tomwalters@0 1167 else
tomwalters@0 1168 t=diffTime - ud.crosshair.xctr;
tomwalters@0 1169 prefix='\Deltat ';
tomwalters@0 1170 end
tomwalters@0 1171
tomwalters@0 1172 % Update time readout
tomwalters@0 1173 [y,e,u] = engunits(t, 'latex','time');
tomwalters@0 1174 %str=[prefix num2str(y) ' ' u];
tomwalters@0 1175 str=[prefix sprintf('%.4f',y) ' ' u];
tomwalters@0 1176 set(ud.htext_time,'string',str);
tomwalters@0 1177
tomwalters@0 1178 %---------------------------------------------------------------
tomwalters@0 1179 function update_freq_readout(hfig,diffFreq)
tomwalters@0 1180
tomwalters@0 1181 ud=get(hfig,'userdata');
tomwalters@0 1182 if nargin<2,
tomwalters@0 1183 f=ud.crosshair.yctr;
tomwalters@0 1184 prefix='';
tomwalters@0 1185 else
tomwalters@0 1186 f=diffFreq - ud.crosshair.yctr;
tomwalters@0 1187 prefix='\Deltaf ';
tomwalters@0 1188 end
tomwalters@0 1189
tomwalters@0 1190 % Update freq readout
tomwalters@0 1191 [y,e,u] = engunits(f,'latex');
tomwalters@0 1192 %str=[prefix num2str(y) ' ' u 'Hz'];
tomwalters@0 1193 str=[prefix sprintf('%.4f',y) ' ' u 'Hz'];
tomwalters@0 1194 set(ud.htext_freq,'string',str);
tomwalters@0 1195
tomwalters@0 1196 %---------------------------------------------------------------
tomwalters@0 1197 function update_dB_readout(hfig,diffAmpl)
tomwalters@0 1198
tomwalters@0 1199 ud = get(hfig,'userdata');
tomwalters@0 1200 if nargin<2,
tomwalters@0 1201 a=get_spec_val(hfig);
tomwalters@0 1202 prefix='';
tomwalters@0 1203 else
tomwalters@0 1204 a=diffAmpl - get_spec_val(hfig);
tomwalters@0 1205 prefix='\Deltaa=';
tomwalters@0 1206 end
tomwalters@0 1207
tomwalters@0 1208 % Update mag readout
tomwalters@0 1209 %str=[prefix num2str(a) ' dB'];
tomwalters@0 1210 str=[prefix sprintf('%.4f',a) ' dB'];
tomwalters@0 1211 set(ud.htext_mag,'string',str);
tomwalters@0 1212
tomwalters@0 1213 %---------------------------------------------------------------
tomwalters@0 1214 function clear_dB_readout(hfig)
tomwalters@0 1215
tomwalters@0 1216 ud = get(hfig,'userdata');
tomwalters@0 1217 set(ud.htext_mag,'string','');
tomwalters@0 1218
tomwalters@0 1219 %---------------------------------------------------------------
tomwalters@0 1220 function wbmotion_cross(hco,eventStruct,sel)
tomwalters@0 1221 % motion callback during horiz/vert-crosshair selection
tomwalters@0 1222 % sel='h', 'v', or 'hv'
tomwalters@0 1223
tomwalters@0 1224 % Get current point in axis ASAP:
tomwalters@0 1225 hfig = gcbf;
tomwalters@0 1226 hco = gco;
tomwalters@0 1227 switch get(hco,'type')
tomwalters@0 1228 case 'axes'
tomwalters@0 1229 hax=hco;
tomwalters@0 1230 otherwise
tomwalters@0 1231 hax=get(hco,'parent');
tomwalters@0 1232 end
tomwalters@0 1233
tomwalters@0 1234 cp = get(hax,'currentpoint');
tomwalters@0 1235 ud = get(hfig,'userdata');
tomwalters@0 1236 x = cp(1,1);
tomwalters@0 1237 y = cp(1,2);
tomwalters@0 1238
tomwalters@0 1239 switch sel
tomwalters@0 1240 case 'h'
tomwalters@0 1241 x=ud.crosshair.xctr;
tomwalters@0 1242 case 'v'
tomwalters@0 1243 y=ud.crosshair.yctr;
tomwalters@0 1244 end
tomwalters@0 1245
tomwalters@0 1246 % Constrain to axis limits, so we don't lose cursor:
tomwalters@0 1247 if any(sel=='v'),
tomwalters@0 1248 xlim=get(hax,'xlim');
tomwalters@0 1249 if x<xlim(1),
tomwalters@0 1250 x=xlim(1);
tomwalters@0 1251 elseif x>xlim(2),
tomwalters@0 1252 x=xlim(2);
tomwalters@0 1253 end
tomwalters@0 1254 end
tomwalters@0 1255
tomwalters@0 1256 if any(sel=='h'),
tomwalters@0 1257 ylim=get(hax,'ylim');
tomwalters@0 1258 if y<ylim(1),
tomwalters@0 1259 y=ylim(1);
tomwalters@0 1260 elseif y>ylim(2),
tomwalters@0 1261 y=ylim(2);
tomwalters@0 1262 end
tomwalters@0 1263 end
tomwalters@0 1264 set_crosshairs(hfig,x,y);
tomwalters@0 1265
tomwalters@0 1266 %---------------------------------------------------------------
tomwalters@0 1267 function wbmotion_segment(hco,eventStruct,hfig)
tomwalters@0 1268 % motion callback during segmentation selection
tomwalters@0 1269
tomwalters@0 1270 % xxx
tomwalters@0 1271 % Get current point in axis ASAP:
tomwalters@0 1272 if nargin<3,
tomwalters@0 1273 hfig = gcbf;
tomwalters@0 1274 end
tomwalters@0 1275
tomwalters@0 1276 hax=gco;
tomwalters@0 1277 t=get(hax,'type');
tomwalters@0 1278 if ~strcmp(t,'axes'),
tomwalters@0 1279 hax = get(hax,'parent');
tomwalters@0 1280 end
tomwalters@0 1281 cp = get(hax,'currentpoint');
tomwalters@0 1282 ud = get(hfig,'userdata');
tomwalters@0 1283 x = cp(1,1);
tomwalters@0 1284 y = cp(1,2);
tomwalters@0 1285
tomwalters@0 1286 % Constrain to axis limits, so we don't lose cursor:
tomwalters@0 1287 xlim=get(hax,'xlim');
tomwalters@0 1288 if x<xlim(1),
tomwalters@0 1289 x=xlim(1);
tomwalters@0 1290 elseif x>xlim(2),
tomwalters@0 1291 x=xlim(2);
tomwalters@0 1292 end
tomwalters@0 1293 ylim=get(hax,'ylim');
tomwalters@0 1294 if y<ylim(1),
tomwalters@0 1295 y=ylim(1);
tomwalters@0 1296 elseif y>ylim(2),
tomwalters@0 1297 y=ylim(2);
tomwalters@0 1298 end
tomwalters@0 1299
tomwalters@0 1300 update_time_readout(hfig,x);
tomwalters@0 1301 update_freq_readout(hfig,y);
tomwalters@0 1302 clear_dB_readout(hfig);
tomwalters@0 1303
tomwalters@0 1304 %---------------------------------------------------------------
tomwalters@0 1305 function install_cursorfcns(hfig,cursorType)
tomwalters@0 1306
tomwalters@0 1307 switch lower(cursorType)
tomwalters@0 1308 case 'none'
tomwalters@0 1309 dn = [];
tomwalters@0 1310 motion = [];
tomwalters@0 1311 up = [];
tomwalters@0 1312 status = '';
tomwalters@0 1313
tomwalters@0 1314 case 'general'
tomwalters@0 1315 dn = [];
tomwalters@0 1316 motion = @wbmotion_general;
tomwalters@0 1317 up = [];
tomwalters@0 1318 status = 'Ready';
tomwalters@0 1319
tomwalters@0 1320 case 'segment'
tomwalters@0 1321 dn = @wbdown_segment;
tomwalters@0 1322 motion = @wbmotion_general;
tomwalters@0 1323 up = [];
tomwalters@0 1324 status = 'Ready';
tomwalters@0 1325
tomwalters@0 1326 case 'segment_buttondown'
tomwalters@0 1327 dn = [];
tomwalters@0 1328 motion = @wbmotion_segment;
tomwalters@0 1329 up = @wbup_segment;
tomwalters@0 1330 status = 'Difference from crosshair';
tomwalters@0 1331
tomwalters@0 1332 case 'thumb'
tomwalters@0 1333 % button not pushed, thumbnail highlighted
tomwalters@0 1334 dn = @wbdown_thumb;
tomwalters@0 1335 motion = @wbmotion_general;
tomwalters@0 1336 up = [];
tomwalters@0 1337 status = 'Pan zoom window';
tomwalters@0 1338
tomwalters@0 1339 case 'thumb_buttondown'
tomwalters@0 1340 % button pushed, thumbnail highlighted
tomwalters@0 1341 dn = [];
tomwalters@0 1342 motion = @wbmotion_thumb;
tomwalters@0 1343 up = @wbup_thumb;
tomwalters@0 1344 status = 'Release to set zoom window';
tomwalters@0 1345
tomwalters@0 1346 case 'thumbleft'
tomwalters@0 1347 % button not pushed, left thumbnail edge highlighted
tomwalters@0 1348 dn = @wbdown_thumbleft;
tomwalters@0 1349 motion = @wbmotion_general;
tomwalters@0 1350 up = [];
tomwalters@0 1351 status = 'Adjust zoom window left edge';
tomwalters@0 1352
tomwalters@0 1353 case 'thumbleft_buttondown'
tomwalters@0 1354 % button pushed, thumbnail highlighted
tomwalters@0 1355 dn = [];
tomwalters@0 1356 motion = @wbmotion_thumbleft;
tomwalters@0 1357 up = @wbup_thumbleft;
tomwalters@0 1358 status = 'Release to set zoom window';
tomwalters@0 1359
tomwalters@0 1360 case 'thumbright'
tomwalters@0 1361 % button not pushed, right thumbnail edge highlighted
tomwalters@0 1362 dn = @wbdown_thumbright;
tomwalters@0 1363 motion = @wbmotion_general;
tomwalters@0 1364 up = [];
tomwalters@0 1365 status = 'Adjust zoom window right edge';
tomwalters@0 1366
tomwalters@0 1367 case 'thumbright_buttondown'
tomwalters@0 1368 % button pushed, right thumbnail edge highlighted
tomwalters@0 1369 dn = [];
tomwalters@0 1370 motion = @wbmotion_thumbright;
tomwalters@0 1371 up = @wbup_thumbright;
tomwalters@0 1372 status = 'Release to set zoom window';
tomwalters@0 1373
tomwalters@0 1374 case 'hcross'
tomwalters@0 1375 % button not pushed, h-crosshair highlighted
tomwalters@0 1376 dn = @wbdown_hcross;
tomwalters@0 1377 motion = @wbmotion_general;
tomwalters@0 1378 up = [];
tomwalters@0 1379 status = 'Move horizontal cursor';
tomwalters@0 1380
tomwalters@0 1381 case 'hcross_buttondown'
tomwalters@0 1382 % button pushed while over horiz cross-hair
tomwalters@0 1383 dn = [];
tomwalters@0 1384 motion = {@wbmotion_cross,'h'};
tomwalters@0 1385 up = @wbup_hcross;
tomwalters@0 1386 status = 'Release to update cursor';
tomwalters@0 1387
tomwalters@0 1388 case 'vcross'
tomwalters@0 1389 dn = @wbdown_vcross;
tomwalters@0 1390 motion = @wbmotion_general;
tomwalters@0 1391 up = [];
tomwalters@0 1392 status = 'Move vertical cursor';
tomwalters@0 1393
tomwalters@0 1394 case 'vcross_buttondown'
tomwalters@0 1395 dn = [];
tomwalters@0 1396 motion = {@wbmotion_cross,'v'};
tomwalters@0 1397 up = @wbup_vcross;
tomwalters@0 1398 status = 'Release to update cursor';
tomwalters@0 1399
tomwalters@0 1400 case 'hvcross'
tomwalters@0 1401 dn = @wbdown_hvcross;
tomwalters@0 1402 motion = @wbmotion_general;
tomwalters@0 1403 up = [];
tomwalters@0 1404 status = 'Move crosshair cursor';
tomwalters@0 1405
tomwalters@0 1406 case 'hvcross_buttondown'
tomwalters@0 1407 dn = [];
tomwalters@0 1408 motion = {@wbmotion_cross,'hv'};
tomwalters@0 1409 up = @wbup_hvcross;
tomwalters@0 1410 status = 'Release to update cursor';
tomwalters@0 1411
tomwalters@0 1412 % Change dynamic range of colormap
tomwalters@0 1413 case 'cmap'
tomwalters@0 1414 dn = @wbdown_cmap;
tomwalters@0 1415 motion = @wbmotion_general;
tomwalters@0 1416 up = [];
tomwalters@0 1417 % Status is set in wbmotion_general function
tomwalters@0 1418 % since it depends on which pointer we're using
tomwalters@0 1419 status = -1;
tomwalters@0 1420
tomwalters@0 1421 case 'cmap_buttondown'
tomwalters@0 1422 dn = [];
tomwalters@0 1423 motion = @wbmotion_cmap;
tomwalters@0 1424 up = @wbup_cmap;
tomwalters@0 1425 status = 'Release to update colormap';
tomwalters@0 1426
tomwalters@0 1427 otherwise
tomwalters@0 1428 error('Unrecognized cursorfcn');
tomwalters@0 1429 end
tomwalters@0 1430
tomwalters@0 1431 set(hfig, ...
tomwalters@0 1432 'windowbuttondownfcn', dn, ...
tomwalters@0 1433 'windowbuttonmotionfcn',motion, ...
tomwalters@0 1434 'windowbuttonupfcn', up)
tomwalters@0 1435
tomwalters@0 1436 update_status(hfig,status);
tomwalters@0 1437
tomwalters@0 1438
tomwalters@0 1439 %---------------------------------------------------------------
tomwalters@0 1440 function resize_fig(hco,eventStruct)
tomwalters@0 1441 % Callback to resize the figure
tomwalters@0 1442
tomwalters@0 1443 update_axes_with_eng_units(gcbf);
tomwalters@0 1444
tomwalters@0 1445
tomwalters@0 1446 %---------------------------------------------------------------
tomwalters@0 1447 function update_axes_with_eng_units(hfig)
tomwalters@0 1448
tomwalters@0 1449 % Update the tick marks for axes that are using engineering units
tomwalters@0 1450 % For example, a resize could have added or removed ticks, and the
tomwalters@0 1451 % axes would no longer have the proper tick marks
tomwalters@0 1452 ud = get(hfig,'userdata');
tomwalters@0 1453 hax_time = ud.hax(2);
tomwalters@0 1454 hax_freq = ud.hax(4);
tomwalters@0 1455
tomwalters@0 1456 % Update freq-axis labels for engineering units, etc:
tomwalters@0 1457 yy=get(hax_freq,'ytick');
tomwalters@0 1458 [cs,eu] = convert2engstrs(yy);
tomwalters@0 1459 set(hax_freq,'yticklabel',cs);
tomwalters@0 1460 set(get(hax_freq,'ylabel'),'string',['Frequency, ' eu 'Hz']);
tomwalters@0 1461
tomwalters@0 1462 % Update time-axis labels for engineering units, etc:
tomwalters@0 1463 yy=get(hax_time,'xtick');
tomwalters@0 1464 [cs,eu] = convert2engstrs(yy,'time');
tomwalters@0 1465 set(hax_time,'xticklabel',cs);
tomwalters@0 1466 set(get(hax_time,'xlabel'),'string',['Time, ' eu]);
tomwalters@0 1467
tomwalters@0 1468
tomwalters@0 1469 %---------------------------------------------------------------
tomwalters@0 1470 function update_gui(hco, eventStruct, hfig)
tomwalters@0 1471
tomwalters@0 1472 if nargin<3, hfig=gcbf; end
tomwalters@0 1473
tomwalters@0 1474 ptr.ptr = get(hfig,'pointer');
tomwalters@0 1475 ptr.shape = get(hfig,'pointershapecdata');
tomwalters@0 1476 ptr.hot = get(hfig,'pointershapehotspot');
tomwalters@0 1477 setptr(hfig,'watch'); % set user's expectations...
tomwalters@0 1478
tomwalters@0 1479 ud = get(hfig,'userdata');
tomwalters@0 1480 hax_spec = ud.hax(1);
tomwalters@0 1481 hax_time = ud.hax(2);
tomwalters@0 1482 hax_tslice = ud.hax(3);
tomwalters@0 1483 hax_freq = ud.hax(4);
tomwalters@0 1484 hax_cbar = ud.hax(5);
tomwalters@0 1485 hax_cbar_ind = ud.hax(6);
tomwalters@0 1486
tomwalters@0 1487 % Get spectrogram parameters:
tomwalters@0 1488 Nwin = str2double(get(ud.spect.nwin,'string'));
tomwalters@0 1489 Nlap = str2double(get(ud.spect.nlap,'string'));
tomwalters@0 1490 Nfft = str2double(get(ud.spect.nfft,'string'));
tomwalters@0 1491
tomwalters@0 1492 % Recompute spectrogram
tomwalters@0 1493 y = ud.y;
tomwalters@0 1494 Fs = ud.Fs;
tomwalters@0 1495 window = 'blackman';
tomwalters@0 1496 w = feval(window,Nwin,'periodic');
tomwalters@0 1497 try
tomwalters@0 1498 [b,f,t]=specgram(y,Nfft,Fs,w,Nlap);
tomwalters@0 1499 [Pxx, W] = pwelch(y,w,Nlap,Nfft,Fs);
tomwalters@0 1500 catch
tomwalters@0 1501 % Error occurred
tomwalters@0 1502 % Put up modal error display, then
tomwalters@0 1503 % get spectrogram params from cache (userdata)
tomwalters@0 1504 msg = lasterr;
tomwalters@0 1505 errordlg(msg,'Specgram Demo Error','modal');
tomwalters@0 1506
tomwalters@0 1507 % Reset Nwin/Nlap/Nfft:
tomwalters@0 1508 Nwin = get(ud.spect.nwin,'userdata');
tomwalters@0 1509 Nlap = get(ud.spect.nlap,'userdata');
tomwalters@0 1510 Nfft = get(ud.spect.nfft,'userdata');
tomwalters@0 1511 set(ud.spect.nwin,'string',num2str(Nwin));
tomwalters@0 1512 set(ud.spect.nlap,'string',num2str(Nlap));
tomwalters@0 1513 set(ud.spect.nfft,'string',num2str(Nfft));
tomwalters@0 1514 return
tomwalters@0 1515 end
tomwalters@0 1516
tomwalters@0 1517 % Update new values into "old" cache (userdata field)
tomwalters@0 1518 % Also, update strings themselves, in case spaces have
tomwalters@0 1519 % been removed, etc:
tomwalters@0 1520 set(ud.spect.nwin,'string',num2str(Nwin),'userdata',Nwin);
tomwalters@0 1521 set(ud.spect.nlap,'string',num2str(Nlap),'userdata',Nlap);
tomwalters@0 1522 set(ud.spect.nfft,'string',num2str(Nfft),'userdata',Nfft);
tomwalters@0 1523
tomwalters@0 1524 ud.f = f;
tomwalters@0 1525 ud.t = t;
tomwalters@0 1526
tomwalters@0 1527 % Pxx is the distribution of power per unit frequency.
tomwalters@0 1528 ud.Pxx = Pxx;
tomwalters@0 1529
tomwalters@0 1530 % W is the vector of normalized frequencies at which the PSD is estimated.
tomwalters@0 1531 ud.w = W;
tomwalters@0 1532
tomwalters@0 1533 % Carefully execute log10:
tomwalters@0 1534 wstate=warning;
tomwalters@0 1535 warning off;
tomwalters@0 1536 b = 20*log10(abs(b));
tomwalters@0 1537 warning(wstate);
tomwalters@0 1538
tomwalters@0 1539 % Handle -inf's:
tomwalters@0 1540 i_inf = find(isinf(b(:)));
tomwalters@0 1541 if ~isempty(i_inf),
tomwalters@0 1542 % Set all -inf points to next-lowest value:
tomwalters@0 1543 b(i_inf)=inf;
tomwalters@0 1544 min_val=min(b(:));
tomwalters@0 1545 b(i_inf)=min_val;
tomwalters@0 1546 end
tomwalters@0 1547
tomwalters@0 1548 blim = [min(b(:)) max(b(:))];
tomwalters@0 1549 spec_xlim = [0 max(t)];
tomwalters@0 1550 spec_ylim = [0 max(f)];
tomwalters@0 1551
tomwalters@0 1552 % Update spectrogram
tomwalters@0 1553 % XXX UINT8 change:
tomwalters@0 1554 set(ud.himage,'cdata',b, 'xdata',t, 'ydata',f);
tomwalters@0 1555 %set(ud.himage,'cdata',uint8( (b-blim(1))./(blim(2)-blim(1))*255 + 1 ), 'xdata',t, 'ydata',f);
tomwalters@0 1556 set(hax_spec,'xlim',spec_xlim, 'ylim', spec_ylim);
tomwalters@0 1557
tomwalters@0 1558 % Update colorbar
tomwalters@0 1559 %XXX UINT8 change:
tomwalters@0 1560 set(ud.himage_cbar, 'ydata',blim, 'cdata', (1:256)');
tomwalters@0 1561 %set(ud.himage_cbar, 'ydata',[1 256], 'cdata', (1:256)');
tomwalters@0 1562 set(hax_cbar,'ylim',blim);
tomwalters@0 1563 set(hax_cbar_ind, 'ylim',blim);
tomwalters@0 1564
tomwalters@0 1565 % Update time slice
tomwalters@0 1566 rows=size(b,1);
tomwalters@0 1567 bi=floor(rows/2); if bi<1, bi=1; end
tomwalters@0 1568 set(ud.htslice_line,'xdata',t, 'ydata',b(bi,:));
tomwalters@0 1569 set(hax_tslice, 'xlim',spec_xlim, 'ylim',blim);
tomwalters@0 1570 % Use 2 ticks only
tomwalters@0 1571 new_ticks = return2ticks(hax_tslice);
tomwalters@0 1572 set(hax_tslice,'Ytick',new_ticks);
tomwalters@0 1573
tomwalters@0 1574 % frequency slice
tomwalters@0 1575 cols=size(b,2);
tomwalters@0 1576 bj=floor(cols/2); if bj<1, bj=1; end
tomwalters@0 1577 set(ud.hfreq_line, 'xdata',b(:,bj),'ydata',f);
tomwalters@0 1578 set(hax_freq, 'ylim',spec_ylim,'xlim',blim);
tomwalters@0 1579
tomwalters@0 1580 % Use 2 ticks only
tomwalters@0 1581 new_xticks = return2ticks(ud.hax(4));
tomwalters@0 1582 set(ud.hax(4),'Xtick',new_xticks);
tomwalters@0 1583
tomwalters@0 1584
tomwalters@0 1585 % full time trace
tomwalters@0 1586 ylen=length(y);
tomwalters@0 1587 half_nfft = ceil(Nfft/2);
tomwalters@0 1588 t1=(0 : length(y)-half_nfft)/Fs;
tomwalters@0 1589 set(ud.htime_plot,'xdata',t1,'ydata',y(half_nfft:end));
tomwalters@0 1590 set(hax_time, 'xlim',spec_xlim);
tomwalters@0 1591
tomwalters@0 1592 update_axes_with_eng_units(hfig);
tomwalters@0 1593
tomwalters@0 1594 % setup thumbnail patch
tomwalters@0 1595 axylim = get(hax_time,'ylim');
tomwalters@0 1596 ymax = axylim(2);
tomwalters@0 1597 ymin = axylim(1);
tomwalters@0 1598 tmax = max(t);
tomwalters@0 1599 tmin = min(t);
tomwalters@0 1600 set(ud.hthumb, ...
tomwalters@0 1601 'xdata',[tmin tmax tmax tmin tmin], ...
tomwalters@0 1602 'ydata',[ymin ymin ymax ymax ymin]);
tomwalters@0 1603
tomwalters@0 1604 % Reset crosshair positions
tomwalters@0 1605 crosshair = ud.crosshair;
tomwalters@0 1606 crosshair.xctr = mean(spec_xlim);
tomwalters@0 1607 crosshair.yctr = mean(spec_ylim);
tomwalters@0 1608 time_ylim = get(hax_time,'ylim');
tomwalters@0 1609 freq_xlim = get(hax_freq,'xlim');
tomwalters@0 1610 tslice_ylim = get(hax_tslice,'ylim');
tomwalters@0 1611
tomwalters@0 1612 % Crosshairs:
tomwalters@0 1613 set(ud.hspec_x, ...
tomwalters@0 1614 'xdata',spec_xlim, ...
tomwalters@0 1615 'ydata',[crosshair.yctr crosshair.yctr]);
tomwalters@0 1616 set(ud.hspec_y, ...
tomwalters@0 1617 'xdata',[crosshair.xctr crosshair.xctr], ...
tomwalters@0 1618 'ydata',spec_ylim);
tomwalters@0 1619 set(ud.htime_y, ...
tomwalters@0 1620 'xdata',[crosshair.xctr crosshair.xctr], ...
tomwalters@0 1621 'ydata',time_ylim);
tomwalters@0 1622 set(ud.htslice_y, ...
tomwalters@0 1623 'xdata',[crosshair.xctr crosshair.xctr], ...
tomwalters@0 1624 'ydata',tslice_ylim);
tomwalters@0 1625 set(ud.hfreq_x, ...
tomwalters@0 1626 'xdata',freq_xlim, ...
tomwalters@0 1627 'ydata',[crosshair.yctr crosshair.yctr]);
tomwalters@0 1628
tomwalters@0 1629 % Colormap indicator triangle:
tomwalters@0 1630 dy_tri=.025*diff(blim);
tomwalters@0 1631 yp=b(bi,bj);
tomwalters@0 1632 ytri=[yp+dy_tri yp-dy_tri yp ];
tomwalters@0 1633 set(ud.hcmap_arrow, ...
tomwalters@0 1634 'erase','xor', ...
tomwalters@0 1635 'linestyle','none', ...
tomwalters@0 1636 'xdata',[0 0 1], ...
tomwalters@0 1637 'ydata',ytri);
tomwalters@0 1638 crosshair.cbar.dy_tri = dy_tri;
tomwalters@0 1639
tomwalters@0 1640 % Update user data:
tomwalters@0 1641 ud.crosshair = crosshair;
tomwalters@0 1642 set(hfig,'userdata',ud);
tomwalters@0 1643
tomwalters@0 1644 % Text readouts:
tomwalters@0 1645 update_time_readout(hfig);
tomwalters@0 1646 update_freq_readout(hfig);
tomwalters@0 1647 update_dB_readout(hfig);
tomwalters@0 1648 %xxx
tomwalters@0 1649 %str=[num2str(b(bi,bj)) ' dB'];
tomwalters@0 1650 %set(ud.htext_mag,'string',str);
tomwalters@0 1651
tomwalters@0 1652 % Re-establish pointer cursor, etc:
tomwalters@0 1653 set(hfig,'pointer',ptr.ptr, ...
tomwalters@0 1654 'pointershapecdata',ptr.shape, ...
tomwalters@0 1655 'pointershapehotspot',ptr.hot);
tomwalters@0 1656
tomwalters@0 1657 %---------------------------------------------------------------
tomwalters@0 1658 function printdlg_cb(hco,eventStruct)
tomwalters@0 1659 printdlg(gcbf);
tomwalters@0 1660
tomwalters@0 1661 %---------------------------------------------------------------
tomwalters@0 1662 function printpreview_cb(hco,eventStruct)
tomwalters@0 1663 printpreview(gcbf);
tomwalters@0 1664
tomwalters@0 1665 %---------------------------------------------------------------
tomwalters@0 1666 function close_cb(hco,eventStruct)
tomwalters@0 1667 close(gcbf);
tomwalters@0 1668
tomwalters@0 1669 %---------------------------------------------------------------
tomwalters@0 1670 function hfig=create_gui(y,Fs,tmin,tmax)
tomwalters@0 1671 %CREATE_GUI Render the figure and all uicontrols.
tomwalters@0 1672
tomwalters@0 1673 % freq, specgram and time
tomwalters@0 1674 hfig = figure('numbertitle','off', ...
tomwalters@0 1675 'name','Spectrogram Demo', ...
tomwalters@0 1676 'menubar','none', ...
tomwalters@0 1677 'toolbar','none', ...
tomwalters@0 1678 'resizefcn',@resize_fig, ...
tomwalters@0 1679 'doublebuffer','off', ...
tomwalters@0 1680 'backingstore','off', ...
tomwalters@0 1681 'integerhandle','off', ...
tomwalters@0 1682 'vis','off', ...
tomwalters@0 1683 'pos',[50 15 550 450],...
tomwalters@0 1684 'PaperPositionMode','auto');
tomwalters@0 1685
tomwalters@0 1686 % Try to create audioplayer object for audio playback and tracking cursor
tomwalters@0 1687 audioplayer_enabled = true;
tomwalters@0 1688 try
tomwalters@0 1689 player = audioplayer(y / abs(max(y)), Fs); %make a player for the normalized signal
tomwalters@0 1690 set(player, 'UserData', hfig, 'TimerPeriod', 0.05, 'TimerFcn', @update_audio_position, ...
tomwalters@0 1691 'StartFcn', @start_function);
tomwalters@0 1692 % the toolbar callback fcns look for these named bits of appdata
tomwalters@0 1693 setappdata(hfig, 'theAudioPlayer', player);
tomwalters@0 1694 setappdata(hfig, 'theAudioRecorder', []);
tomwalters@0 1695 selection.inPoint = tmin*Fs;
tomwalters@0 1696 selection.outPoint = tmax*Fs;
tomwalters@0 1697 setappdata(hfig, 'audioSelection', selection); % selection starts as "full"
tomwalters@0 1698 catch
tomwalters@0 1699 audioplayer_enabled = false;
tomwalters@0 1700 end
tomwalters@0 1701
tomwalters@0 1702 % Load toolbar icons
tomwalters@0 1703 icon_file = 'specgramdemoicons.mat';
tomwalters@0 1704 icon = load(icon_file);
tomwalters@0 1705
tomwalters@0 1706 % Create toolbar:
tomwalters@0 1707 htoolbar = uitoolbar(hfig);
tomwalters@0 1708
tomwalters@0 1709 % Print:
tomwalters@0 1710 uipushtool('parent',htoolbar, ...
tomwalters@0 1711 'tooltip','Print', ...
tomwalters@0 1712 'clickedcallback',@printdlg_cb, ...
tomwalters@0 1713 'cdata',icon.print);
tomwalters@0 1714 % Print preview:
tomwalters@0 1715 uipushtool('parent',htoolbar, ...
tomwalters@0 1716 'tooltip','Print Preview', ...
tomwalters@0 1717 'clickedcallback',@printpreview_cb, ...
tomwalters@0 1718 'cdata',icon.printpreview);
tomwalters@0 1719
tomwalters@0 1720 if audioplayer_enabled,
tomwalters@0 1721 % add Play/Pause/Stop audio toolbar buttons
tomwalters@0 1722 [htoolbar, audiobuttons] = render_basicaudiotoolbar(htoolbar);
tomwalters@0 1723
tomwalters@0 1724 % set play button to "active" version, because changing the button image
tomwalters@0 1725 % causes the whole darn window to repaint! Ick.
tomwalters@0 1726 play_button = audiobuttons(1);
tomwalters@0 1727 audioIcons = getappdata(htoolbar, 'audioButtonIcons');
tomwalters@0 1728 set(play_button, 'cdata', audioIcons.play_on);
tomwalters@0 1729 else
tomwalters@0 1730 % Play icon
tomwalters@0 1731 uipushtool('parent',htoolbar, ...
tomwalters@0 1732 'tooltip','Play', ...
tomwalters@0 1733 'clickedcallback',@play_sound, ...
tomwalters@0 1734 'cdata',icon.playsound);
tomwalters@0 1735 end
tomwalters@0 1736
tomwalters@0 1737 % Zoom in, out, full
tomwalters@0 1738 uipushtool('parent',htoolbar, ...
tomwalters@0 1739 'separator','on', ...
tomwalters@0 1740 'tooltip','Zoom 100%', ...
tomwalters@0 1741 'clickedcallback', @zoom_full, ...
tomwalters@0 1742 'cdata',icon.fullview);
tomwalters@0 1743 uipushtool('parent',htoolbar, ...
tomwalters@0 1744 'tooltip','Zoom In', ...
tomwalters@0 1745 'clickedcallback',@zoom_in, ...
tomwalters@0 1746 'cdata',icon.zoominx);
tomwalters@0 1747 uipushtool('parent',htoolbar, ...
tomwalters@0 1748 'tooltip','Zoom Out', ...
tomwalters@0 1749 'clickedcallback',@zoom_out, ...
tomwalters@0 1750 'cdata',icon.zoomoutx);
tomwalters@0 1751 % Center crosshairs
tomwalters@0 1752 uipushtool('parent',htoolbar, ...
tomwalters@0 1753 'tooltip','Center Crosshair', ...
tomwalters@0 1754 'clickedcallback',@center_cross, ...
tomwalters@0 1755 'separator','on', ...
tomwalters@0 1756 'cdata',icon.center_crosshair);
tomwalters@0 1757
tomwalters@0 1758 % What's this?
tomwalters@0 1759 uipushtool('parent',htoolbar, ...
tomwalters@0 1760 'separator','on', ...
tomwalters@0 1761 'tooltip','What''s This?', ...
tomwalters@0 1762 'clickedcallback',@HelpWhatsThisCB, ...
tomwalters@0 1763 'cdata',icon.whatsthis);
tomwalters@0 1764
tomwalters@0 1765 % specgram
tomwalters@0 1766 % inputs: t, f, b
tomwalters@0 1767 hax_spec = axes('pos',[.25 .275 .625 .525]);
tomwalters@0 1768 himage=image; axis xy; colormap(jet)
tomwalters@0 1769 set(himage,'erase','xor','cdatamapping','scaled');
tomwalters@0 1770 set(hax_spec, ...
tomwalters@0 1771 'box','on', ...
tomwalters@0 1772 'draw','fast', ...
tomwalters@0 1773 'xticklabel','');
tomwalters@0 1774 % xxx
tomwalters@0 1775 % Shut off image axis visibility
tomwalters@0 1776 set(hax_spec, 'vis','off');
tomwalters@0 1777
tomwalters@0 1778 % time slice
tomwalters@0 1779 hax_tslice = axes('pos',[.25 .825 .625 .1]);
tomwalters@0 1780 htslice_line=line('color','b');
tomwalters@0 1781 set(htslice_line,'erase','xor'); % xxx
tomwalters@0 1782 set(hax_tslice, ...
tomwalters@0 1783 'box','on', ...
tomwalters@0 1784 'fontsize',8, ...
tomwalters@0 1785 'draw','fast', ...
tomwalters@0 1786 'xticklabel','', ...
tomwalters@0 1787 'xtick',[], ...
tomwalters@0 1788 'yaxisloc','right');
tomwalters@0 1789 ylabel('dB');
tomwalters@0 1790 sz=size(y);
tomwalters@0 1791
tomwalters@0 1792 % Title of time slice plot
tomwalters@0 1793 [ey,ee,eu]=engunits(Fs,'latex');
tomwalters@0 1794 str=['Data=[' num2str(sz(1)) 'x' num2str(sz(2)) '], Fs=' ...
tomwalters@0 1795 num2str(ey) ' ' eu 'Hz'];
tomwalters@0 1796 title(str);
tomwalters@0 1797
tomwalters@0 1798 % colorbar
tomwalters@0 1799 cmapLen = 256;
tomwalters@0 1800 hax_cbar = axes('pos',[.91 .275 .03 .525]);
tomwalters@0 1801 himage_cbar = image([0 1],[0 1],(1:cmapLen)');
tomwalters@0 1802 set(himage_cbar,'cdatamapping','scaled','erase','none');
tomwalters@0 1803 set(hax_cbar, ...
tomwalters@0 1804 'draw','fast', ...
tomwalters@0 1805 'fontsize',8, ...
tomwalters@0 1806 'box','on', ...
tomwalters@0 1807 'xticklabel','', ...
tomwalters@0 1808 'Ydir','normal', 'YAxisLocation','right', 'xtick',[]);
tomwalters@0 1809
tomwalters@0 1810 % frequency slice
tomwalters@0 1811 hax_freq = axes('pos',[.1 .275 .125 .525]);
tomwalters@0 1812 hfreq_line=line('color','b');
tomwalters@0 1813 set(hfreq_line,'erase','xor');
tomwalters@0 1814 set(hax_freq, ...
tomwalters@0 1815 'fontsize',8, ...
tomwalters@0 1816 'box','on',...
tomwalters@0 1817 'draw','fast', ...
tomwalters@0 1818 'xdir','rev', ...
tomwalters@0 1819 'xaxisloc','top');
tomwalters@0 1820 ylabel('Frequency, Hz');
tomwalters@0 1821 xlabel('dB');
tomwalters@0 1822
tomwalters@0 1823 % colorbar indicator
tomwalters@0 1824 hax_cbar_ind = axes('pos',[.885+.01 .275 .015 .525]);
tomwalters@0 1825 set(hax_cbar_ind,'vis','off','xlim',[0 1],'ylim',[0 1], ...
tomwalters@0 1826 'draw','fast', ...
tomwalters@0 1827 'fontsize',8, ...
tomwalters@0 1828 'yaxisloc','right');
tomwalters@0 1829
tomwalters@0 1830 % full time trace
tomwalters@0 1831 % inputs: y, Fs
tomwalters@0 1832 hax_time = axes('pos',[.25 .15 .625 .1]);
tomwalters@0 1833 htime_plot = line('color','b');
tomwalters@0 1834 set(hax_time, ...
tomwalters@0 1835 'box','on',...
tomwalters@0 1836 'fontsize',8, ...
tomwalters@0 1837 'draw','fast', ...
tomwalters@0 1838 'yaxisloc','right');
tomwalters@0 1839 xlabel('Time, secs'); ylabel('Ampl');
tomwalters@0 1840
tomwalters@0 1841 % thumbnail patch
tomwalters@0 1842 %bgclr = get(0,'defaultuicontrolbackgr');
tomwalters@0 1843 %bgclr = get(0,'defaultfigurecolor');
tomwalters@0 1844 bgclr = 'b';
tomwalters@0 1845 hthumb = patch([0 0 1 1 0], [0 1 1 0 0], bgclr, ...
tomwalters@0 1846 'edgecolor','k', ...
tomwalters@0 1847 'erase','xor');
tomwalters@0 1848
tomwalters@0 1849 % Crosshairs:
tomwalters@0 1850 hspec_x=line('parent',hax_spec, ...
tomwalters@0 1851 'erase','xor');
tomwalters@0 1852 hspec_y=line('parent',hax_spec, ...
tomwalters@0 1853 'erase','xor');
tomwalters@0 1854 htime_y=line('parent',hax_time, ...
tomwalters@0 1855 'linewidth',2, ...
tomwalters@0 1856 'erase','xor');
tomwalters@0 1857 htslice_y=line('parent',hax_tslice, ...
tomwalters@0 1858 'erase','xor');
tomwalters@0 1859 hfreq_x=line('parent',hax_freq, ...
tomwalters@0 1860 'erase','xor');
tomwalters@0 1861
tomwalters@0 1862 % Colormap indicator triangle:
tomwalters@0 1863 hcmap_arrow=patch('parent',hax_cbar_ind, ...
tomwalters@0 1864 'xdata',[0 0 1], ...
tomwalters@0 1865 'ydata',[0 0 0]);
tomwalters@0 1866
tomwalters@0 1867 % Text readouts:
tomwalters@0 1868 % xxx
tomwalters@0 1869 hax_readout = axes('pos',[0.02 .09 .185 .15],'vis','off');
tomwalters@0 1870 patch([0 1 1 0 0],[0 0 1 1 0],'w');
tomwalters@0 1871 htext_time = text('parent',hax_readout, 'pos',[0.075 .8], ...
tomwalters@0 1872 'erase','xor');
tomwalters@0 1873 htext_freq = text('parent',hax_readout, 'pos',[0.075 .5], ...
tomwalters@0 1874 'erase','xor');
tomwalters@0 1875 htext_mag = text('parent',hax_readout, 'pos',[0.075 .2], ...
tomwalters@0 1876 'erase','xor');
tomwalters@0 1877
tomwalters@0 1878 % Status bar
tomwalters@0 1879 bgc=get(hfig,'color');
tomwalters@0 1880 hax_status = axes('pos',[0.005 0.01 .99 .04]);
tomwalters@0 1881 set(hax_status,'vis','off','xlim',[0 1],'ylim',[0 1]);
tomwalters@0 1882 % Main status:
tomwalters@0 1883 h1=line([0 .45 .45],[0 0 1],'color','w');
tomwalters@0 1884 h2=line([0 0 .45],[0 1 1],'color',[1 1 1]*0);
tomwalters@0 1885 htext_status = uicontrol('parent',hfig, ...
tomwalters@0 1886 'style','text', ...
tomwalters@0 1887 'units','norm', ...
tomwalters@0 1888 'pos',[.015 .012 .96-.55 .035], ...
tomwalters@0 1889 'horiz','left', ...
tomwalters@0 1890 'backgr',bgc, ...
tomwalters@0 1891 'string','Ready');
tomwalters@0 1892
tomwalters@0 1893 % Spectrogram controls:
tomwalters@0 1894 %
tomwalters@0 1895 % segment length
tomwalters@0 1896 ylen = length(y);
tomwalters@0 1897 Nfft = min(256,ylen);
tomwalters@0 1898 Nwin = Nfft;
tomwalters@0 1899 % Nlap = min(Nwin,ceil(Nwin/2));
tomwalters@0 1900 Nlap = min(Nwin,200);
tomwalters@0 1901 ud.spect.nwin_text = uicontrol('parent',hfig, ...
tomwalters@0 1902 'style','text', ...
tomwalters@0 1903 'units','norm', ...
tomwalters@0 1904 'pos', [.45 .012 .07 .035], ...
tomwalters@0 1905 'backgr',bgc, ...
tomwalters@0 1906 'horiz','right', ...
tomwalters@0 1907 'string','Nwin:');
tomwalters@0 1908 ud.spect.nwin = uicontrol('parent',hfig, ...
tomwalters@0 1909 'style','edit', ...
tomwalters@0 1910 'units','norm', ...
tomwalters@0 1911 'pos', [.45+.07+.005 .01 .08 .04], ...
tomwalters@0 1912 'backgr','white', ...
tomwalters@0 1913 'horiz','left', ...
tomwalters@0 1914 'string',num2str(Nwin), ...
tomwalters@0 1915 'callback',@update_gui);
tomwalters@0 1916 % overlap length
tomwalters@0 1917 ud.spect.nlap_text = uicontrol('parent',hfig, ...
tomwalters@0 1918 'style','text', ...
tomwalters@0 1919 'units','norm', ...
tomwalters@0 1920 'pos', [.61 .012 .06 .035], ...
tomwalters@0 1921 'backgr',bgc, ...
tomwalters@0 1922 'horiz','right', ...
tomwalters@0 1923 'string','Nlap:');
tomwalters@0 1924 ud.spect.nlap = uicontrol('parent',hfig, ...
tomwalters@0 1925 'style','edit', ...
tomwalters@0 1926 'units','norm', ...
tomwalters@0 1927 'pos', [.61+.06+.005 .01 .08 .04], ...
tomwalters@0 1928 'backgr','white', ...
tomwalters@0 1929 'horiz','left', ...
tomwalters@0 1930 'string',num2str(Nlap), ...
tomwalters@0 1931 'callback',@update_gui);
tomwalters@0 1932 % fft length
tomwalters@0 1933 ud.spect.nfft_text = uicontrol('parent',hfig, ...
tomwalters@0 1934 'style','text', ...
tomwalters@0 1935 'units','norm', ...
tomwalters@0 1936 'pos', [.76 .012 .05 .035], ...
tomwalters@0 1937 'backgr', bgc, ...
tomwalters@0 1938 'horiz','right', ...
tomwalters@0 1939 'string','Nfft:');
tomwalters@0 1940 ud.spect.nfft = uicontrol('parent',hfig, ...
tomwalters@0 1941 'style','edit', ...
tomwalters@0 1942 'units','norm', ...
tomwalters@0 1943 'pos', [.75+.06+.005 .01 .08 .04], ...
tomwalters@0 1944 'backgr','white', ...
tomwalters@0 1945 'horiz','left', ...
tomwalters@0 1946 'string',num2str(Nfft), ...
tomwalters@0 1947 'callback',@update_gui);
tomwalters@0 1948
tomwalters@0 1949 % Window
tomwalters@0 1950
tomwalters@0 1951 % Menus
tomwalters@0 1952 mFile = uimenu('parent',hfig,'label','&File');
tomwalters@0 1953 uimenu('parent',mFile,'label','&Print','callback',@printdlg_cb);
tomwalters@0 1954 uimenu('parent',mFile,'label','&Close', ...
tomwalters@0 1955 'callback',@close_cb,'separator','on');
tomwalters@0 1956
tomwalters@0 1957 uimenu('parent',hfig, 'label','&Window', ...
tomwalters@0 1958 'tag','winmenu', ...
tomwalters@0 1959 'callback', winmenu('callback'));
tomwalters@0 1960 %
tomwalters@0 1961 % Help menu:
tomwalters@0 1962 %
tomwalters@0 1963 mHelp = uimenu('parent',hfig,'label','&Help');
tomwalters@0 1964
tomwalters@0 1965 % Help -> Specgramdemo Help
tomwalters@0 1966 uimenu('parent',mHelp, ...
tomwalters@0 1967 'Label','Spectrogram Demo &Help', ...
tomwalters@0 1968 'Callback',@HelpSpecgramdemoCB);
tomwalters@0 1969
tomwalters@0 1970 % Help -> Signal Processing Toolbox Help
tomwalters@0 1971 uimenu('parent',mHelp, ...
tomwalters@0 1972 'Label','Signal Processing &Toolbox Help', ...
tomwalters@0 1973 'Callback',@HelpProductCB);
tomwalters@0 1974
tomwalters@0 1975 % Help -> What's This?
tomwalters@0 1976 uimenu('parent',mHelp, ...
tomwalters@0 1977 'Label','&What''s This?', ...
tomwalters@0 1978 'Callback', @HelpWhatsThisCB,...
tomwalters@0 1979 'Separator','On');
tomwalters@0 1980
tomwalters@0 1981 % Help -> Demos
tomwalters@0 1982 uimenu('parent',mHelp, ...
tomwalters@0 1983 'Label','&Demos', ...
tomwalters@0 1984 'Callback',@HelpDemosCB,...
tomwalters@0 1985 'Separator','On');
tomwalters@0 1986
tomwalters@0 1987 % Help -> About Signal Processing Toolbox
tomwalters@0 1988 uimenu('parent',mHelp, ...
tomwalters@0 1989 'Label','&About Signal Processing Toolbox', ...
tomwalters@0 1990 'Callback',@HelpAboutCB,...
tomwalters@0 1991 'Separator','On');
tomwalters@0 1992
tomwalters@0 1993 set(hfig,'colormap',jet(256));
tomwalters@0 1994
tomwalters@0 1995 % Retain info in figure userdata:
tomwalters@0 1996 ud.hfig = hfig;
tomwalters@0 1997 ud.hax = [hax_spec hax_time hax_tslice hax_freq hax_cbar hax_cbar_ind];
tomwalters@0 1998 ud.hspec_x = hspec_x;
tomwalters@0 1999 ud.hspec_y = hspec_y;
tomwalters@0 2000 ud.htime_y = htime_y;
tomwalters@0 2001 ud.htslice_y = htslice_y;
tomwalters@0 2002 ud.hfreq_x = hfreq_x;
tomwalters@0 2003 ud.hcmap_arrow = hcmap_arrow;
tomwalters@0 2004 ud.hfreq_line = hfreq_line;
tomwalters@0 2005 ud.htslice_line = htslice_line;
tomwalters@0 2006 ud.htime_plot = htime_plot;
tomwalters@0 2007 ud.htext_time = htext_time;
tomwalters@0 2008 ud.htext_freq = htext_freq;
tomwalters@0 2009 ud.htext_mag = htext_mag;
tomwalters@0 2010 ud.htext_status= htext_status;
tomwalters@0 2011 ud.crosshair = [];
tomwalters@0 2012 ud.himage = himage;
tomwalters@0 2013 ud.himage_cbar = himage_cbar;
tomwalters@0 2014 ud.hthumb = hthumb;
tomwalters@0 2015 ud.f=[];
tomwalters@0 2016 ud.t=[];
tomwalters@0 2017 ud.y=y;
tomwalters@0 2018 ud.Fs=Fs;
tomwalters@0 2019 ud.currPtr = ''; % current pointer
tomwalters@0 2020 ud.Pxx = [];
tomwalters@0 2021 ud.w = [];
tomwalters@0 2022
tomwalters@0 2023 % Set plot default modes:
tomwalters@0 2024 ud.plot.top = 'spectrogram_time_slice';
tomwalters@0 2025 ud.plot.left = 'spectrogram_freq_slice';
tomwalters@0 2026
tomwalters@0 2027 set(hfig,'userdata',ud);
tomwalters@0 2028
tomwalters@0 2029 winmenu(hfig); % Initialize the submenu, after ud is installed
tomwalters@0 2030
tomwalters@0 2031 % Protect GUI from user plots, etc:
tomwalters@0 2032 set([hfig ud.hax],'handlevis','callback');
tomwalters@0 2033
tomwalters@0 2034 % After GUI has all elements in it, install context help:
tomwalters@0 2035 install_context_help(hfig);
tomwalters@0 2036 install_context_menus(hfig);
tomwalters@0 2037
tomwalters@0 2038 % Populate GUI with data, limits, etc:
tomwalters@0 2039 update_gui([],[],hfig);
tomwalters@0 2040
tomwalters@0 2041 % Enable general (non-segmenting) mouse functions:
tomwalters@0 2042 install_cursorfcns(hfig,'general');
tomwalters@0 2043 set(hfig,'vis','on');
tomwalters@0 2044
tomwalters@0 2045 %%%%%%%%%%%%%%%%%%%%%%%%%%
tomwalters@0 2046 % inserted by S.Bleeck
tomwalters@0 2047 % switch to modal
tomwalters@0 2048 uiwait(hfig);
tomwalters@0 2049 %%%%%%%%%%%%%%%%%%%%%%%%%%
tomwalters@0 2050
tomwalters@0 2051
tomwalters@0 2052
tomwalters@0 2053 return
tomwalters@0 2054
tomwalters@0 2055 % ---------------------------------------------------------------
tomwalters@0 2056 % H E L P S Y S T E M
tomwalters@0 2057 % --------------------------------------------------------------
tomwalters@0 2058 %
tomwalters@0 2059 % General rules:
tomwalters@0 2060 % - Context menus that launch the "What's This?" item have their
tomwalters@0 2061 % tag set to 'WT?...', where the '...' is the "keyword" for the
tomwalters@0 2062 % help lookup system.
tomwalters@0 2063 %
tomwalters@0 2064
tomwalters@0 2065 %--------------------------------------------------------------
tomwalters@0 2066 function HelpWhatsThisBDown(hco,eventStruct)
tomwalters@0 2067 % HelpWhatsThisBDown Button-down function called from either
tomwalters@0 2068 % the menu-based "What's This?" function, or the toolbar icon.
tomwalters@0 2069
tomwalters@0 2070 hfig = gcbf;
tomwalters@0 2071 hOver = gcbo; % overobj('uicontrol'); % handle to object under pointer
tomwalters@0 2072
tomwalters@0 2073 % Restore pointer icon quickly:
tomwalters@0 2074 setptr(hfig,'arrow');
tomwalters@0 2075
tomwalters@0 2076 % Shut off button-down functions for uicontrols and the figure:
tomwalters@0 2077 hChildren = findobj(hfig);
tomwalters@0 2078 set(hChildren, 'ButtonDownFcn','');
tomwalters@0 2079 set(hfig,'WindowButtonDownFcn','');
tomwalters@0 2080
tomwalters@0 2081 % Restore GUI pointers, etc:
tomwalters@0 2082 wbmotion_general(hfig);
tomwalters@0 2083
tomwalters@0 2084 % Dispatch to context help:
tomwalters@0 2085 hc = get(hOver,'uicontextmenu');
tomwalters@0 2086 hm = get(hc,'children'); % menu(s) pointed to by context menu
tomwalters@0 2087
tomwalters@0 2088 % Multiple entries (children) of context-menu may be present
tomwalters@0 2089 % Tag is a string, but we may get a cell-array of strings if
tomwalters@0 2090 % multiple context menus are present:
tomwalters@0 2091 % Find 'What's This?' help entry
tomwalters@0 2092 tag = get(hm,'tag');
tomwalters@0 2093 helpIdx = find(strncmp(tag,'WT?',3));
tomwalters@0 2094 if ~isempty(helpIdx),
tomwalters@0 2095 % in case there were accidentally multiple 'WT?' entries,
tomwalters@0 2096 % take the first (and hopefully, the only) index:
tomwalters@0 2097 if iscell(tag),
tomwalters@0 2098 tag = tag{helpIdx(1)};
tomwalters@0 2099 end
tomwalters@0 2100 HelpGeneral([],[],tag);
tomwalters@0 2101 end
tomwalters@0 2102
tomwalters@0 2103 %--------------------------------------------------------------
tomwalters@0 2104 function HelpWhatsThisCB(hco, eventStruct)
tomwalters@0 2105 % HelpWhatsThisCB Get "What's This?" help
tomwalters@0 2106 % This mimics the context-menu help selection, but allows
tomwalters@0 2107 % cursor-selection of the help topic
tomwalters@0 2108
tomwalters@0 2109 % NOTE: Enabling context-help "destroys" the enable-state
tomwalters@0 2110 % of all uicontrols in the GUI. When the callback completes,
tomwalters@0 2111 % we must restore the enable states.
tomwalters@0 2112
tomwalters@0 2113 hfig = gcbf;
tomwalters@0 2114
tomwalters@0 2115 % Change pointer icon:
tomwalters@0 2116 setptr(hfig,'help');
tomwalters@0 2117
tomwalters@0 2118 % Install button-down functions on all uicontrols,
tomwalters@0 2119 % plus the figure itself:
tomwalters@0 2120 % uicontrol, axes, line, patch, text
tomwalters@0 2121 hChildren = findobj(hfig);
tomwalters@0 2122 % No need to set enable states, etc.
tomwalters@0 2123 set(hChildren, ...
tomwalters@0 2124 'ButtonDownFcn',@HelpWhatsThisBDown);
tomwalters@0 2125 set(hfig, ...
tomwalters@0 2126 'WindowButtonMotionFcn','', ...
tomwalters@0 2127 'WindowButtonUpFcn','', ...
tomwalters@0 2128 'WindowButtonDownFcn','');
tomwalters@0 2129
tomwalters@0 2130 %--------------------------------------------------------------
tomwalters@0 2131 function HelpSpecgramdemoCB(hco,eventStruct)
tomwalters@0 2132 %HELPSPECGRAMDEMO Get specgramdemo reference-page help
tomwalters@0 2133
tomwalters@0 2134 helpwin(mfilename);
tomwalters@0 2135
tomwalters@0 2136 %--------------------------------------------------------------
tomwalters@0 2137 function HelpProductCB(hco,eventStruct)
tomwalters@0 2138 %HELPRPODUCTCB Opens the Help window with the online doc Roadmap
tomwalters@0 2139 % page (a.k.a. "product page") displayed.
tomwalters@0 2140 doc signal/
tomwalters@0 2141
tomwalters@0 2142 %--------------------------------------------------------------
tomwalters@0 2143 function HelpDemosCB(hco,eventStruct)
tomwalters@0 2144 %HELPDEMOSCB Starts Demo window, with the appropriate product's
tomwalters@0 2145 % demo highlighted in the Demo window contents pane.
tomwalters@0 2146 demo toolbox signal
tomwalters@0 2147
tomwalters@0 2148 %--------------------------------------------------------------
tomwalters@0 2149 function HelpAboutCB(hco,eventStruct)
tomwalters@0 2150 %HELPABOUTCB Displays version number of product, and copyright.
tomwalters@0 2151
tomwalters@0 2152 aboutsignaltbx;
tomwalters@0 2153
tomwalters@0 2154 %--------------------------------------------------------------
tomwalters@0 2155 function HelpGeneral(hco,eventStruct,tag)
tomwalters@0 2156 % HelpGeneral Define CSH text for specgramdemo
tomwalters@0 2157
tomwalters@0 2158 hfig = gcbf;
tomwalters@0 2159 hco = gcbo;
tomwalters@0 2160
tomwalters@0 2161 if nargin<3,
tomwalters@0 2162 % Testing purposes only:
tomwalters@0 2163 tag = get(hco,'tag');
tomwalters@0 2164 end
tomwalters@0 2165
tomwalters@0 2166 % Check for legal tag string:
tomwalters@0 2167 if ~ischar(tag),
tomwalters@0 2168 error('Invalid context-sensitive help tag.');
tomwalters@0 2169 end
tomwalters@0 2170
tomwalters@0 2171 % Remove 'WT?' prefix;
tomwalters@0 2172 if strncmp(tag,'WT?',3),
tomwalters@0 2173 tag(1:3) = [];
tomwalters@0 2174 else
tomwalters@0 2175 error('Help tag must be a string beginning with "WT?" prefix.');
tomwalters@0 2176 end
tomwalters@0 2177
tomwalters@0 2178 ud = get(hfig,'UserData');
tomwalters@0 2179
tomwalters@0 2180 % Define text for CSH system
tomwalters@0 2181 title = ['Help: ' tag];
tomwalters@0 2182 msg = '';
tomwalters@0 2183 switch tag
tomwalters@0 2184 case ''
tomwalters@0 2185 msg = {'';
tomwalters@0 2186 'No help available on selected item.'};
tomwalters@0 2187
tomwalters@0 2188 case 'Spectrogram image'
tomwalters@0 2189 msg = {'';
tomwalters@0 2190 'This image displays the spectrogram for the signal currently loaded ';
tomwalters@0 2191 'in the viewer. The spectrogram presents the magnitude of the short-time ';
tomwalters@0 2192 'Fourier transform.';
tomwalters@0 2193 '';
tomwalters@0 2194 'Calculate the spectrogram as follows:';
tomwalters@0 2195 '';
tomwalters@0 2196 '1. Split the signal into overlapping sections and apply the';
tomwalters@0 2197 'window specified by the window parameter to each section.';
tomwalters@0 2198 '';
tomwalters@0 2199 '2. Compute the discrete-time Fourier transform of each';
tomwalters@0 2200 'section with a length Nfft FFT to estimate the short-term ';
tomwalters@0 2201 'frequency content of the signal. These transforms ';
tomwalters@0 2202 'make up the columns of B. The quantity (length(Nwin) - Nlap)'
tomwalters@0 2203 'specifies by how many samples the window will be shifted.';
tomwalters@0 2204 '';
tomwalters@0 2205 '3. For real input, truncate the spectrogram to the';
tomwalters@0 2206 'first (Nfft/2 + 1) points when Nfft is even and (Nfft + 1)/2 when ';
tomwalters@0 2207 'Nfft is odd.'};
tomwalters@0 2208
tomwalters@0 2209 case 'Zoom Window Panner'
tomwalters@0 2210 msg = {'';
tomwalters@0 2211 'Shows a panoramic view of the signal which is loaded in the viewer. ';
tomwalters@0 2212 'When you zoom in the spectrogram, the corresponding time domain ';
tomwalters@0 2213 'portion is highlighed.';
tomwalters@0 2214 '';
tomwalters@0 2215 'You can zoom the panner by dragging the mouse on the left- and ';
tomwalters@0 2216 'right-hand edges of the highlighted zoom region. Right-click the ';
tomwalters@0 2217 'highlighted zoom area to bring up a menu for focusing in on the zoomed ';
tomwalters@0 2218 'region'};
tomwalters@0 2219
tomwalters@0 2220 case 'Spectrogram Frequency Slice' % Left axes
tomwalters@0 2221 if strcmp(ud.plot.left,'spectrogram_freq_slice'),
tomwalters@0 2222 msg = {'';
tomwalters@0 2223 'This view displays a frequency slice for the current spectrogram. The ';
tomwalters@0 2224 'view is updated as you move the crosshair cursor along the frequency '
tomwalters@0 2225 'axes (horizontally).'};
tomwalters@0 2226 else
tomwalters@0 2227 % Change the helpwin title for the PSD case.
tomwalters@0 2228 title = ['Help: Signal Power Spectral Density'];
tomwalters@0 2229
tomwalters@0 2230 msg = {'';
tomwalters@0 2231 'Displays the Power Spectral Density (PSD) estimate calculated ';
tomwalters@0 2232 'using Welch''s averaged modified periodogram method.'};
tomwalters@0 2233
tomwalters@0 2234 end
tomwalters@0 2235
tomwalters@0 2236 case 'Spectrogram Time Slice', % Top axes
tomwalters@0 2237 msg = {'';
tomwalters@0 2238 'This view displays a time slice for the current spectrogram. The';
tomwalters@0 2239 'view is updated as you move the crosshair cursor along the time'
tomwalters@0 2240 'axes (vertically).'};
tomwalters@0 2241
tomwalters@0 2242 case 'Colorbar'
tomwalters@0 2243 msg = {'';
tomwalters@0 2244 'The colorbar shows the color scale for the current spectrogram.';
tomwalters@0 2245 ''};
tomwalters@0 2246
tomwalters@0 2247 case 'Status Bar',
tomwalters@0 2248 msg = {'';
tomwalters@0 2249 'The Status Bar displays information about the state of the ';
tomwalters@0 2250 'Spectrogram Demo, the current operation of the tool, and operation';
tomwalters@0 2251 'of the crosshair cursor.'};
tomwalters@0 2252
tomwalters@0 2253 case 'Magnitude Readout',
tomwalters@0 2254 msg = {'';
tomwalters@0 2255 'Displays the magnitude (in dB) of a spectrogram slice.';
tomwalters@0 2256 ''};
tomwalters@0 2257
tomwalters@0 2258 case 'Frequency Readout',
tomwalters@0 2259 msg = {'';
tomwalters@0 2260 'Displays frequency values in Hz.';
tomwalters@0 2261 ''};
tomwalters@0 2262
tomwalters@0 2263 case 'Time Readout',
tomwalters@0 2264 msg = {'';
tomwalters@0 2265 'Displays time measurements in seconds for the Time Plot ';
tomwalters@0 2266 'and the Time Slice'};
tomwalters@0 2267
tomwalters@0 2268 case 'Time Plot', % Bottom axes
tomwalters@0 2269 msg = {'';
tomwalters@0 2270 'Time Plot displays the original signal in its entirety.'};
tomwalters@0 2271
tomwalters@0 2272 case 'Colorbar Indicator',
tomwalters@0 2273 msg = {'';
tomwalters@0 2274 'The colorbar indicator points to the level of the spectrogram.'};
tomwalters@0 2275
tomwalters@0 2276 case 'Frequency Crosshair',
tomwalters@0 2277 msg = {'';
tomwalters@0 2278 'Move the frequency crosshair cursor to pin-point a particular ';
tomwalters@0 2279 'frequency location on the spectrogram''s frequency slice axes.'};
tomwalters@0 2280
tomwalters@0 2281 case 'Time Crosshair',
tomwalters@0 2282 msg = {'';
tomwalters@0 2283 'Move the time crosshair cursor to pin-point a particular ';
tomwalters@0 2284 'time instance on the spectrogram''s time slice axes.'};
tomwalters@0 2285
tomwalters@0 2286 case 'Spectrogram Demo',
tomwalters@0 2287 msg = {'';
tomwalters@0 2288 'This is the Spectrogram Demo which displays a spectrogram, ';
tomwalters@0 2289 'a time plot, and a frequency slice of an input signal';
tomwalters@0 2290 '';
tomwalters@0 2291 'SPECGRAMDEMO(y,Fs) displays a spectrogram of signal y, assuming a sample ';
tomwalters@0 2292 'rate of Fs Hz. If y is specified but Fs is not, a sample rate of 1 ';
tomwalters@0 2293 'Hz is assumed. If no input arguments are supplied, y and Fs are ';
tomwalters@0 2294 'taken from the default data file "mtlb.mat."'};
tomwalters@0 2295
tomwalters@0 2296 case 'Spectrogram Window Size',
tomwalters@0 2297 msg = {'';
tomwalters@0 2298 'Nwin specifies the length of the Periodic Blackman window used in ';
tomwalters@0 2299 'this demo. The default value is 256.'};
tomwalters@0 2300
tomwalters@0 2301 case 'Spectrogram FFT Size',
tomwalters@0 2302 msg = {'';
tomwalters@0 2303 'Nfft specifies the FFT length used to calculate the spectrogram. ';
tomwalters@0 2304 'This value determines the frequencies at which the discrete-time ';
tomwalters@0 2305 'Fourier transform is computed. These values are typically powers ';
tomwalters@0 2306 'of two, such as 256 or 512.'};
tomwalters@0 2307
tomwalters@0 2308 case 'Spectrogram Overlap'
tomwalters@0 2309 msg = {'';
tomwalters@0 2310 'Use Nlap to specify the number of samples to overlap the windowed sections.'};
tomwalters@0 2311 end
tomwalters@0 2312
tomwalters@0 2313 % If no text is defined, simply display the tag.
tomwalters@0 2314 if isempty(msg),
tomwalters@0 2315 msg = {'';
tomwalters@0 2316 ['This is the ' tag '.']};
tomwalters@0 2317 end
tomwalters@0 2318
tomwalters@0 2319 % Put up message box for help:
tomwalters@0 2320 %hmsg = msgbox(msg,title, 'help','modal');
tomwalters@0 2321 %CenterFigOnFig(hfig, hmsg);
tomwalters@0 2322
tomwalters@0 2323 helpwin(char(msg),title);
tomwalters@0 2324
tomwalters@0 2325 %--------------------------------------------------------------
tomwalters@0 2326 function CenterFigOnFig(hfig,hmsg)
tomwalters@0 2327 % CenterFigOnFig Center hMsg figure on top of hFig figure
tomwalters@0 2328
tomwalters@0 2329 set(hfig,'units','pix');
tomwalters@0 2330 figPos = get(hfig,'pos');
tomwalters@0 2331 figCtr = [figPos(1)+figPos(3)/2 figPos(2)+figPos(4)/2];
tomwalters@0 2332
tomwalters@0 2333 set(hmsg,'units','pix');
tomwalters@0 2334 msgPos = get(hmsg,'position');
tomwalters@0 2335 msgCtr = [msgPos(1)+msgPos(3)/2 msgPos(2)+msgPos(4)/2];
tomwalters@0 2336
tomwalters@0 2337 movePos = figCtr - msgCtr;
tomwalters@0 2338
tomwalters@0 2339 new_msgPos = msgPos;
tomwalters@0 2340 new_msgPos(1:2) = msgPos(1:2) + movePos;
tomwalters@0 2341 set(hmsg,'Position',new_msgPos);
tomwalters@0 2342
tomwalters@0 2343 return
tomwalters@0 2344
tomwalters@0 2345 %--------------------------------------------------------------
tomwalters@0 2346 function install_context_help(hfig)
tomwalters@0 2347
tomwalters@0 2348 ud = get(hfig,'userdata');
tomwalters@0 2349
tomwalters@0 2350 main = {'label','&What''s This?', ...
tomwalters@0 2351 'callback',@HelpGeneral, 'parent'};
tomwalters@0 2352
tomwalters@0 2353 setWTC(hfig,main, [ud.himage ud.hax(1)], 'Spectrogram image');
tomwalters@0 2354 setWTC(hfig,main, ud.hthumb, 'Zoom Window Panner');
tomwalters@0 2355 setWTC(hfig,main, [ud.himage_cbar ud.hax(5)], 'Colorbar');
tomwalters@0 2356 setWTC(hfig,main, ud.htext_status, 'Status Bar');
tomwalters@0 2357 setWTC(hfig,main, ud.htext_mag, 'Magnitude Readout');
tomwalters@0 2358 setWTC(hfig,main, ud.htext_freq, 'Frequency Readout');
tomwalters@0 2359 setWTC(hfig,main, ud.htext_time, 'Time Readout');
tomwalters@0 2360 setWTC(hfig,main, [ud.htime_plot ud.hax(2)], 'Time Plot');
tomwalters@0 2361 setWTC(hfig,main, [ud.htslice_line ud.hax(3)], 'Spectrogram Time Slice');
tomwalters@0 2362 setWTC(hfig,main, [ud.hfreq_line ud.hax(4)], 'Spectrogram Frequency Slice');
tomwalters@0 2363 setWTC(hfig,main, [ud.hcmap_arrow ud.hax(6)], 'Colorbar Indicator');
tomwalters@0 2364
tomwalters@0 2365 setWTC(hfig,main, [ud.hfreq_x ud.hspec_x], 'Frequency Crosshair');
tomwalters@0 2366 setWTC(hfig,main, [ud.htime_y ud.htslice_y ud.hspec_y], 'Time Crosshair');
tomwalters@0 2367 setWTC(hfig,main, ud.hfig, 'Spectrogram Demo');
tomwalters@0 2368
tomwalters@0 2369 setWTC(hfig,main, [ud.spect.nwin ud.spect.nwin_text], 'Spectrogram Window Size');
tomwalters@0 2370 setWTC(hfig,main, [ud.spect.nfft ud.spect.nfft_text], 'Spectrogram FFT Size');
tomwalters@0 2371 setWTC(hfig,main, [ud.spect.nlap ud.spect.nlap_text], 'Spectrogram Overlap');
tomwalters@0 2372
tomwalters@0 2373 % xxx set context for:
tomwalters@0 2374 % - readout axis
tomwalters@0 2375 % - uitoolbar
tomwalters@0 2376
tomwalters@0 2377 %--------------------------------------------------------------
tomwalters@0 2378 function setWTC(hfig,main,hItem,tagStr)
tomwalters@0 2379 % setWT Set the "What's This?" context menu and callback:
tomwalters@0 2380 hc = uicontextmenu('parent',hfig);
tomwalters@0 2381 uimenu(main{:},hc, 'tag',['WT?' tagStr]);
tomwalters@0 2382 set(hItem,'uicontextmenu',hc);
tomwalters@0 2383
tomwalters@0 2384
tomwalters@0 2385 % ---------------------------------------------------------------
tomwalters@0 2386 % C O N T E X T M E N U S
tomwalters@0 2387 % --------------------------------------------------------------
tomwalters@0 2388
tomwalters@0 2389 %-----------------------------------------------------------------
tomwalters@0 2390 function install_context_menus(hfig)
tomwalters@0 2391
tomwalters@0 2392 install_specgram_mode_menus(hfig);
tomwalters@0 2393 install_colorbar_menus(hfig);
tomwalters@0 2394 install_freq_slice_menus(hfig);
tomwalters@0 2395 install_time_slice_menus(hfig);
tomwalters@0 2396 install_time_panner_menus(hfig);
tomwalters@0 2397
tomwalters@0 2398 %-----------------------------------------------------------------
tomwalters@0 2399 function install_specgram_mode_menus(hfig)
tomwalters@0 2400
tomwalters@0 2401 % Additional menus to prepend to the spectrogram context menu:
tomwalters@0 2402
tomwalters@0 2403 ud = get(hfig,'userdata');
tomwalters@0 2404 hc = get(ud.himage,'uicontext'); % ud.hax(1) also?
tomwalters@0 2405
tomwalters@0 2406 hEntry=[]; % holds handles to each colormap menu item
tomwalters@0 2407 opts={hc,'2-D Image',@changeSpecgramMode, 'checked','on'};
tomwalters@0 2408 hEntry(end+1) = createContext(opts);
tomwalters@0 2409 opts={hc,'3-D Magnitude Plot',@changeSpecgramMode};
tomwalters@0 2410 hEntry(end+1) = createContext(opts);
tomwalters@0 2411 % xxx disable last menu until feature implemented:
tomwalters@0 2412 set(hEntry(end),'enable','off');
tomwalters@0 2413 opts={hc,'3-D dB Plot',@changeSpecgramMode};
tomwalters@0 2414 hEntry(end+1) = createContext(opts);
tomwalters@0 2415 % xxx disable last menu until feature implemented:
tomwalters@0 2416 set(hEntry(end),'enable','off');
tomwalters@0 2417
tomwalters@0 2418 % Give each menu item a vector of handles to all peer menus
tomwalters@0 2419 set(hEntry,'userdata',hEntry);
tomwalters@0 2420
tomwalters@0 2421 fixup_context_order(hc);
tomwalters@0 2422
tomwalters@0 2423 %-----------------------------------------------------------------
tomwalters@0 2424 function install_colorbar_menus(hfig)
tomwalters@0 2425 % Additional menus to prepend to the colorbar context menu:
tomwalters@0 2426
tomwalters@0 2427 ud = get(hfig,'userdata');
tomwalters@0 2428 hc = get(ud.himage_cbar,'uicontext'); % ud.hax(1) also?
tomwalters@0 2429
tomwalters@0 2430 opts={hc,'Colormap',''};
tomwalters@0 2431 hCmap = createContext(opts);
tomwalters@0 2432
tomwalters@0 2433 hEntry=[]; % holds handles to each colormap menu item
tomwalters@0 2434 opts={hCmap,'Jet',@changeCMap, 'checked','on'};
tomwalters@0 2435 hEntry(end+1) = createContext(opts);
tomwalters@0 2436 opts={hCmap,'Hot',@changeCMap};
tomwalters@0 2437 hEntry(end+1) = createContext(opts);
tomwalters@0 2438 opts={hCmap,'Gray',@changeCMap};
tomwalters@0 2439 hEntry(end+1) = createContext(opts);
tomwalters@0 2440 opts={hCmap,'Bone',@changeCMap};
tomwalters@0 2441 hEntry(end+1) = createContext(opts);
tomwalters@0 2442 opts={hCmap,'Copper',@changeCMap};
tomwalters@0 2443 hEntry(end+1) = createContext(opts);
tomwalters@0 2444 opts={hCmap,'Pink',@changeCMap};
tomwalters@0 2445 hEntry(end+1) = createContext(opts);
tomwalters@0 2446
tomwalters@0 2447 opts={hc,'Set Limits',@manual_cmap_limits, 'separator','on'};
tomwalters@0 2448 createContext(opts);
tomwalters@0 2449
tomwalters@0 2450 opts={hc,'Reset Limits',@reset_cmap_limits};
tomwalters@0 2451 createContext(opts);
tomwalters@0 2452
tomwalters@0 2453 % Give each menu item a vector of handles to all peer menus
tomwalters@0 2454 set(hEntry,'userdata',hEntry);
tomwalters@0 2455
tomwalters@0 2456 fixup_context_order(hc);
tomwalters@0 2457
tomwalters@0 2458 %-----------------------------------------------------------------
tomwalters@0 2459 function install_freq_slice_menus(hfig)
tomwalters@0 2460
tomwalters@0 2461 % Additional menus to prepend to the spectrogram context menu:
tomwalters@0 2462
tomwalters@0 2463 ud = get(hfig,'userdata');
tomwalters@0 2464 hax_freq = ud.hax(4);
tomwalters@0 2465 hc = get(hax_freq,'uicontext'); % ud.hax(1) also?
tomwalters@0 2466
tomwalters@0 2467 hEntry=[]; % holds handles to each colormap menu item
tomwalters@0 2468 opts={hc,'Marginal (specgram slice)',@changeFreqSliceMode, 'checked','on'};
tomwalters@0 2469 hEntry(end+1) = createContext(opts);
tomwalters@0 2470 %opts={hc,'Integrated (freq PSD)',@changeFreqSliceMode};
tomwalters@0 2471 opts={hc,'Power Spectral Density',@changeFreqSliceMode};
tomwalters@0 2472 hEntry(end+1) = createContext(opts);
tomwalters@0 2473 set(hEntry(end),'enable','on');
tomwalters@0 2474
tomwalters@0 2475 % Give each menu item a vector of handles to all peer menus
tomwalters@0 2476 set(hEntry,'userdata',hEntry);
tomwalters@0 2477
tomwalters@0 2478 fixup_context_order(hc);
tomwalters@0 2479
tomwalters@0 2480 %-----------------------------------------------------------------
tomwalters@0 2481 function install_time_slice_menus(hfig)
tomwalters@0 2482
tomwalters@0 2483 % Additional menus to prepend to the spectrogram context menu:
tomwalters@0 2484
tomwalters@0 2485 ud = get(hfig,'userdata');
tomwalters@0 2486 hax_tslice = ud.hax(3);
tomwalters@0 2487 hc = get(hax_tslice,'uicontext'); % ud.hax(1) also?
tomwalters@0 2488
tomwalters@0 2489 hEntry=[]; % holds handles to each colormap menu item
tomwalters@0 2490 opts={hc,'Marginal (specgram slice)',@changeTimeSliceMode, 'checked','on'};
tomwalters@0 2491 hEntry(end+1) = createContext(opts);
tomwalters@0 2492 opts={hc,'Integrated (time zoom)',@changeTimeSliceMode};
tomwalters@0 2493 hEntry(end+1) = createContext(opts);
tomwalters@0 2494
tomwalters@0 2495 % disable last menu until feature implemented:
tomwalters@0 2496 set(hEntry(end),'enable','off');
tomwalters@0 2497
tomwalters@0 2498 % Give each menu item a vector of handles to all peer menus
tomwalters@0 2499 set(hEntry,'userdata',hEntry);
tomwalters@0 2500
tomwalters@0 2501 fixup_context_order(hc);
tomwalters@0 2502
tomwalters@0 2503 %-----------------------------------------------------------------
tomwalters@0 2504 function install_time_panner_menus(hfig)
tomwalters@0 2505
tomwalters@0 2506 % Additional menus to prepend to the time-panner context menu:
tomwalters@0 2507
tomwalters@0 2508 ud = get(hfig,'userdata');
tomwalters@0 2509 hthumb = ud.hthumb; % XXX add to time axis as well?
tomwalters@0 2510 hc = get(hthumb, 'uicontext');
tomwalters@0 2511
tomwalters@0 2512 % Update the menu on-the-fly:
tomwalters@0 2513 set(hc,'callback', @focus_menu_render_callback);
tomwalters@0 2514
tomwalters@0 2515 hEntry=[]; % holds handles to each colormap menu item
tomwalters@0 2516
tomwalters@0 2517 opts={hc,'Focus In',@focusTimeIn};
tomwalters@0 2518 hEntry(end+1) = createContext(opts);
tomwalters@0 2519
tomwalters@0 2520 opts={hc,'Previous Focus',@focusTimePrev};
tomwalters@0 2521 hEntry(end+1) = createContext(opts);
tomwalters@0 2522
tomwalters@0 2523 opts={hc,'Reset Focus',@focusTimeReset};
tomwalters@0 2524 hEntry(end+1) = createContext(opts);
tomwalters@0 2525
tomwalters@0 2526 % Give each menu item a vector of handles to all peer menus
tomwalters@0 2527 set(hEntry,'userdata',hEntry);
tomwalters@0 2528
tomwalters@0 2529 fixup_context_order(hc);
tomwalters@0 2530
tomwalters@0 2531 update_focus_history_menu(hfig); % pass any focus context menu
tomwalters@0 2532
tomwalters@0 2533 %-----------------------------------------------------------------
tomwalters@0 2534 function hMenu=createContext(opts)
tomwalters@0 2535 % Helper function to append additional context menus
tomwalters@0 2536 args = {'parent',opts{1}, 'label',opts{2}, 'callback',opts{3:end}};
tomwalters@0 2537 hMenu=uimenu(args{:});
tomwalters@0 2538
tomwalters@0 2539 %-----------------------------------------------------------------
tomwalters@0 2540 function fixup_context_order(hContext)
tomwalters@0 2541 % Put the first context menu entry (the "What's This?" entry)
tomwalters@0 2542 % last in the context menu list, and turn on the separator
tomwalters@0 2543 % for the "What's This?" entry
tomwalters@0 2544 childList = get(hContext,'children');
tomwalters@0 2545 childList = childList([end 1:end-1]);
tomwalters@0 2546 set(hContext,'children',childList);
tomwalters@0 2547 set(childList(1),'separator','on');
tomwalters@0 2548
tomwalters@0 2549 %---------------------------------------------------------------
tomwalters@0 2550 function changeCMap(hco,eventStruct)
tomwalters@0 2551
tomwalters@0 2552 hco=gcbo; hfig=gcbf;
tomwalters@0 2553 % Reset checks on all colormap menu items:
tomwalters@0 2554 set(get(hco,'userdata'),'checked','off');
tomwalters@0 2555 set(hco,'checked','on');
tomwalters@0 2556
tomwalters@0 2557 % Update figure colormap:
tomwalters@0 2558 cmapStr = lower(get(hco,'label'));
tomwalters@0 2559 cmap = feval(cmapStr);
tomwalters@0 2560 set(hfig,'colormap',cmap);
tomwalters@0 2561
tomwalters@0 2562 %---------------------------------------------------------------
tomwalters@0 2563 function changeSpecgramMode(hco,eventStruct)
tomwalters@0 2564
tomwalters@0 2565 hco=gcbo; hfig=gcbf;
tomwalters@0 2566 % Reset checks on all menu items:
tomwalters@0 2567 set(get(hco,'userdata'),'checked','off');
tomwalters@0 2568 set(hco,'checked','on');
tomwalters@0 2569
tomwalters@0 2570 % Update userdata cache:
tomwalters@0 2571 % Update display:
tomwalters@0 2572
tomwalters@0 2573 %---------------------------------------------------------------
tomwalters@0 2574 function changeFreqSliceMode(hco,eventStruct)
tomwalters@0 2575
tomwalters@0 2576 hco=gcbo; hfig=gcbf;
tomwalters@0 2577 % Reset checks on all menu items
tomwalters@0 2578 set(get(hco,'userdata'),'checked','off');
tomwalters@0 2579 set(hco,'checked','on');
tomwalters@0 2580
tomwalters@0 2581 % Update userdata cache:
tomwalters@0 2582 % Update display:
tomwalters@0 2583 left_plot_toggle;
tomwalters@0 2584
tomwalters@0 2585 %---------------------------------------------------------------
tomwalters@0 2586 function changeTimeSliceMode(hco,eventStruct)
tomwalters@0 2587
tomwalters@0 2588 hco=gcbo; hfig=gcbf;
tomwalters@0 2589 % Reset checks on all menu items
tomwalters@0 2590 set(get(hco,'userdata'),'checked','off');
tomwalters@0 2591 set(hco,'checked','on');
tomwalters@0 2592
tomwalters@0 2593 % Update userdata cache:
tomwalters@0 2594 % Update display:
tomwalters@0 2595
tomwalters@0 2596
tomwalters@0 2597 % ---------------------------------------------------------------
tomwalters@0 2598 % F O C U S S Y S T E M
tomwalters@0 2599 % --------------------------------------------------------------
tomwalters@0 2600
tomwalters@0 2601 %---------------------------------------------------------------
tomwalters@0 2602 function push_curr_to_focus_history(hfig)
tomwalters@0 2603
tomwalters@0 2604 ud = get(hfig,'userdata');
tomwalters@0 2605 hax_time = ud.hax(2);
tomwalters@0 2606
tomwalters@0 2607 % focus history is stored in userdata of time-panner axis
tomwalters@0 2608 % as either an empty vector or cell, or as
tomwalters@0 2609 % a cell-array of 2-element x-lim vector.
tomwalters@0 2610
tomwalters@0 2611 % get current time-axis limits
tomwalters@0 2612 curr_xlim = get(hax_time,'xlim');
tomwalters@0 2613
tomwalters@0 2614 curr_history = get(hax_time,'userdata');
tomwalters@0 2615 if isempty(curr_history),
tomwalters@0 2616 updated_focus_history = {curr_xlim};
tomwalters@0 2617 else
tomwalters@0 2618 updated_focus_history = [curr_history {curr_xlim}];
tomwalters@0 2619 end
tomwalters@0 2620 set(hax_time,'userdata',updated_focus_history);
tomwalters@0 2621
tomwalters@0 2622 update_focus_history_menu(hfig);
tomwalters@0 2623
tomwalters@0 2624 %---------------------------------------------------------------
tomwalters@0 2625 function hist_xlim = pop_from_focus_history(hfig)
tomwalters@0 2626
tomwalters@0 2627 ud = get(hfig,'userdata');
tomwalters@0 2628 hax_time = ud.hax(2);
tomwalters@0 2629 curr_xlim = get(hax_time,'xlim'); % get current time-axis limits
tomwalters@0 2630
tomwalters@0 2631 curr_history = get(hax_time,'userdata');
tomwalters@0 2632 if isempty(curr_history),
tomwalters@0 2633 % no prev focus info recorded
tomwalters@0 2634 warning('Attempt to pop empty focus stack');
tomwalters@0 2635 hist_xlim = curr_xlim;
tomwalters@0 2636
tomwalters@0 2637 %im_xdata = get(ud.himage,'xdata');
tomwalters@0 2638 %hist_xlim = [min(im_xdata) max(im_xdata)];
tomwalters@0 2639 else
tomwalters@0 2640 % Pop last history xlim
tomwalters@0 2641 hist_xlim = curr_history{end};
tomwalters@0 2642 curr_history(end) = [];
tomwalters@0 2643 set(hax_time,'userdata',curr_history);
tomwalters@0 2644 end
tomwalters@0 2645
tomwalters@0 2646 update_focus_history_menu(hfig);
tomwalters@0 2647
tomwalters@0 2648 %---------------------------------------------------------------
tomwalters@0 2649 function clear_focus_history(hfig)
tomwalters@0 2650 % Remove all previous focus entries
tomwalters@0 2651
tomwalters@0 2652 ud = get(hfig,'userdata');
tomwalters@0 2653 hax_time = ud.hax(2);
tomwalters@0 2654 set(hax_time,'userdata',[]);
tomwalters@0 2655
tomwalters@0 2656 update_focus_history_menu(hfig);
tomwalters@0 2657
tomwalters@0 2658 %---------------------------------------------------------------
tomwalters@0 2659 function update_focus_history_menu(hfig)
tomwalters@0 2660
tomwalters@0 2661 ud = get(hfig,'userdata');
tomwalters@0 2662 hax_time = ud.hax(2);
tomwalters@0 2663
tomwalters@0 2664 % Update 'Previous Focus' context menu label:
tomwalters@0 2665 %
tomwalters@0 2666 curr_history = get(hax_time,'userdata');
tomwalters@0 2667 histLen = length(curr_history);
tomwalters@0 2668 str = 'Previous Focus';
tomwalters@0 2669 if histLen>0,
tomwalters@0 2670 str = [str ' (' num2str(histLen) ')'];
tomwalters@0 2671 ena = 'on';
tomwalters@0 2672 else
tomwalters@0 2673 ena = 'off';
tomwalters@0 2674 end
tomwalters@0 2675
tomwalters@0 2676 % Get panner context menu handle:
tomwalters@0 2677 hmenu = findobj( get(get(ud.hthumb, 'uicontext'),'children'),'label','Focus In');
tomwalters@0 2678 hAllMenus = get(hmenu,'userdata'); % vector of handles to context menus
tomwalters@0 2679 hFocusPrev = hAllMenus(2);
tomwalters@0 2680 set(hFocusPrev, 'label',str);
tomwalters@0 2681 set(hAllMenus(2:3), 'enable',ena); % Prev and Reset Focus menus
tomwalters@0 2682
tomwalters@0 2683 %---------------------------------------------------------------
tomwalters@0 2684 function focus_menu_render_callback(hco, eventStruct)
tomwalters@0 2685 % Used to update the enable of the "Focus In" menu item
tomwalters@0 2686 % Only enabled if thumb_xlim ~= curr_xlim
tomwalters@0 2687
tomwalters@0 2688 hfig=gcbf; hparent=gcbo;
tomwalters@0 2689 ud = get(hfig,'userdata');
tomwalters@0 2690 hAllMenus = get(hparent,'children'); % vector of handles to context menus
tomwalters@0 2691
tomwalters@0 2692 % Enable 'Focus on Window' if zoom window is less than entire panner
tomwalters@0 2693 %
tomwalters@0 2694 hFocusIn = hAllMenus(end); % 'Focus on Zoom' entry
tomwalters@0 2695 hax_time = ud.hax(2);
tomwalters@0 2696 curr_xlim = get(hax_time,'xlim'); % get current time-axis limits
tomwalters@0 2697 % Get thumbnail xlim vector:
tomwalters@0 2698 thumb_xdata = get(ud.hthumb,'xdata'); % current thumbnail patch coords
tomwalters@0 2699 thumb_xlim = [min(thumb_xdata) max(thumb_xdata)]; % convert to xlim
tomwalters@0 2700 if ~isequal(curr_xlim, thumb_xlim),
tomwalters@0 2701 ena='on';
tomwalters@0 2702 else
tomwalters@0 2703 ena='off';
tomwalters@0 2704 end
tomwalters@0 2705 set(hFocusIn,'enable',ena);
tomwalters@0 2706
tomwalters@0 2707 %---------------------------------------------------------------
tomwalters@0 2708 function focusTimeIn(hco,eventStruct)
tomwalters@0 2709
tomwalters@0 2710 hfig=gcbf;
tomwalters@0 2711
tomwalters@0 2712 % get current time-axis (panner) limits
tomwalters@0 2713 ud = get(hfig,'userdata');
tomwalters@0 2714 hax_time = ud.hax(2);
tomwalters@0 2715 curr_xlim = get(hax_time,'xlim');
tomwalters@0 2716
tomwalters@0 2717 % Get thumbnail xlim vector:
tomwalters@0 2718 thumb_xdata = get(ud.hthumb,'xdata'); % current thumbnail patch coords
tomwalters@0 2719 thumb_xlim = [min(thumb_xdata) max(thumb_xdata)]; % convert to xlim
tomwalters@0 2720
tomwalters@0 2721 if ~isequal(curr_xlim, thumb_xlim),
tomwalters@0 2722 push_curr_to_focus_history(hfig);
tomwalters@0 2723
tomwalters@0 2724 % Zoom in to thumb limits
tomwalters@0 2725 hax_time = ud.hax(2);
tomwalters@0 2726
tomwalters@0 2727 if 0
tomwalters@0 2728 xidx = round(1+thumb_xlim*ud.Fs);
tomwalters@0 2729 yfocus = ud.y(xidx(1):xidx(2));
tomwalters@0 2730 ylim = [min(yfocus) max(yfocus)];
tomwalters@0 2731 set(hax_time, 'ylim',ylim);
tomwalters@0 2732 end
tomwalters@0 2733
tomwalters@0 2734 set(hax_time,'xlim', thumb_xlim);
tomwalters@0 2735 update_axes_with_eng_units(gcbf);
tomwalters@0 2736 end
tomwalters@0 2737
tomwalters@0 2738 %---------------------------------------------------------------
tomwalters@0 2739 function focusTimePrev(hco,eventStruct)
tomwalters@0 2740
tomwalters@0 2741 hfig=gcbf;
tomwalters@0 2742 ud = get(hfig,'userdata');
tomwalters@0 2743 hax_time = ud.hax(2);
tomwalters@0 2744
tomwalters@0 2745 % Reset to last focus
tomwalters@0 2746 xlim = pop_from_focus_history(hfig);
tomwalters@0 2747
tomwalters@0 2748 if 0
tomwalters@0 2749 xidx = round(1+xlim*ud.Fs);
tomwalters@0 2750 yfocus = ud.y(xidx(1):xidx(2));
tomwalters@0 2751 ylim = [min(yfocus) max(yfocus)];
tomwalters@0 2752 set(hax_time, 'ylim',ylim);
tomwalters@0 2753 end
tomwalters@0 2754
tomwalters@0 2755 set(hax_time, 'xlim',xlim);
tomwalters@0 2756 update_axes_with_eng_units(gcbf);
tomwalters@0 2757
tomwalters@0 2758 %---------------------------------------------------------------
tomwalters@0 2759 function focusTimeReset(hco,eventStruct,hfig)
tomwalters@0 2760 % Remove all previous focus entries
tomwalters@0 2761
tomwalters@0 2762 if nargin<3, hfig=gcbf; end
tomwalters@0 2763 clear_focus_history(hfig);
tomwalters@0 2764
tomwalters@0 2765 % Reset focus zoom:
tomwalters@0 2766 ud = get(hfig,'userdata');
tomwalters@0 2767 hax_time = ud.hax(2);
tomwalters@0 2768 im_xdata = get(ud.himage,'xdata');
tomwalters@0 2769 xlim = [min(im_xdata) max(im_xdata)];
tomwalters@0 2770
tomwalters@0 2771 if 0
tomwalters@0 2772 xidx = round(1+xlim*ud.Fs);
tomwalters@0 2773 yfocus = ud.y(xidx(1):xidx(2));
tomwalters@0 2774 ylim = [min(yfocus) max(yfocus)];
tomwalters@0 2775 set(hax_time,'ylim',ylim);
tomwalters@0 2776 end
tomwalters@0 2777
tomwalters@0 2778 set(hax_time,'xlim',xlim);
tomwalters@0 2779 update_axes_with_eng_units(gcbf);
tomwalters@0 2780
tomwalters@0 2781 % ---------------------------------------------------------------
tomwalters@0 2782 % PARAMETER WINDOW
tomwalters@0 2783 % --------------------------------------------------------------
tomwalters@0 2784 % function create_param_gui
tomwalters@0 2785 % XXX UNUSED
tomwalters@0 2786
tomwalters@0 2787
tomwalters@0 2788 % ---------------------------------------------------------------
tomwalters@0 2789 % AXES UPDATE FUNCTIONS
tomwalters@0 2790 % --------------------------------------------------------------
tomwalters@0 2791 function update_left_plot(hfig)
tomwalters@0 2792 % UPDATE_LEFT_PLOT Updates the frequency plot with the appropriate analysis
tomwalters@0 2793
tomwalters@0 2794 ud = get(hfig,'UserData');
tomwalters@0 2795 mode = ud.plot.left;
tomwalters@0 2796 if strcmp(mode,'spectrogram_freq_slice'),
tomwalters@0 2797 update_freqslice(hfig);
tomwalters@0 2798 else
tomwalters@0 2799 update_psdplot(hfig);
tomwalters@0 2800 end
tomwalters@0 2801
tomwalters@0 2802 % --------------------------------------------------------------
tomwalters@0 2803 function update_freqslice(hfig)
tomwalters@0 2804 % UPDATE_FREQSLICE Update the Frequency Slice (on the left axes)
tomwalters@0 2805
tomwalters@0 2806 ud = get(hfig,'UserData');
tomwalters@0 2807 set(ud.hfreq_line, 'xdata',get_spec_freq(hfig),'ydata',ud.f);
tomwalters@0 2808 hax_freq = ud.hax(4);
tomwalters@0 2809
tomwalters@0 2810 b = get(ud.himage,'cdata');
tomwalters@0 2811 blim = [min(b(:)) max(b(:))];
tomwalters@0 2812 spec_ylim = [0 max(ud.f)];
tomwalters@0 2813 xlabel('dB');
tomwalters@0 2814 set(hax_freq, ...
tomwalters@0 2815 'YLim',spec_ylim, ...
tomwalters@0 2816 'XLim',blim,...
tomwalters@0 2817 'XtickMode','auto');
tomwalters@0 2818 set(hax_freq, 'Xtick', return2ticks(hax_freq));
tomwalters@0 2819
tomwalters@0 2820 % Update extent of horizontal crosshair:
tomwalters@0 2821 set(ud.hfreq_x, 'xdata',blim);
tomwalters@0 2822
tomwalters@0 2823
tomwalters@0 2824 % --------------------------------------------------------------
tomwalters@0 2825 function update_psdplot(hfig)
tomwalters@0 2826 % UPDATE_PSDPLOT Update the PSD plot (on the left axes)
tomwalters@0 2827
tomwalters@0 2828 ud = get(hfig,'UserData');
tomwalters@0 2829 wstate = warning;
tomwalters@0 2830 warning off;
tomwalters@0 2831 density = 10*log10(ud.Pxx);
tomwalters@0 2832 warning(wstate);
tomwalters@0 2833
tomwalters@0 2834 hax_freq = ud.hax(4);
tomwalters@0 2835
tomwalters@0 2836 % Update the PSD plot with data and limits
tomwalters@0 2837 set(ud.hfreq_line,'Xdata',density,'Ydata',ud.w);
tomwalters@0 2838 xlim = [min(density(:)) max(density(:))];
tomwalters@0 2839 xlabel('dB/Hz');
tomwalters@0 2840 set(hax_freq, ...
tomwalters@0 2841 'YLim', [0 ud.Fs/2],'XLim',xlim,...
tomwalters@0 2842 'XTickMode','auto');
tomwalters@0 2843 set(hax_freq, 'Xtick', return2ticks(hax_freq));
tomwalters@0 2844
tomwalters@0 2845 % Update extent of horizontal crosshair:
tomwalters@0 2846 set(ud.hfreq_x, 'xdata',xlim);
tomwalters@0 2847
tomwalters@0 2848
tomwalters@0 2849 % ---------------------------------------------------------------
tomwalters@0 2850 % UTILITY FUNCTIONS
tomwalters@0 2851 % --------------------------------------------------------------
tomwalters@0 2852 function new_xtick = return2ticks(haxes)
tomwalters@0 2853 % RETURN2TICKS Utility to return two tick marks
tomwalters@0 2854 x = get(haxes,'Xtick');
tomwalters@0 2855 if length(x)>2,
tomwalters@0 2856 new_xtick = [x(1) x(end)];
tomwalters@0 2857 else
tomwalters@0 2858 new_xtick = x;
tomwalters@0 2859 end
tomwalters@0 2860
tomwalters@0 2861 %--------------------------------------------------------------
tomwalters@0 2862 % [EOF] specgramdemo.m