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
|