gusucode.com > 信号处理工具箱 - signal源码程序 > signal\signal\sigdemos\sosdemo.m
function sosdemo(action,s); %SOSDEMO Second Order Sections Demonstration for the Signal Processing Toolbox. % Copyright (c) 1988-98 by The MathWorks, Inc. % $Revision: 1.2 $ $Date: 1998/07/21 11:53:15 $ % Possible actions: % initialize % createplot % viewtoggle % filter % grids % slide % showtoggle % clickline % puttitle % order % cutoff % closehelp % info % button callbacks: % info if nargin<1, action='initialize'; end; if strcmp(action,'createplot'), % create and plot Second order sections set(gcf,'Pointer','watch'); hndlList=get(gcf,'Userdata'); upHndl = hndlList(1); filterHndl = hndlList(2); orderHndl = hndlList(3); cutoffHndl = hndlList(4); btn1Hndl = hndlList(5); btn2Hndl = hndlList(6); slideHndl = hndlList(7); leftHndl = hndlList(8); rightHndl = hndlList(9); cascadeHndl = hndlList(12); gridHndl = hndlList(13); v = get(filterHndl,'value'); op = get(filterHndl,'string'); op = deblank(op(v,:)); n = get(orderHndl,'UserData'); wn = get(cutoffHndl,'UserData'); section = get(slideHndl,'value'); v = get(upHndl,'value'); updown = get(upHndl,'String'); updown = deblank(updown(v,:)); cascade = get(cascadeHndl,'value'); gr = get(gridHndl,'value'); sos = get(filterHndl,'UserData'); set(gcf,'nextplot','add') % Now plot response ax = newplot; np = 256; m = size(sos,1); h = []; H = zeros(np,m); [H(:,1),F] = freqz(sos(1,1:3),sos(1,4:6),np,2); for i=2:m, if cascade, H(:,i) = H(:,i-1).*freqz(sos(i,1:3),sos(i,4:6),np,2); else H(:,i) = freqz(sos(i,1:3),sos(i,4:6),np,2); end end warnsave = warning; % turn off "Log of zero" messages warning('off') H = 20*log10(abs(H)); warning(warnsave) max_pt = max(max(H)); for i=1:m, cb = sprintf('sosdemo(''lineclick'',%g)',i); h=[h,line((i)*ones(np,1),F,H(:,i),'color',linecolor(1),'buttondownfcn',cb)]; end set(h(section),'color',linecolor(2)); if get(btn1Hndl,'value')==0, invis = 1:m; invis(section) = []; set(h(invis),'visible','off'); end if get(btn2Hndl,'value')==1, view(60,30) zlim = get(gca,'zlim'); set(gca,'zlim',[max(zlim(1),-100) max(max_pt,10) ],... 'xlim',[1 m+.01],'ylim',[0 1]) else view(90,0) zlim = get(gca,'zlim'); set(gca,'zlim',[max(zlim(1),-100) max(max_pt,10) ],... 'xlim',[1 m+.01],'ylim',[0 1]) end if gr, grid on, else grid off, end axis(axis) set(rightHndl,'String',int2str(m),'UserData',m) set(slideHndl,'Max',m,'Value',section) sosdemo('puttitle') xlabel('Section'), ylabel('Frequency'), zlabel('Magnitude (dB)') set(gca,'UserData',h) set(gcf,'handlevisibility','callback') set(gcf,'Pointer','arrow'); return elseif strcmp(action,'initialize'), shh = get(0,'ShowHiddenHandles'); set(0,'ShowHiddenHandles','on') figNumber=figure( ... 'Name','Second Order Sections Demo', ... 'handlevisibility','callback',... 'IntegerHandle','off',... 'NumberTitle','off'); %================================== % Set up the axes axes( ... 'Units','normalized', ... 'Position',[0.10 0.22 0.60 0.7], ... 'XTick',[],'YTick',[], ... 'Box','on'); set(figNumber,'defaultaxesposition',[0.10 0.22 0.60 0.7]) %================================= % Set up the scroll bar sbBottom=0.1; sbLeft=0.05; barHeight = 0.04; barWidth = .675; textWidth = barWidth/2; scrollPos = [sbLeft sbBottom barWidth barHeight]; callbackStr = 'sosdemo(''slide'')'; slideHndl = uicontrol( ... 'Style','slider', ... 'Units','normalized', ... 'Position',scrollPos, ... 'Value',6, ... 'userdata',6, ... 'min',1, ... 'max',6, ... 'Interruptible','off', ... 'Callback',callbackStr); % Left and right range indicators c = get(gcf,'Color'); if [.298936021 .58704307445 .114020904255]*c'<.5, fgColor = [1 1 1]; else fgColor = [0 0 0]; end rangePos = [sbLeft sbBottom-barHeight textWidth barHeight]; leftHndl = uicontrol( ... 'Style','text', ... 'Units','normalized', ... 'Position',rangePos, ... 'Horiz','left', ... 'Background',c, ... 'Foreground',fgColor, ... 'String','1'); rangePos = [sbLeft+barWidth/2 sbBottom-barHeight textWidth barHeight]; rightHndl = uicontrol( ... 'Style','text', ... 'Units','normalized', ... 'Position',rangePos, ... 'Horiz','right', ... 'Background',c, ... 'Foreground',fgColor, ... 'String','6'); %==================================== % Information for all buttons (and menus) labelColor=[0.8 0.8 0.8]; yInitPos=0.90; menutop=0.95; top=0.4; left=0.785; btnWid=0.175; btnHt=0.06; textHeight = 0.05; textWidth = 0.07; % Spacing between the button and the next command's label spacing=0.025; %==================================== % The CONSOLE frame frmBorder=0.019; frmBottom=0.04; frmHeight = 0.92; frmWidth = btnWid; yPos=frmBottom-frmBorder; frmPos=[left-frmBorder yPos frmWidth+2*frmBorder frmHeight+2*frmBorder]; h=uicontrol( ... 'Style','frame', ... 'Units','normalized', ... 'Position',frmPos, ... 'BackgroundColor',[0.5 0.5 0.5]); %==================================== % The UPDOWN Menu menuNumber=1; yPos=menutop-(menuNumber-1)*(btnHt+spacing); labelStr='Up|Down'; callbackStr='sosdemo(''filter'')'; % Generic button information btnPos=[left yPos-btnHt btnWid btnHt]; upHndl=uicontrol( ... 'Style','popupmenu', ... 'Units','normalized', ... 'Position',btnPos, ... 'String',labelStr, ... 'Interruptible','on', ... 'Callback',callbackStr); %==================================== % The FILTER Menu menuNumber=2; yPos=menutop-(menuNumber-1)*(btnHt+spacing); labelStr='Butter|Cheby1|Cheby2|Ellip'; callbackStr='sosdemo(''filter'');'; % Generic button information btnPos=[left yPos-btnHt btnWid btnHt]; filterHndl=uicontrol( ... 'Style','popupmenu', ... 'Units','normalized', ... 'Position',btnPos, ... 'String',labelStr, ... 'Interruptible','on', ... 'Value',3,... % chebyshev type 2 'Callback',callbackStr); %=================================== % Filter order top = yPos - btnHt - spacing; labelWidth = frmWidth-textWidth-.01; labelBottom=top-textHeight; labelLeft = left; labelRight = left+btnWid; labelPos = [labelLeft labelBottom labelWidth textHeight]; h = uicontrol( ... 'Style','text', ... 'Units','normalized', ... 'Position',labelPos, ... 'Horiz','left', ... 'String','Order:', ... 'Interruptible','off', ... 'BackgroundColor',[0.5 0.5 0.5], ... 'ForegroundColor','white'); % Text field textPos = [labelRight-textWidth labelBottom textWidth textHeight]; callbackStr = 'sosdemo(''order'')'; orderHndl = uicontrol( ... 'Style','edit', ... 'Units','normalized', ... 'Position',textPos, ... 'Horiz','right', ... 'Background','white', ... 'Foreground','black', ... 'String','6','Userdata',6, ... 'callback',callbackStr); %=================================== % Filter cutoff top = yPos - 2*btnHt - 2*spacing; labelWidth = frmWidth-textWidth-.01; labelBottom=top-textHeight; labelLeft = left; labelRight = left+btnWid; %labelPos = [labelLeft labelBottom labelWidth textHeight]; labelPos = [labelLeft labelBottom btnWid textHeight]; h = uicontrol( ... 'Style','text', ... 'Units','normalized', ... 'Position',labelPos, ... 'Horiz','left', ... 'String','Cutoffs:', ... 'Interruptible','off', ... 'BackgroundColor',[0.5 0.5 0.5], ... 'ForegroundColor','white'); % Text field %textPos = [labelRight-1.5*textWidth labelBottom 1.5*textWidth textHeight]; textPos = [labelLeft labelBottom-btnHt btnWid textHeight]; callbackStr = 'sosdemo(''cutoff'')'; cutoffHndl = uicontrol( ... 'Style','edit', ... 'Units','normalized', ... 'Position',textPos, ... 'Horiz','right', ... 'Background','white', ... 'Foreground','black', ... 'String','[0.4 0.7]','Userdata',[.4 .7], ... 'callback',callbackStr); top = labelBottom-4*spacing; %==================================== % button 1 btnNumber=1; yPos=top-(btnNumber-1)*(btnHt+spacing); labelStr='Show all'; callbackStr='sosdemo(''showtoggle'');'; % Generic button information btnPos=[left yPos-btnHt btnWid btnHt]; btn1Hndl=uicontrol( ... 'Style','checkbox', ... 'Units','normalized', ... 'Position',btnPos, ... 'String',labelStr, ... 'Value',1, ... 'Callback',callbackStr); %==================================== % button 2 btnNumber=2; yPos=top-(btnNumber-1)*(btnHt+spacing); labelStr='3-D plot'; callbackStr='sosdemo(''viewtoggle'');'; % Generic button information btnPos=[left yPos-btnHt btnWid btnHt]; btn2Hndl=uicontrol( ... 'Style','checkbox', ... 'Units','normalized', ... 'Position',btnPos, ... 'String',labelStr, ... 'Value',1, ... 'Callback',callbackStr); %==================================== % button 3 btnNumber=3; yPos=top-(btnNumber-1)*(btnHt+spacing); labelStr='Cascade'; callbackStr='sosdemo(''createplot'');'; % Generic button information btnPos=[left yPos-btnHt btnWid btnHt]; btn3Hndl=uicontrol( ... 'Style','checkbox', ... 'Units','normalized', ... 'Position',btnPos, ... 'String',labelStr, ... 'Value',1, ... 'Callback',callbackStr); %==================================== % button 4 btnNumber=4; yPos=top-(btnNumber-1)*(btnHt+spacing); labelStr='Grid'; callbackStr='sosdemo(''grids'');'; % Generic button information btnPos=[left yPos-btnHt btnWid btnHt]; btn4Hndl=uicontrol( ... 'Style','checkbox', ... 'Units','normalized', ... 'Position',btnPos, ... 'String',labelStr, ... 'Value',1, ... 'Callback',callbackStr); %==================================== % The INFO button labelStr='Info'; callbackStr='sosdemo(''info'')'; helpHndl=uicontrol( ... 'Style','pushbutton', ... 'Units','normalized', ... 'Position',[left frmBottom+btnHt+spacing btnWid btnHt], ... 'String',labelStr, ... 'Callback',callbackStr); %==================================== % The CLOSE button labelStr='Close'; callbackStr='close(gcf)'; closeHndl=uicontrol( ... 'Style','pushbutton', ... 'Units','normalized', ... 'Position',[left frmBottom btnWid btnHt], ... 'String',labelStr, ... 'Callback',callbackStr); hndlList=[ upHndl filterHndl orderHndl cutoffHndl btn1Hndl btn2Hndl ... slideHndl leftHndl rightHndl helpHndl closeHndl btn3Hndl ... btn4Hndl]; set(figNumber, ... 'Visible','on', ... 'UserData',hndlList); sosdemo('filter') set(0,'ShowHiddenHandles',shh) return elseif strcmp(action,'viewtoggle'), v = get(gco,'value'); hndlList = get(gcf,'UserData'); m = floor(get(hndlList(7),'max')); % number of sections if v==1 view(60,30) else view(90,0) end return elseif strcmp(action,'slide'), v = get(gco,'value'); max_v = get(gco,'max'); min_v = get(gco,'min'); old_v = get(gco,'UserData'); if round(v)==old_v, v = old_v + ( 2*( (old_v-v)<0 ) - 1 ); if v>max_v, v = max_v; end if v<min_v, v = min_v; end else v = round(v); end set(gco,'value',v,'userdata',v); h = get(gca,'UserData'); hndlList = get(gcf,'UserData'); if get(hndlList(5),'value')==1, % Show all set(h,'color',linecolor(1)) set(h(v),'color',linecolor(2)) else set(h,'visible','off','color',linecolor(1)) set(h(v),'visible','on','color',linecolor(2)) end set(gco,'value',v); sosdemo('puttitle') return elseif strcmp(action,'puttitle') hndlList = get(gcf,'UserData'); v = get(hndlList(7),'value'); % section selection cascade = get(hndlList(12),'value'); if cascade title( sprintf( ... 'Cumulative Cascade Responses (through section %g highlighted)', v)) else title( sprintf( ... 'Response of Individual Sections (section %g highlighted)', v)) end return elseif strcmp(action,'lineclick'), h = get(gca,'UserData'); hndlList = get(gcf,'UserData'); if get(hndlList(5),'value')==1, % Show all set(h,'color',linecolor(1)) set(h(s),'color',linecolor(2)) else set(h,'visible','off','color',linecolor(1)) set(h(s),'visible','on','color',linecolor(2)) end set(hndlList(7),'value',s,'userdata',s); sosdemo('puttitle') return elseif strcmp(action,'showtoggle'), v = get(gco,'value'); h = get(gca,'UserData'); hndlList = get(gcf,'UserData'); hlast = floor(get(hndlList(7),'value')); % Slider value if v==1, set(h,'visible','on') else set(h,'visible','off') set(h(hlast),'visible','on') end return elseif strcmp(action,'order'), v = get(gco,'UserData'); s = get(gco,'String'); vv = eval(s,num2str(v)); if vv<1, vv = v; end vv = round(vv); set(gco,'Userdata',vv,'String',num2str(vv)) sosdemo('filter') return elseif strcmp(action,'cutoff'), v = get(gco,'UserData'); s = get(gco,'String'); if length(v) == 1, vv = eval(s,num2str(v)); else vv = eval(s,['[' num2str(v(1)) ' ' num2str(v(2)) ']']); end if any(vv<0 | vv>1), vv = v; end if length(vv)>1, if diff(vv)<0, vv = v; end, end vv = round(vv*100)/100; if length(vv) == 2 set(gco,'Userdata',vv, ... 'String', [ '[' num2str(vv(1)) ' ' num2str(vv(2)) ']' ] ) else set(gco,'Userdata',vv,'String', [ '[' num2str(vv(1)) ']' ] ) end if ~all(v == vv), sosdemo('filter'), end return elseif strcmp(action,'filter'), % store the second order sections in the UserData of the filter popup set(gcf,'Pointer','watch'); hndlList=get(gcf,'Userdata'); upHndl = hndlList(1); filterHndl = hndlList(2); orderHndl = hndlList(3); cutoffHndl = hndlList(4); btn1Hndl = hndlList(5); btn2Hndl = hndlList(6); slideHndl = hndlList(7); leftHndl = hndlList(8); rightHndl = hndlList(9); cascadeHndl = hndlList(12); gridHndl = hndlList(13); v = get(filterHndl,'value'); op = get(filterHndl,'string'); op = deblank(op(v,:)); n = get(orderHndl,'UserData'); wn = get(cutoffHndl,'UserData'); v = get(upHndl,'value'); updown = get(upHndl,'String'); updown = deblank(updown(v,:)); cascade = get(cascadeHndl,'value'); gr = get(gridHndl,'value'); Rpass = 3; Rstop = 30; if strcmp(op,'Butter'), [z,p,k] = butter(n,wn); elseif strcmp(op,'Cheby1'), [z,p,k] = cheby1(n,Rpass,wn); elseif strcmp(op,'Cheby2'), [z,p,k] = cheby2(n,Rstop,wn); elseif strcmp(op,'Ellip'), [z,p,k] = ellip(n,Rpass,Rstop,wn); else error('Unknown filter type.'); end sos = zp2sos(z,p,k,lower(updown)); section = size(sos,1); set(slideHndl,'max',section); val = min(section,get(slideHndl,'value')); set(slideHndl,'value',val,'userdata',val); set(filterHndl,'UserData',sos) sosdemo('createplot') set(gcf,'Pointer','arrow'); return elseif strcmp(action,'grids'), gr = get(gco,'value'); if gr, grid on, else grid off, end return elseif strcmp(action,'closehelp'), % Restore close button help behind helpfun's back ch = get(gcf,'ch'); for i=1:length(ch), if strcmp(get(ch(i),'type'),'uicontrol'), if strcmp(lower(get(ch(i),'String')),'close'), callbackStr = get(ch(i),'callback'); k = findstr('; sosdemo(',callbackStr); callbackStr = callbackStr(1:k-1); set(ch(i),'callback',callbackStr) break; end end end ch = get(0,'ch'); if ~isempty(find(ch==s)), figure(s), end % Make sure figure exists elseif strcmp(action,'order'), v = get(gco,'Userdata'); s = get(gco,'String'); vv = eval(s,num2str(v)); if vv<1, vv = v; end vv = round(vv); set(gco,'Userdata',vv,'String',num2str(vv)) sosdemo('filter') return elseif strcmp(action,'info'), set(gcf,'pointer','arrow') ttlStr = get(gcf,'Name'); hlpStr1 = [ ... ' ' ' This demo lets you examine the internal struct- ' ' ture of a digital filter. ' ' ' ' It designs a Butterworth, Chebyshev type I or II, ' ' or elliptic digital filter of the specified "order" ' ' and with the specified cutoff frequencies. ' ' ' ' "Order" specifies the filter order for lowpass ' ' filters, and half the filter order for bandpass ' ' filters. ' ' ' ' "Filter cutoffs" can be a two element vector for ' ' bandpass filters, or a scalar for lowpass filters. ' ' ' ]; hlpStr2 = [ ... ' The function ZP2SOS transforms a digital filter ' ' into "second order sections" form. ' ' ' ' It groups pairs of poles and zeros together ' ' so that the cascade of the second order filters ' ' (or "sections") is equivalent to the original filter.' ' ' ' ZP2SOS pairs the pole-zero pairs, orders ' ' them, and scales them, so that in certain fixed ' ' point implementations the cascade filter avoids ' ' overflow and has minimal noise gain. ' ' ' ' The "Up" and "Down" options tell ZP2SOS which ' ' way to order the sections: ' ' "Up" - places pole-zero pairs with poles ' ' closest to the unit circle (high "Q" filters) ' ' at end of cascade. ' ' "Down" - places pole-zero pairs in the ' ' opposite order. ']; hlpStr3 = [ ... ' The slider at the bottom of the figure lets you ' ' choose one of the responses to highlight or ' ' display. You can also highlight a response by ' ' clicking on it. ' ' ' ' The four toggle switches on the right have the ' ' following effects: ' ' "Show all" - shows all of the sections at once ' ' or just the selected one. ' ' "3-D plot" - allows you change from a 3-D to a ' ' 2-D view. ' ' "Cascade" - with this turned on, the n-th resp- ' ' onse is the cascade of sections 1 through n. ' ' If turned off, the n-th response is simply the ' ' response of section n. ' ' "Grid" - toggles grid on and off. ' ' ' ' File name: sosdemo.m ']; myFig = gcf; helpfun(ttlStr,hlpStr1,hlpStr2,hlpStr3); return % avoid fancy, self-modifying code which % is killing the callback to this window's close button % if you press the info button more than once. % Also, a bug on Windows MATLAB is killing the % callback if you hit the info button even once! % Protect against gcf changing -- Change close button behind % helpfun's back ch = get(gcf,'ch'); for i=1:length(ch), if strcmp(get(ch(i),'type'),'uicontrol'), if strcmp(lower(get(ch(i),'String')),'close'), callbackStr = [get(ch(i),'callback') ... '; sosdemo(''closehelp'',' num2str(myFig) ')']; set(ch(i),'callback',callbackStr) return end end end return end % if strcmp(action, ... set(gcf,'pointer','arrow') function c = linecolor(num) % LINECOLOR Return the line color of a line % Input = 1 or 2, 1 for highlighted, 2 for not highlighted co = get(gcf,'defaultaxescolororder'); c = co(min(num,size(co,1)),:);