⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fdellip.m

📁 有关matlab的电子书籍有一定的帮助希望有用
💻 M
📖 第 1 页 / 共 3 页
字号:
function varargout = fdellip(varargin)
%fdellip  Elliptic Module for filtdes.

%   Author: T. Krauss
%   Copyright (c) 1988-98 by The MathWorks, Inc.
%   $Revision: 1.7 $

% Change this global to static when available:
%  following are common to several modules
global minOrdCheckbox bandpop order pbspecs sbspecs pbmeasures sbmeasures
global passframe stopframe passframe1 stopframe1
%  following static to fdellip
global f1 f2 f3 f4 Fp1 Fp2 Rp Rs 
global Fs1m Fs2m 
global order0 order1
global ax L1 L2 Lresp L3_1 L3_2
global Fs

switch varargin{1}
case 'init'

    filt = varargin{2};
    Fs = filt.Fs;
    [setOrderFlag_init, type_init, f_init, Rp_init, Rs_init, ...
      order_init, Fpass_init] = initSpecs(filt);

    [minOrdCheckbox bandpop order pbspecs sbspecs ...
         pbmeasures sbmeasures passframe stopframe ...
         passframe1 stopframe1 ax Lresp L1 L2 order1 ...
         L3_1 L3_2] = fdutil('commonObjects');
    order0 = order;
             
    co = get(0,'defaultaxescolororder');
    lo = get(0,'defaultaxeslinestyleorder');

    if ~strcmp(bandpop.userdata,'fdellip')
       % this module is not current
        bandpop.userdata = 'fdellip';
            
        minOrdCheckbox.callback = 'fdellip(''checkbox'')';
        bandpop.callback = 'fdellip(''newtype'')';         

        order0.callback = 'fdellip(''dirty'')';
                        
        set(ax,'title','Frequency Response',...
              'xlabel','Frequency',...
              'ylabel','Magnitude (dB)',...
              'ylim',[-150 10],'xlim',[0 Fs/2],...
              'xlimbound',[0 Fs/2]);

        sethelp
        
        set(Lresp,'buttondownfcn','fdellip(''LrespDown'')')
                       
        set(L1,'buttondownfcn','fdellip(''L1down'')',...
               'buttonupfcn','fdellip(''L1up'')',...
               'color',co(min(2,size(co,1)),:))
        set(L2,'buttondownfcn','fdellip(''L2down'')',...
               'buttonupfcn','fdellip(''L2up'')',...
               'color',co(min(2,size(co,1)),:))
        set(L3_1,'xdata',Fpass_init([1 1]),...
                 'segmentdragcallback',{'fdellip(''L3_drag'',1)'},...
                 'buttondownfcn','fdellip(''L3_down'',1)',...
                 'buttonupfcn','fdellip(''L1up'')');
        set(L3_2,'xdata',Fpass_init([end end]),...
                 'segmentdragcallback',{'fdellip(''L3_drag'',2)'},...
                 'buttondownfcn','fdellip(''L3_down'',2)',...
                 'buttonupfcn','fdellip(''L1up'')');
        Rp = pbspecs(3);
        set(Rp,'value',Rp_init,'label','Rp')
        Rs = sbspecs(3);
        set(Rs,'value',Rs_init,'label','Rs')
        set(Rp,'callback','fdellip(''Rpchange'')')
        set(Rs,'callback','fdellip(''Rschange'')')
        Fp1 = pbspecs(1);
        Fp2 = pbspecs(2);
        Fs1m = sbmeasures(1);
        Fs2m = sbmeasures(2);
        % fdutil('changeToEdit',pbmeasures(1:3))
        fdutil('changeToText',[Fs1m Fs2m])
    end    
    set(minOrdCheckbox,'visible','on')
    set(Rp,'visible','on')
    set(Rs,'visible','on')
    set(sbspecs(1),'visible','on')
    set(Fs1m,'visible','on')
    set(pbmeasures(1),'visible','off')
    set(pbmeasures(2),'visible','off')
    set(pbmeasures(3),'visible','off')
    set(sbmeasures(3),'visible','off')
        
    fdellip('newfilt',setOrderFlag_init,type_init,f_init,Rp_init,...
               Rs_init,Fpass_init,order_init)
    
    [filt, errstr] = fdutil('callModuleApply',...
                               'fdellip',filt,'');
    varargout{1} = filt;
    varargout{2} = errstr;

case 'apply'    
    
    filt = varargin{2};
    msg = varargin{3};
    if strcmp(msg,'motion') & ~strcmp(get(Lresp,'erasemode'),'xor')
        Lresp.erasemode = 'xor';
        drawnow
    end
    
    % DESIGN FILTER!!!!
    type = bandpop.value;
    setOrderFlag = ~minOrdCheckbox.value;
    if ~setOrderFlag     % estimate order
        [n,Fpass] = estimateOrder(type,Rp.value,Rs.value,Fs,...
                 f1.value,f2.value,f3.value,f4.value);
    else
        n = order.value;
        Fpass = Fp1.value * 2/Fs;
        if type > 2  % pass/stop
            Fpass(2) = Fp2.value * 2/Fs;
        end
    end
    
    % save specifications in specifications structure:
    specstruc.setOrderFlag = setOrderFlag;
    specstruc.type = type;
    if ~setOrderFlag
        f = getFrequencyValues(type,f1,f2,f3,f4,Fs);
        specstruc.f = f;
    else
        specstruc.f = [];  % place holder, will be defined by measureFilt
    end
    specstruc.Rp = Rp.value;
    specstruc.Rs = Rs.value;
    specstruc.Fpass = Fpass;
    specstruc.order = n;
                          
%     if ~setOrderFlag & isfield(filt.specs,'fdellip') & ...
%         isequal(specstruc.Fpass,filt.specs.fdellip.Fpass) ...
%         & isequal(specstruc.order,filt.specs.fdellip.order)
%         filt.specs.fdellip = specstruc;
%         varargout{1} = filt;
%         varargout{2} = '';
%         return
%     end

    if n>50
        [continueFlag,errstr] = fdutil('largeWarning',n,msg);
        if ~continueFlag
            varargout{1} = filt;
            varargout{2} = errstr;
            return
        end
    end
        
    % design filter:
    if type == 2
        [b,a] = ellip(n,specstruc.Rp,specstruc.Rs,Fpass,'high');
    elseif type == 4
        [b,a] = ellip(n,specstruc.Rp,specstruc.Rs,Fpass,'stop');
    else
        [b,a] = ellip(n,specstruc.Rp,specstruc.Rs,Fpass);
    end
        
    % compute frequency response:
    nfft = filtdes('nfft');
    [H,ff] = freqz(b,a,nfft,Fs);
    % avoid log of 0 at 0 and Fs/2:
    if H(1) == 0, H(1) = H(2); end
    if H(end) == 0, H(end) = H(end-1); end
    Hlog = 20*log10(abs(H(:)));
    set(Lresp,'xdata',ff,'ydata',Hlog);
    
    % make measurements:
    if ~ ((strcmp(msg,'motion') | strcmp(msg,'up')) & ~setOrderFlag ...
             & strcmp(get(order1,'visible'),'on') )  | ...
       (~setOrderFlag & (filt.specs.fdellip.type ~= type))
        objSetupFlag = 1;
    else
        objSetupFlag = 0;
    end
    
    specstruc = measureFilt(objSetupFlag,specstruc,Fs,order1,...
                  sbmeasures,Fs1m,Fs2m,ff,Hlog,L1,L2,ax);
                      
    if ~strcmp(msg,'motion')
        % if design is due to a drag operation, lines are already solid
        % so we can skip this step
        Lresp.linestyle = '-';
        L1.linestyle = '-';
        L2.linestyle = '-';
        set(L3_1,'linestyle','-')
        set(L3_2,'linestyle','-')
        if strcmp(L3_1.erasemode,'normal')
            warning('L3_1 erasemode is normal... why?')
            L3_1.erasemode = 'xor';
            L3_2.erasemode = 'xor';
        end
    end
    
    % alter filt fields:
    filt.tf.num = b;
    filt.tf.den = a;
    filt.specs.fdellip = specstruc;
    filt.zpk = [];  % clear out in case filtview has written these
    filt.ss = [];
    filt.sos = [];

    varargout{1} = filt;
    varargout{2} = '';
        
