function [N, ff, aa, wts] = remezord(fcuts, mags, devs, fsamp)
%REMEZORD  FIR order estimator (lowpass, highpass, bandpass, multiband)
%	[N,Fo,Mo,W] = REMEZORD(F,M,DEV,Fs) finds the approximate order N, 
%	normalized frequency band edges Fo, frequency band magnitudes Mo and 
%	weights W to be used by the REMEZ function as follows:
%	    B = REMEZ(N,Fo,Mo,W)
%	The resulting filter will approximately meet the specifications given
%	by the input parameters F, M, and DEV.  F is a vector of cutoff
%	frequencies in Hz, in ascending order between 0 and half the sampling
%	frequency Fs. If you do not specify Fs, it defaults to 2.  M is a vector
%	specifying the desired function's amplitude on the bands defined by F.
%	The length of F is twice the length of M, minus 2 (it must therefore
%	be even).  The first frequency band always starts at zero, and the last
%	always ends at Fs/2.  DEV is a vector of maximum deviations or ripples 
%	allowable for each band.
%
%	EXAMPLE: Design a lowpass filter with a passband cutoff of 1000Hz, a 
%	stopband cutoff of 2000Hz, passband ripple of 0.01, stopband ripple 
%	of 0.1, and a sampling frequency of 8000Hz:
%
%	    [n,fo,mo,w] = remezord( [1000 2000], [1 0], [0.1 0.01], 8000 );
%	    b = remez(n,fo,mo,w);
%
%	CAUTION 1: The order N is often underestimated. If the filter does not
%	meet the original specifications, a higher order such as N+1 or N+2 
%	will.
%	CAUTION 2: Results are inaccurate if cutoff frequencies are near zero
%	frequency or the Nyquist frequency.

%	Author(s): J. H. McClellan, 10-28-91
%	Copyright (c) 1984-94 by The MathWorks, Inc.
%	$Revision: 1.5 $  $Date: 1994/01/25 17:59:45 $

%	References:
%	  [1] Rabiner & Gold, Theory and Applications of DSP, pp. 156-7.     

error(nargchk(3,4,nargin))
typ = 'Bandpass';
if nargin == 3,
    fsamp = 2;
end
fcuts = fcuts/fsamp;       %  NORMALIZE to sampling frequency

% Turn vectors into column vectors
fcuts = fcuts(:);
mags = mags(:);
devs = devs(:);

[mf,nf] = size(fcuts);
[mm,nm] = size(mags);
[md,nd] = size(devs);
nbands = mm;

if length(mags) ~= length(devs)
    error('Requires M and DEV to be the same length.')
end

if mf ~= 2*(nbands-1)
    error('Length of F must be 2*length(M)-2.')
end

zz = mags==0;             % find stopbands
devs = devs./(zz+mags);   % divide delta by mag to get relative deviation

% Determine the smallest width transition zone
% Separate the passband and stopband edges
%
f1 = fcuts(1:2:(mf-1));
f2 = fcuts(2:2:mf);
[df,n] = min(f2-f1);

%=== LOWPASS case: Use formula (ref: Herrmann, Rabiner, Chan)
%
if( nbands==2 )
     L = remlpord( f1(n), f2(n), devs(1), devs(2));

%=== BANDPASS case:
%    - try different lowpasses and take the WORST one that
%        goes thru the BP specs; try both transition widths
%    - will also do the bandreject case
%    - does the multi-band case, one bandpass at a time.
%    
else
  L = 0;
  for i=2:nbands-1,
    L1 = remlpord( f1(i-1), f2(i-1), devs(i),   devs(i-1) );
    L2 = remlpord( f1(i),   f2(i),   devs(i),   devs(i+1) );
    L = max( [L; L1; L2] );
  end
end

N = ceil( L ) - 1;   % need order, not length, for remez

end

%=== Make the MATLAB compatible specs for remez
%
ff = [0;2*fcuts;1];
am(1:2:2*nbands-1) = mags;	
aa = [am';0] + [0;am'];
wts = ones(size(devs))*max(devs)./devs;

