📄 spectview.m
字号:
function varargout = spectview(varargin)
%SPECTVIEW Spectrum Viewer.
% This graphical tool for Spectral Analysis lets you create, edit,
% and analyze the frequency content of digital signals.
%
% This function is available through the Signal Processing Toolbox
% GUI (Graphic User Interface). To use it, type 'sptool'.
%
% See also SPTOOL, SIGBROWSE, FILTVIEW, FILTDES.
% Copyright (c) 1988-98 by The MathWorks, Inc.
% $Revision: 1.19 $ $ Date: $
if nargin == 0
if isempty(findobj(0,'tag','sptool'))
disp('Type ''sptool'' to start the Signal GUI.')
else
disp('To use the Spectrum Viewer, click on a signal in the ''SPTool''')
disp('and then click on ''Create'' under the ''Spectra'' column.')
end
return
elseif ~isstr(varargin{1})
spinit(varargin{:}) % initialize tool
return
end
switch varargin{1}
%------------------------------------------------------------------------
%spectview('update',fig)
%spectview('update',fig,s,ind)
%spectview('update',fig,s,ind,newdataFlag)
%spectview('update',fig,s,ind,sptoolfig,msg)
% Callback for when selected signals have changed
% Inputs:
% fig - figure handle of spectrum viewer
% s - structure array of spectra
% ind - index of selected spectra
% s,ind together are optional - if omitted, they are obtained from SPTool
% sptoolfig - figure handle of SPTool (optional)
% msg - message as passed from SPTool
% can be 'new', 'value', 'label', 'Fs', 'dup', 'clear'
% The only real distinction here is between 'new' and the rest;
% 'new' means start from scratch as you cannot count on objects
% being the same just because they are at the same index position in ind.
% So 'new' will allocate new lines while anything else will retain any
% lines that are at the same index location.
case 'update'
fig = varargin{2};
ud = get(fig,'userdata');
if nargin > 2
s = varargin{3};
ind = varargin{4};
else
[s,ind] = sptool('Spectra');
end
if nargin > 5
msg = varargin{6};
else
msg = 'new'; % new starts from scratch
end
fromScratch = strcmp(msg,'new');
for i = 1:length(s(ind))
if isempty(s(ind(i)).lineinfo)
% assign next available line color and style
[s(ind(i)).lineinfo,ud.colorCount] = ...
nextcolor(ud.colororder,ud.linestyleorder,ud.colorCount);
s(ind(i)).lineinfo.columns = 1;
% poke back into SPTool
if nargin > 4
sptool('import',s(ind(i)),0,varargin{5})
else
sptool('import',s(ind(i)))
end
end
end
magscale = findcstr(get(ud.hand.magscaleMenu,'checked'),'on');
oldLines = ud.lines;
oldPatches = ud.patches;
% de-allocate any lines that are no longer visible (save in cache);
% also delete any such patches:
patchDeleteList = [];
for i=1:length(ud.lines)
if ~any(ud.SPToolIndices(i)==ind) | fromScratch
% a quick command line test reveals that destroying and creating
% 100 lines is about twice as slow as setting the visible, tag,
% xdata, and ydata of 100 lines.
ud.linecache.h = [ud.linecache.h; ud.lines(i).h];
patchDeleteList = [patchDeleteList; ud.patches{i}];
ud.patches{i} = [];
end
end
% reset line cache:
set(ud.linecache.h,'visible','off','tag','','xdata',0,'ydata',0)
delete(patchDeleteList)
N = length(ind);
if length(ud.lines)>N
ud.lines(N+1:end) = [];
ud.patches(N+1:end) = [];
end
for i=1:N
if ~isempty(ud.SPToolIndices) & ~fromScratch
j = find(ind(i)==ud.SPToolIndices);
else
j = [];
end
if isempty(j) | ~isequal(s(ind(i)),ud.spect(j))
% set up fields for panning:
ud.lines(i).data = s(ind(i)).P;
ud.lines(i).columns = 1; % all spectra have but one column
ud.lines(i).Fs = -1; % panner uses this for unequally spaced
if ~isempty(s(ind(i)).f)
ud.lines(i).t0 = s(ind(i)).f(1);% starting "time" for panfcn
else
ud.lines(i).t0 = [];
end
ud.lines(i).xdata = s(ind(i)).f;
xd = s(ind(i)).f;
yd = s(ind(i)).P;
yd = spmagfcn(yd,magscale);
% create patch first so line is on top of it
ud.patches{i} = [];
if ~isempty(s(ind(i)).confid)
if s(ind(i)).confid.enable
% assign or create a new patch
ud.patches{i} = patch(0,0,...
confidPatchColor(s(ind(i)).lineinfo.color),...
'edgecolor','none','parent',ud.mainaxes,...
'buttondownfcn',['spectview(''linedown'',' ...
num2str(i) ')']);
Pc = s(ind(i)).confid.Pc;
if ~isempty(Pc)
verts = [[xd(:); flipud(xd(:))] ...
spmagfcn([Pc(:,1); flipud(Pc(:,2))],magscale)];
N = length(verts(:,1));
numFaces = N-2;
faces = zeros(numFaces,3);
faces(1:2:end,1) = (1:numFaces/2)';
faces(2:2:end,1) = (2:numFaces/2+1)';
faces(1:2:end,2) = (2:numFaces/2+1)';
faces(2:2:end,2) = N - (1:numFaces/2)';
faces(1:2:end,3) = N - (0:numFaces/2-1)';
faces(2:2:end,3) = N - (0:numFaces/2-1)';
set(ud.patches{i},'vertices',verts,...
'faces',faces);
end
end
end
%assign lines, set xdata and ydata
[ud.lines(i).h,ud.linecache.h] = assignline(ud.linecache.h,...
length(s(ind(i)).lineinfo.columns),ud.mainaxes,...
'color',s(ind(i)).lineinfo.color,...
'linestyle',s(ind(i)).lineinfo.linestyle,...
'visible','on',...
'tag',s(ind(i)).label);
set(ud.lines(i).h,'xdata',xd,'ydata',yd);
else
% use old lines (no need to set x and ydata)
ud.lines(i) = oldLines(j);
ud.patches{i} = oldPatches{j};
if ~isempty(ud.patches{i})
set(ud.patches{i},'buttondownfcn',['spectview(''linedown'',' ...
num2str(i) ')'])
end
end
set(ud.lines(i).h,'buttondownfcn',['spectview(''linedown'',' ...
num2str(i) ')'])
end
if ~fromScratch
common = intersect(ud.SPToolIndices,ind);
else
common = [];
end
ud.SPToolIndices = ind;
ud.spect = s(ind);
if ~isempty(ud.spect)
ud.focusIndex = 1;
else
ud.focusIndex = [];
end
spzoomout(ud,isempty(common),0) % saves userdata
ud = get(fig,'userdata');
sptlegend('setstring',{ud.spect.label},{ud.lines.columns},fig)
spectview('linedown',ud.focusIndex,0,fig,1)
%------------------------------------------------------------------------
% spectview('magscale',scaling,fig,setprefFlag)
% callback of magscale menu; changes scaling
% Inputs:
% scaling - string; either 'db' or 'lin'
% fig - optional - figure handle of spectrum viewer - defaults to gcf
% setprefFlag - optional - 1 ==> set preferences in sptool (default),
% 0 ==> don't
case 'magscale'
scaling = varargin{2};
if nargin < 3
fig = gcf;
else
fig = varargin{3};
end
if nargin < 4
setprefFlag = 1;
else
setprefFlag = varargin{4};
end
ud = get(fig,'userdata');
old = findcstr(get(ud.hand.magscaleMenu,'checked'),'on');
switch scaling
case 'db'
checks = {'on' 'off'};
case 'lin'
checks = {'off' 'on'};
% case 'log'
% checks = {'off' 'off' 'on'};
end
set(ud.hand.magscaleMenu,{'checked'},checks')
new = findcstr(checks,'on');
if ~isequal(old,new)
for i=1:length(ud.spect)
yd = ud.lines(i).data;
yd = spmagfcn(yd,new);
set(ud.lines(i).h,'ydata',yd);
if ~isempty(ud.spect(i).confid) & ...
ud.spect(i).confid.enable
Pc = ud.spect(i).confid.Pc;
if ~isempty(Pc)
verts = get(ud.patches{i},'vertices');
verts(:,2) = spmagfcn([Pc(:,1); flipud(Pc(:,2))],new);
set(ud.patches{i},'vertices',verts);
end
end
end
spzoomout(ud,0)
if new == 3
set(ud.mainaxes,'yscale','log')
else
set(ud.mainaxes,'yscale','linear')
end
if setprefFlag
p = sptool('getprefs','spectview');
p.magscale = new;
sptool('setprefs','spectview',p)
end
end
%------------------------------------------------------------------------
% spectview('freqscale',scaling,fig,setprefFlag)
% callback of freqscale menu; changes scaling
% Inputs:
% scaling - string; either 'lin' or 'log'
% fig - optional - figure handle of spectrum viewer - defaults to gcf
% setprefFlag - optional - 1 ==> set preferences in sptool (default),
% 0 ==> don't
case 'freqscale'
scaling = varargin{2};
if nargin < 3
fig = gcf;
else
fig = varargin{3};
end
if nargin < 4
setprefFlag = 1;
else
setprefFlag = varargin{4};
end
ud = get(fig,'userdata');
switch scaling
case 'lin'
checks = {'on' 'off'};
case 'log'
checks = {'off' 'on'};
end
old = findcstr(get(ud.hand.freqscaleMenu,'checked'),'on');
set(ud.hand.freqscaleMenu,{'checked'},checks')
new = findcstr(checks,'on');
if ~isequal(old,new)
range = findcstr(get(ud.hand.freqrangeMenu,'checked'),'on');
if new == 2 & range == 3 % can't display negative values!
set(ud.hand.freqrangeMenu(1),'checked','on')
set(ud.hand.freqrangeMenu(3),'checked','off')
spectview('freqrange','half',fig,0)
end
if new == 2
set(ud.mainaxes,'xscale','log')
if ud.prefs.tool.ruler
% Make sure that x-axes lower limit is not 0
xlim = setLogscaleLims(ud.mainaxes,ud.lines,'xlim');
set(ud.mainaxes,'xlim',xlim)
ud.limits.xlim = xlim;
set(fig,'userdata',ud)
ruler('newlimits',fig)
end
else
set(ud.mainaxes,'xscale','linear')
if ud.prefs.tool.ruler & old == 2 % Change xlim(1) back to 0
xlim = get(ud.mainaxes,'xlim');
xlim(1) = 0;
set(ud.mainaxes,'xlim',xlim)
ud.limits.xlim = xlim;
set(fig,'userdata',ud)
ruler('newlimits',fig)
end
end
if setprefFlag
p = sptool('getprefs','spectview');
p.freqscale = new;
p.freqrange = findcstr(get(ud.hand.freqrangeMenu,'checked'),'on');
sptool('setprefs','spectview',p)
end
end
%------------------------------------------------------------------------
% spectview('freqrange',range,fig,setprefFlag)
% callback of freqrange menu; changes range
% Inputs:
% range - string; either 'half', 'whole' or 'neg'
% fig - optional - figure handle of spectrum viewer - defaults to gcf
% setprefFlag - optional - 1 ==> set preferences in sptool (default),
% 0 ==> don't
case 'freqrange'
range = varargin{2};
if nargin < 3
fig = gcf;
else
fig = varargin{3};
end
if nargin < 4
setprefFlag = 1;
else
setprefFlag = varargin{4};
end
ud = get(fig,'userdata');
switch range
case 'half'
checks = {'on' 'off' 'off'};
case 'whole'
checks = {'off' 'on' 'off'};
case 'neg'
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -