📄 filtdes.m
字号:
function varargout = filtdes(varargin)
%FILTDES Filter Designer.
% This graphical tool allows you to design lowpass, highpass, bandpass,
% and bandstop digital filters.
%
% Type 'sptool' to start the Signal Processing GUI Tool and access
% the Filter Designer.
%
% [B,A] = FILTDES('getfilt') returns the numerator coefficients in B
% and denominator coefficients in A of the current filter.
%
% [B,A,Fs] = FILTDES('getfilt') returns the sampling frequency Fs also.
%
% See also SPTOOL, SIGBROWSE, FILTVIEW, SPECTVIEW.
% Author: T. Krauss, 3/7/94
% Version 2, May 1997
% Copyright (c) 1988-98 by The MathWorks, Inc.
% $Revision: 1.51 $ $Date: 1997/12/02 18:36:17 $
if nargin==0
if isempty(findobj(0,'tag','sptool'))
disp('Type ''sptool'' to start the Signal GUI.')
else
disp('To use the Filter Designer, click on the ''Design New'' button')
disp('under the ''Filters'' column in the ''SPTool''.')
end
return
end
if nargin<1
action = 'init';
f = [];
elseif isstruct(varargin{1})
action = 'init';
f = varargin{1};
else
action = varargin{1};
end
switch action
%------------------------------------------------------------------------
%filtdes('init')
%filtdes(f) - where f is a filter structure of type 'design'
% Creates a new figure with tag 'filtdes'
case 'init'
figname = prepender('Filter Designer');
screensize = get(0,'screensize');
fp = get(0,'defaultfigureposition');
fw = 700;
%fw = 610; % figure width -
% slightly less than the minimum width of 640 pixels
% (assuming 640x480 is smallest screen size)
fw = min(fw,screensize(3)-50);
fh = 410; % figure height - slightly less than minimum screen width (480)
fp = [fp(1)-(fw-fp(3))/2 fp(2)+fp(4)-fh fw fh];
% create figure
fig = figure('visible','off',...
'handlevisibility','callback',...
'tag','filtdes',...
'name',figname,...
'menubar','none',...
'position',fp,...
'numbertitle','off',...
'integerhandle','off',...
'windowbuttonmotionfcn','filtdes(''motion'')',...
'closerequestfcn','filtdes(''SPTclose'')');
ud.sz = sptsizes;
% load preferences from SPTool:
SPTfig = findobj(0,'tag','sptool');
filtdesPrefs = sptool('getprefs','filtdes',SPTfig);
ud.prefs.tool.zoompersist = filtdesPrefs.zoomFlag;
ud.prefs.nfft = eval(filtdesPrefs.nfft,'1024');
ud.prefs.grid = filtdesPrefs.grid;
ud.prefs.AutoDesignInit = filtdesPrefs.AutoDesignInit;
% create "ht" field; stands for "handle table"
ud.ht.specFrame = uicontrol('style','frame','tag','specFrame');
% axFrame - invisible - used for axes positioning purposes:
ud.ht.axFrame = uicontrol('style','frame','visible','off','tag','axFrame');
ud.ht.measFrame = uicontrol('style','frame','tag','measFrame');
ud.ht.tb2Frame = uicontrol('style','frame','tag','tb2Frame'); %"toolbar 2 frame"
ud.ht.specLabel = uicontrol('style','text',...
'string','Specifications','tag','specFrame');
ud.ht.measLabel = uicontrol('style','text',...
'string','Measurements','tag','measFrame');
ud.ht.toolTip = uicontrol('style','text',...
'string','','horizontalalignment','left','visible','off');
if strcmp(computer,'MAC2')
fontSize = 14;
fontWeight = 'normal';
elseif strcmp(computer,'PCWIN')
fontSize = 9;
fontWeight = 'bold';
else
fontSize = 12;
fontWeight = 'bold';
end
set([ud.ht.specLabel ud.ht.measLabel],...
'fontsize',fontSize,'fontweight',fontWeight)
set(ud.ht.measLabel,'backgroundcolor',[.9 .5 .5])
set(ud.ht.specLabel,'backgroundcolor',[.7 .9 .7])
ud.ht.revert = uicontrol('style','pushbutton',...
'string','Revert','callback','filtdes(''revert'')',...
'enable','off','tag','revert');
ud.ht.apply = uicontrol('style','pushbutton',...
'string','Apply','callback','filtdes(''apply'')',...
'enable','off','tag','apply');
ud.ht.autoDesign = uicontrol('style','checkbox',...
'string','Auto Design','callback','filtdes(''autodesignCB'')',...
'enable','on','value',ud.prefs.AutoDesignInit,'tag','AutoDesign');
ud.ht.modulePopup = uicontrol('style','popupmenu',...
'string','1','callback','filtdes(''modulepopup'')',...
'enable','on','value',1);
ud.ht.moduleLabel = uicontrol('style','text','string','Algorithm',...
'horizontalalignment','left');
ud.ht.FsLabel = uicontrol('style','text','string','Sampling Frequency',...
'horizontalalignment','left','tag','Fs');
ud.ht.FsEdit = uicontrol('style','edit','string','1',...
'backgroundcolor','w','horizontalalignment','left',...
'callback','filtdes(''Fsedit'')','tag','Fs');
ud.ht.overlay = uicontrol('style','pushbutton',...
'string','Overlay Spectrum...','callback','filtdes(''overlay'')',...
'enable','on','tag','overlaybutton');
ud.ht.filtMenuLabel = uicontrol('style','text','string','Filter',...
'horizontalalignment','left','tag','filtmenu');
ud.ht.filtMenu = uicontrol('style','popupmenu','string',{'filt1'},...
'callback','filtdes(''filtmenu'')','tag','filtmenu');
%====================================
% MENUS
% MENU LABEL CALLBACK TAG
mc={ '&File' ' ' 'File'
'>&Close^w' 'filtdes(''SPTclose'')' 'close'
'&Window' winmenu('callback') 'winmenu'};
handles = makemenu(fig, char(mc(:,1)), ...
char(mc(:,2)), char(mc(:,3)));
set(handles,'handlevisibility','callback')
winmenu(fig) % initialize windows menu
% Register modules
ud.modules = fdmodp({}); % calls one in signal/private
% now call each one found on path:
p = sptool('getprefs','plugins',SPTfig);
if p.plugFlag
ud.modules = sptool('callall','fdmod',ud.modules);
end
modulePopupStr = cell(length(ud.modules),1);
for i=1:length(ud.modules)
eval(['modulePopupStr{i} = ' ud.modules{i} '(''description'');'],...
['modulePopupStr{i} = ''' ud.modules{i} ''';'])
end
% Initialize Objects arrays
% This structure contains a field for each type of object supported
% by filtdes, including fdspec, fdax, fdline, and fdmeas
% Each field is an array of the corresponding objects
ud.Objects = [];
ud.Objects.fdspec = [];
ud.Objects.fdax = [];
ud.Objects.fdline = [];
ud.Objects.fdmeas = [];
if isempty(f)
% create a new filter
Fs = sptool('commonFs');
[err,errmsg,ud.filt]=sbswitch('importfilt','make',{1 1 1 Fs});
ud.filt.type = 'design';
else
ud.filt = f;
end
set(ud.ht.FsEdit,'string',sprintf('%1.5g',ud.filt.Fs))
if isfield(ud.filt,'specs') & isstruct(ud.filt.specs) & ...
isfield(ud.filt.specs,'currentModule')
if isempty(strcmp(ud.modules,ud.filt.specs.currentModule))
ud.filt.specs.currentModule = ud.modules{1};
end
moduleInd = find(strcmp(ud.modules,ud.filt.specs.currentModule));
ud.currentModule = ud.modules{moduleInd};
set(ud.ht.modulePopup,'string',modulePopupStr,'value',moduleInd)
else
ud.filt.specs.currentModule = ud.modules{1};
ud.currentModule = ud.modules{1};
set(ud.ht.modulePopup,'string',modulePopupStr,'value',1)
end
% define ud.pointer and justzoom
ud.pointer = 0;
ud.justzoom = [0 0];
% save userdata before calling zoombar since zoombar alters ud.
% Also, set resizefcn before calling zoombar since zoombar
% appends to resizefcn. The resizefcn is not set at figure
% creation time because if it were, it would get called and that would
% be bad since the objects being resized wouldn't exist yet.
set(fig,'userdata',ud,'resizefcn','filtdes(''resize'')')
filtdes('resize')
% ====================================================================
% now add toolbar
btnlist = {'zoominy' 'zoomouty' 'zoominx' ...
'zoomoutx' 'passband' 'zoomout' 'mousezoom' 'help'}';
tb_callbackstr = {
'filtdes(''zoom'',''zoominy'')'
'filtdes(''zoom'',''zoomouty'')'
'filtdes(''zoom'',''zoominx'')'
'filtdes(''zoom'',''zoomoutx'')'
'filtdes(''zoom'',''passband'')'
'filtdes(''zoom'',''zoomout'')'
'filtdes(''zoom'',''mousezoom'')'
'filtdes(''help'')' };
zoombar('fig',fig,'btnlist',btnlist,'callbacks',tb_callbackstr,...
'left_width',2*ud.sz.fus + ud.sz.bw,...
'right_width',0);
% call module to initilize itself:
[newfilt,errstr] = feval(ud.currentModule,'init',ud.filt);
ud = get(fig,'userdata'); % restore userdata in case it has been changed
if ~isequal(ud.filt,newfilt)
ud.filt = newfilt;
set(fig,'userdata',ud)
ud.filt = importFiltNoLineinfo(ud.filt,1);
set(fig,'userdata',ud)
end
for i = 1:length(ud.Objects.fdspec)
ud.Objects.fdspec(i).revertvalue = ud.Objects.fdspec(i).value;
end
set([ud.ht.revert ud.ht.apply],'enable','off')
% last step: make the figure visible
set(fig,'visible','on')
%------------------------------------------------------------------------
%filtdes('motion')
% windowbuttonmotionfcn for filtdes figure
case 'motion'
fig = gcbf;
pt = get(fig,'currentpoint');
%disp(sprintf('x = %g, y = %g',pt(1),pt(2)))
ud = get(fig,'userdata');
pos = get(ud.ht.axFrame,'position');
% disable tooltips for now - to re-enable, change 0 to 1 and
% set(ud.ht.toolTip,'visible','on') and change resizefcn to account
% for smaller afp
if 0
[toolTipStr,returnFlag] = determineToolTip(fig,pt,ud,pos);
set(ud.ht.toolTip,'string',toolTipStr)
if returnFlag
return
end
end
% handle non-regular modes
if ud.pointer == -1 % wait mode
setptr(fig,'watch')
return
elseif ud.pointer == 1 % zoom mode
setptr(fig,'cross')
return
elseif ud.pointer == 2 % help mode
setptr(fig,'help')
return
end
if length(ud.Objects.fdax)==0
return
end
ax = ud.Objects.fdax.h;
if length(ax)>1
ax = [ax{:}];
end
axFound = 0;
for i=1:length(ax)
pos = get(ax(i),'position');
if sbswitch('pinrect',pt,[pos(1) pos(1)+pos(3) pos(2) pos(2)+pos(4)])
axFound = 1;
break
end
end
if axFound
ax = ax(i);
axud = get(ax,'userdata');
thePtr = axud.pointer;
if isempty(thePtr)
thePtr = 'arrow';
end
% now find list of lines in this axes which have nontrivial
% vertexpointer or segmentpointer properties
pta = get(ax,'currentpoint');
pta = pta(1,1:2);
xlim = get(ax,'xlim');
ylim = get(ax,'ylim');
pos = get(ax,'position'); % assumed in pixels
xscale = pos(3)/diff(xlim); % number of pixels per x axis units
yscale = pos(4)/diff(ylim); % number of pixels per y axis units
allLines = findobj(ax,'type','line');
for i=1:length(allLines)
lineUd = get(allLines(i),'userdata');
if ~isempty(lineUd) & strcmp(get(allLines(i),'visible'),'on')
vp = lineUd.vertexpointer;
sp = lineUd.segmentpointer;
if length(vp)>1 | length(sp)>1 | ~isempty(vp{1}) | ~isempty(sp{1})
% Are we close to this line?
xd = get(allLines(i),'xdata');
yd = get(allLines(i),'ydata');
[vertexFlag,dist,ind,segdist,segind] = ...
closestpoint(pta,allLines(i),xscale,yscale,xd,yd);
if vertexFlag & (dist<3.5) & ...
(length(vp)>1 | ~isempty(vp{1}))
if length(vp) == 1
thePtr = vp{1};
else
thePtr = vp{ind};
end
break
elseif ~vertexFlag & (segdist<3.5) & ...
(length(sp)>1 | ~isempty(sp{1}))
if length(sp) == 1
thePtr = sp{1};
else
thePtr = sp{segind};
end
break
end
end
end
end
if ~isempty(thePtr)
setptr(fig,thePtr)
else
setptr(fig,'arrow')
end
else
currentPtr = get(fig,'pointer'); % Prevent flicker on PCWIN
if ~strcmp(currentPtr,'arrow')
setptr(fig,'arrow')
end
return
end
%------------------------------------------------------------------------
% enable = filtdes('selection',verb.action,msg,SPTfig)
% respond to selection change in SPTool
% possible actions are
% 'create' - New Design button - always enabled
% 'change' - Edit Design button - enabled when
% there is a filter selected which is a valid design
case 'selection'
msg = varargin{3};
SPTfig = varargin{4};
switch varargin{2}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -