www.gusucode.com > signal 工具箱matlab源码程序 > signal/+fdesign/@rsrc/ifir.m

    function varargout = ifir(this, varargin)
%IFIR   Design an interpolated FIR filter.

%   Copyright 2005-2014 The MathWorks, Inc.

% Make sure that IFIR is valid for this set of specifications.
if ~isdesignmethod(this, 'ifir')
    error(message('signal:fdesign:rsrc:ifir:invalidMethod', 'IFIR', this.SpecificationTypeListeners));
end

validatercf(this);

% Parse the inputs for the multirate filter structure.
[filtstruct, varargin] = parsestruct(this, 'firsrc', 'ifir', varargin{:});

filtstruct = ['mfilt.', filtstruct];

dfactor = this.DecimationFactor;
ifactor = this.InterpolationFactor;

% If System object is requested, first design mfilt then later convert to
% System object if possible
sysObjFlag = false;
sysObjIdx = find(cellfun(@(x)strcmpi('SystemObject',x),varargin),1);
if ~isempty(sysObjIdx)
    if varargin{sysObjIdx+1} == 1
        sysObjFlag = true;
        varargin(sysObjIdx:sysObjIdx+1) = [];  % remove the property so that result is mfilt at first
    end
end

[Hd, upfactor] = ifir(this.CurrentFDesign, varargin{:}, ...
    'rcf', max(ifactor, dfactor));

fm = getfmethod(Hd);

if isa(Hd, 'dfilt.cascade')
    [Hm,final_upfactor] = cascadenoble(Hd,upfactor,ifactor,dfactor,filtstruct);
    if sysObjFlag
        Hm = sysobj(Hm);  % return dsp.FilterCascade
    end
elseif isa(Hd, 'dfilt.parallel'),
    if sysObjFlag
        % Error out because parallel structure is not supported by System objects
        error(message('signal:fdesign:decimator:ifir:ParallelNotSupportedBySystemObjects'));
    end
    % Find cascade branch within parallel
    if isa(Hd.stage(1),'dfilt.cascade'),
        s1 = 1;
        s2 = 2;
    else
        s1 = 2;
        s2 = 1;
    end
    [Hm1,final_upfactor] = cascadenoble(Hd.stage(s1),upfactor,ifactor,dfactor,filtstruct);
    if ifactor > dfactor,
        Hvec = interpdelaynoble(this,Hd.stage(s2),ifactor);
        Hvec = interpmergedelays(this,Hvec);
        % Merge downsampler
        if strcmpi(class(Hvec(end)),'mfilt.firinterp'),
            Hvec(end) = mfilt.firsrc(Hvec(end).InterpolationFactor,dfactor,...
                Hvec(end).Numerator);
        else
            % Must be a delay
            Hvec(end) = mfilt.firdecim(dfactor,[zeros(1,Hvec(end).Latency),1]);
        end
    else
        Hvec = decimdelaynoble(this,Hd.stage(s2),dfactor);
        Hvec = decimmergedelays(this,Hvec(end:-1:1));
          % Merge upsampler
        if strcmpi(class(Hvec(1)),'mfilt.firdecim'),
            Hvec(1) = mfilt.firsrc(ifactor,Hvec(1).DecimationFactor,...
                ifactor*Hvec(1).Numerator);
        else
            % Must be a delay
            Hvec(1) = mfilt.firinterp(ifactor,[zeros(1,Hvec(1).Latency),1]);
        end
    end     
    Hm2 = cascade(Hvec);
    Hm = parallel(Hm1,Hm2);
else

    % If we are returned a single section, the design was simple enough
    % that we can just use a single interpolator.
    Hm = feval(filtstruct, ifactor, dfactor, ifactor*Hd.Numerator);
    final_upfactor = 1;
    
    if sysObjFlag
        Hm = sysobj(Hm);  % return dsp.FilterCascade
    end
end

if isa(Hm, 'dsp.private.FilterAnalysis') % if returning a System object
    setMetaData(Hm,this,fm);
else
    Hm.setfdesign(this);
    Hm.setfmethod(fm);
end

if nargout
    varargout = {Hm, final_upfactor};
else
    if this.NormalizedFrequency,
        inputs = {'NormalizedFrequency', 'On'};
    else
        inputs = {'Fs', this.Fs};
    end

    fvtool(Hm, inputs{:});
end

%--------------------------------------------------------------------------
function [Hm,final_upfactor] = cascadenoble(Hd,upfactor,ifactor,dfactor,filtstruct)

% If InterpolationFactor (LK) is greater than DecimationFactor (M).
%
%  /\ LK -- H1(z) -- H2(z^L) -- \/ M
%
%  /\ LK -- H2(z^L) -- H1(z) -- \/ M
%
%  /\ K -- H2(z) -- /\ L -- H1(z) -- \/ M
%
%  H2_interp_K(z) -- H1_src_L_M(z)
%
% If DecimationFactor (MK) is greater than InterpolationFactor (L)
%
%  /\ L -- H1(z) -- H2(z^M) -- \/ MK
%
%  /\ L -- H1(z) -- \/M -- H2(z) -- \/ K
%
%  H1_src_L_M(z) -- H2_decim_K(z)
%
%  J & K are often 1, in which case we dont need a multirate.

% When the decimation factor and upsampling factor do not share a
% denominator, we use the interpolation first code.
if ifactor > dfactor || gcd(upfactor, dfactor) == 1

    % Use GCD here bcause UPFACTOR and IFACTOR may not be integer
    % factors of each other, but we are sure to have some divisors
    % be equal.
    L = gcd(upfactor, ifactor);
    K = ifactor/L;
    final_upfactor = upfactor/L;

    % Remove the extra ones from the numerator.  We will get these
    % automatically when we use the interpolating structure.
    b_h2 = Hd.Stage(2).Numerator(1:L:end);

    % If there is "left over" interpolation put it into the first stage.
    if K == 1
        Hm1 = Hd.Stage(2);
        Hm1.Numerator = b_h2;
    else
        Hm1 = mfilt.firinterp(K, K*b_h2);
    end

    % Create the 2nd stage.
    if L == 1
        if dfactor == 1
            Hm2 = Hd.Stage(1);
        else
            Hm2 = mfilt.firdecim(dfactor, Hd.Stage(1).Numerator);
        end
    else
        Hm2 = feval(filtstruct, L, dfactor, L*Hd.Stage(1).Numerator);
    end
else
    M = gcd(upfactor, dfactor);
    K = dfactor/M;
    final_upfactor = upfactor/K;

    % Remove the extra ones from the numerator.  We will get these
    % automatically when we use the interpolating structure.
    b_h2 = Hd.Stage(2).Numerator(1:M:end);

    % Create the 1st stage.
    if M == 1
        if ifactor == 1
            Hm1 = Hd.Stage(1);
        else
            Hm1 = mfilt.firinterp(ifactor, ifactor*Hd.Stage(1).Numerator);
        end
    else
        Hm1 = feval(filtstruct, ifactor, M, ifactor*Hd.Stage(1).Numerator);
    end

    % If there is "left over" interpolation put it into the 2nd stage.
    if K == 1
        Hm2 = Hd.Stage(2);
        Hm2.Numerator = b_h2;
    else
        Hm2 = mfilt.firdecim(K, b_h2);
    end
end
Hm = mfilt.cascade(Hm1, Hm2);

% [EOF]