www.gusucode.com > signal 工具箱matlab源码程序 > signal/fir2.m
function [b,a] = fir2(nn, ff, aa, npt, lap, wind) %FIR2 FIR arbitrary shape filter design using the frequency sampling method. % B = FIR2(N,F,A) designs an Nth order linear phase FIR digital filter % with the frequency response specified by vectors F and A and returns % the filter coefficients in length N+1 vector B. % % The vectors F and A specify the frequency and magnitude breakpoints for % the desired frequency response. The frequencies in F must be given in % increasing order with 0.0 < F < 1.0 and 1.0 corresponding to half the % sample rate. The first and last elements of F must equal 0 and 1 % respectively. % % B = FIR2(N,F,A,NPT) specifies the number of points, NPT, for the grid % onto which FIR2 linearly interpolates the frequency response. NPT must % be greater than 1/2 the filter order (NPT > N/2). If desired, you can % interpolate F and A before passing them to FIR2. % % B = FIR2(N,F,A,NPT,LAP) specifies the size of the region, LAP, that % FIR2 inserts around duplicate frequency points to provide a smooth but % steep transition in the requested frequency response. % % By default FIR2 windows the impulse response with a Hamming window. % Other available windows, including Boxcar, Hann, Bartlett, Blackman, % Kaiser and Chebwin can be specified with an optional trailing argument. % % For example, % B = FIR2(N,F,A,bartlett(N+1)) uses a Bartlett window. % B = FIR2(N,F,A,chebwin(N+1,R)) uses a Chebyshev window. % % For filters with a gain other than zero at Fs/2, e.g., highpass % and bandstop filters, N must be even. Otherwise, N will be % incremented by one. In this case the window length should be % specified as N+2. % % % Example 1: % % Design a 30th-order lowpass filter and overplot the desired % % frequency response with the actual frequency response. % % f = [0 0.6 0.6 1]; % Frequency breakpoints % m = [1 1 0 0]; % Magnitude breakpoints % b = fir2(30,f,m); % Frequency sampling-based FIR filter design % [h,w] = freqz(b,1,128); % Frequency response of filter % plot(f,m,w/pi,abs(h)) % legend('Ideal','fir2 Designed') % title('Comparison of Frequency Response Magnitudes') % % % Example 2: % % The chirp.mat file contains a signal, y, that has most of its power % % above fs/4, or half the Nyquist frequency. Design a 34th-order FIR % % highpass filter to attenuate the components of the signal below % % fs/4. Use a cutoff frequency of 0.48. % % load chirp; % Load data (y and Fs) into workspace % y = y + 0.5*rand(size(y)); % Adding noise % f = [0 0.48 0.48 1]; % Frequency breakpoints % m = [0 0 1 1]; % Magnitude breakpoints % b = fir2(34,f,m); % FIR filter design % freqz(b,1,512); % Frequency response of filter % output = filtfilt(b,1,y); % Zero-phase digital filtering % figure; % subplot(211); plot(y,'b'); title('Original Signal') % subplot(212); plot(output,'g'); title('Filtered Signal') % % See also FIR1, FIRLS, CFIRPM, FIRPM, BUTTER, CHEBY1, CHEBY2, YULEWALK, % FREQZ, FILTER, DESIGNFILT. % Author(s): L. Shure, 3-27-87 % C. Denham, 7-26-90, revised % Copyright 1988-2013 The MathWorks, Inc. % % Optional input arguments (see the user's guide): % npt - number for interpolation % lap - the number of points for jumps in amplitude narginchk(3,6); % Cast to enforce precision rules nn = signal.internal.sigcasttofloat(nn,'double','fir2','N',... 'allownumeric'); % Check if A is a valid input. 'F' can not be character as the first and % last elements of F vector should be 0 and 1 respectively so we do not % need to check its type here. aa = signal.internal.sigcasttofloat(aa,'double','fir2','A', 'allownumeric'); [nn,msg1,msg2,msgobj] = firchk(nn,ff(end),aa); if ~isempty(msg1), error(msgobj); end; if ~isempty(msg2), warning(msgobj); end; % Work with filter length instead of filter order nn = nn + 1; if (nargin > 3) % Cast to enforce precision rules npt = signal.internal.sigcasttofloat(npt,'double','fir2','NPT',... 'allownumeric'); if nargin == 4 if length(npt) == 1 if (2 ^ round(log(npt)/log(2))) ~= npt % NPT is not an even power of two npt = 2^ceil(log(npt)/log(2)); end wind = hamming(nn); else wind = npt; if nn < 1024 npt = 512; else npt = 2.^ceil(log(nn)/log(2)); end end lap = fix(npt/25); elseif nargin == 5 % Cast to enforce precision rules lap = signal.internal.sigcasttofloat(lap,'double','fir2','LAP',... 'allownumeric'); if length(npt) == 1 if (2 ^ round(log(npt)/log(2))) ~= npt % NPT is not an even power of two npt = 2.^ceil(log(npt)/log(2)); end if length(lap) == 1 wind = hamming(nn); else wind = lap; lap = fix(npt/25); end else wind = npt; npt = lap; lap = fix(npt/25); end end elseif nargin == 3 if nn < 1024 npt = 512; else npt = 2.^ceil(log(nn)/log(2)); end wind = hamming(nn); lap = fix(npt/25); end % Cast to enforce precision rules wind = signal.internal.sigcasttofloat(wind,'double','fir2','WINDOW',... 'allownumeric'); if nn ~= length(wind) error(message('signal:fir2:UnequalLengths')) end [mf,nf] = size(ff); [ma,na] = size(aa); if ma ~= mf || na ~= nf error(message('signal:fir2:MismatchedDimensions')) end nbrk = max(mf,nf); if mf < nf ff = ff'; aa = aa'; end if abs(ff(1)) > eps || abs(ff(nbrk) - 1) > eps error(message('signal:fir2:InvalidRange')) end ff(1) = 0; ff(nbrk) = 1; % interpolate breakpoints onto large grid H = zeros(1,npt); nint=nbrk-1; df = diff(ff'); if (any(df < 0)) error(message('signal:fir2:InvalidFreqVec')) end if nn>2*npt error(message('signal:fir2:InvalidNpt', ceil( nn/2 ), nn - 1)); end npt = npt + 1; % Length of [dc 1 2 ... nyquist] frequencies. nb = 1; H(1)=aa(1); for i=1:nint if df(i) == 0 nb = ceil(nb - lap/2); ne = nb + lap; else ne = fix(ff(i+1)*npt); end if (nb < 0 || ne > npt) error(message('signal:fir2:SignalErr')) end j=nb:ne; if nb == ne inc = 0; else inc = (j-nb)/(ne-nb); end H(nb:ne) = inc*aa(i+1) + (1 - inc)*aa(i); nb = ne + 1; end % Fourier time-shift. dt = 0.5 .* (nn - 1); rad = -dt .* sqrt(-1) .* pi .* (0:npt-1) ./ (npt-1); H = H .* exp(rad); H = [H conj(H(npt-1:-1:2))]; % Fourier transform of real series. ht = real(ifft(H)); % Symmetric real series. b = ht(1:nn); % Raw numerator. b = b .* wind(:).'; % Apply window. a = 1; % Denominator.