case 'revert'
    filt = filtdes('filt');
    oldtype = filt.specs.fdellip.type;
    % need to restore filter type
    setOrderFlag = filt.specs.fdellip.setOrderFlag;
    oldSetOrderFlag = ~minOrdCheckbox.value;
    f = filt.specs.fdellip.f;
    Rpass = filt.specs.fdellip.Rp;
    Rstop = filt.specs.fdellip.Rs;
    Fpass = filt.specs.fdellip.Fpass;
    N = filt.specs.fdellip.order;
    fdellip('newfilt',setOrderFlag,oldtype,f,Rpass,Rstop,Fpass,N)

    specStruc = measureFilt(1,filt.specs.fdellip,Fs,order1,...
                  sbmeasures,Fs1m,Fs2m,Lresp.xdata,Lresp.ydata,L1,L2,ax);

    Lresp.linestyle = '-';
    L1.linestyle = '-';
    L2.linestyle = '-';
    set(L3_1,'linestyle','-')
    set(L3_2,'linestyle','-')
    
    for i=1:2
        set(sbmeasures(i),'enable','on')
    end
    set(order1,'enable','on')
    
case 'help'
    str = fdhelpstr('fdellip');
    varargout{1} = str{2};

case 'description'
    varargout{1} = 'Elliptic IIR';

case 'Fs'
% Sampling frequency has changed

%   The filter spec does not depend on the sampling frequency
    filt = varargin{2};
    varargout{1} = filt;
    
% update various lines and specifications:
    oldFs = varargin{3};
    Fs = filt.Fs;  % new Fs
    if minOrdCheckbox.value
        f1.value = f1.value*Fs/oldFs;
        f2.value = f2.value*Fs/oldFs;
        f3.value = f3.value*Fs/oldFs;
        f4.value = f4.value*Fs/oldFs;
        f1.range = f1.range*Fs/oldFs;
        f2.range = f2.range*Fs/oldFs;
        f3.range = f3.range*Fs/oldFs;
        f4.range = f4.range*Fs/oldFs;
    else
        Fp1.value = Fp1.value*Fs/oldFs;
        Fp2.value = Fp2.value*Fs/oldFs;
        Fp1.range = Fp1.range*Fs/oldFs;
        Fp2.range = Fp2.range*Fs/oldFs;
    end
    
    ax.xlimbound = [0 Fs/2];
    ax.xlim = ax.xlim*Fs/oldFs;
    ax.xlimpassband = ax.xlimpassband*Fs/oldFs;
    L1.xdata = L1.xdata*Fs/oldFs;
    L2.xdata = L2.xdata*Fs/oldFs;
    Lresp.xdata = Lresp.xdata*Fs/oldFs;
    L3_1.xdata = L3_1.xdata*Fs/oldFs;
    L3_2.xdata = L3_2.xdata*Fs/oldFs;
    
    Fs1m.value = Fs1m.value*Fs/oldFs;
    Fs2m.value = Fs2m.value*Fs/oldFs;
    
%---------------------------------------------------------------------
% -------- following cases are module specific --------- 
%---------------------------------------------------------------------

case 'dirty'
% fdellip('dirty')
% Callback of a spec ... to change appearance so user can
%  see that the specs and the currently designed filter
%  don't match
    if Lresp.linestyle ~= ':'
        Lresp.linestyle = ':';
        L1.linestyle = ':';
        L2.linestyle = ':';
        L3_1.linestyle = ':';
        L3_2.linestyle = ':';
    end
    for i=1:2
        set(sbmeasures(i),'enable','off')
    end
    set(order1,'enable','off')

%---------------------------------------------------------------------
% fdellip('clean')
% opposite of 'dirty'
case 'clean'
    if Lresp.linestyle ~= '-'
        Lresp.linestyle = '-';
        L1.linestyle = '-';
        L2.linestyle = '-';
        L3_1.linestyle = '-';
        L3_2.linestyle = '-';
    end
    for i=1:2
        set(sbmeasures(i),'enable','on')
    end
    set(order1,'enable','on')
    filtdes('setenable','off')
    
%---------------------------------------------------------------------
% fdellip('fchange',i)
%    Callback when frequency i has changed
%    Need to update ranges and lines L1, L2
case 'fchange'
    type = bandpop.value;
    if nargin == 1
    % a passband freq spec has changed  (we are in set mode)
        if type >= 3
            Fpass = [Fp1.value Fp2.value];
            if Fpass(1) >= Fpass(2)
                FpassOld = [L3_1.xdata(1) L3_2.xdata(1)];
                i = find(Fpass~=FpassOld);  % index of changed band edge
                if i == 1
                    Fpass(2) = (Fpass(1)+Fs/2)/2;
                    set(Fp2,'value',Fpass(2))
                else
                    Fpass(1) = Fpass(2)/2;
                    set(Fp1,'value',Fpass(1))
                end
            end
            set(L3_1,'xdata',Fpass([1 1]))
            set(L3_2,'xdata',Fpass([2 2]))
        else
            Fpass = Fp1.value;
            set(L3_1,'xdata',Fpass([1 1]))
        end
        
        fdellip('dirty')
        return
    end
    i = varargin{2};
    xd1 = L1.xdata;
    xd2 = L2.xdata;
    f = [f1.value,f2.value,f3.value,f4.value];
    % update lines
    switch type
    case 1
      % L1 xdata = [0 f1 NaN 0 f1]
      % L2 xdata = [f2 Fs/2]
        if i==1
            xd1([2 5]) = f(1);
        else
            xd2(1) = f(2);
        end
    case 2
      % L1 xdata = [f2 Fs/2 NaN f2 Fs/2]
      % L2 xdata = [0 f1]
        if i == 1
            xd2(2) = f(1);
        else
            xd1([1 4]) = f(2);
        end
    case 3  % bandpass
      % L1 xdata = [f2 f3 NaN f2 f3]
      % L2 xdata = [0 f1 NaN f4 Fs/2]
        if xd2(2) ~= f(1)
            xd2(2) = f(1);
        elseif xd1(1) ~= f(2)
            xd1([1 4]) = f(2);
        elseif xd1(2) ~= f(3)
            xd1([2 5]) = f(3);
        elseif xd2(4) ~= f(4)
            xd2(4) = f(4);
        end
    case 4
      % L1 xdata = [0 f1 NaN 0 f1 NaN f4 Fs/2 NaN f4 Fs/2]
      % L2 xdata = [f2 f3]
        if xd1(2) ~= f(1)
            xd1([2 5]) = f(1);
        elseif xd2(1) ~= f(2)
            xd2(1) = f(2);
        elseif xd2(2) ~= f(3)
            xd2(2) = f(3);
        elseif xd1(7) ~= f(4)
            xd1([7 10]) = f(4);
        end
    end
    
    if ~minOrdCheckbox.value   % set order
        %passbandChange = ...
        %  (type==(1:4))*[1 0 0 0; 0 1 0 0;...
        %         0 1 1 0; 1 0 0 1 ]*(i==(1:4))';
        %if passbandChange
        %    fChangeMeas(i,type,Fs,Lresp,L1,L2,f1,f2,f3,f4,Rp,Rs,Fp1,Fp2)
        %    return
        %end
        L3_1.xdata = Fp1.value([1 1]);
        if type>2
            L3_2.xdata = Fp2.value([1 1]);
        end
    else
        [xd1,xd2] = fdutil('validateBands',xd1,xd2,...
                           type,i,f,f1,f2,f3,f4,Fs);
    end

    dirty = 0; % Flag used to indicate that specs have changed.
    
    % If there's a NaN in the data being compared the if-statement will
    % fail (return false) even tough the two variables are equal.  So,
    % remove the NaNs before comparing.
    nonNaNindx_L1 = ~isnan(L1.xdata);
    nonNaNindx_xd1 = ~isnan(xd1);
    if ~isequal(xd1(nonNaNindx_xd1),L1.xdata(nonNaNindx_L1)) 
        % only set if changed
        L1.xdata = xd1;
        dirty = 1;
    end

    % If there's a NaN in the data being compared the if-statement will

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -