function [h,rs] = firemb(M,mag,hmw,del); % [h,rs] = firemb(M,w1,w2,del); % multiband linear phase FIR filter design with specified ripple sizes % - the derivative of the frequency response amplitude at the half-magnitude % frequencies are set equal i % parameters % h : filter of length 2*M+1 % rs : reference set upon convergence % mag : magnitudes of the ideal % hmw : half-magnitude frequencies % hmw(i) should be in the interval (0,pi) % del : delta for the bands % subprograms needed % localmax, frefine, dropw % % (this program has not been tested extensively and may % have problems at times) % % % EXAMPLES % % M = 32; % mag = [0 1 0]; % del = [0.05 0.05 0.05]; % hmw = [.3 .7]*pi; % [h,rs] = firemb(M,mag,hmw,del); % % M = 22; % mag = [0 1 0 1]; % del = [0.05 0.05 0.05 0.05]; % hmw = [.25 .5 .75]*pi; % [h,rs] = firemb(M,mag,hmw,del); % % M = 32; % mag = [0 1 0 1 0]; % del = [0.05 0.05 0.05 0.05 0.05]; % hmw = [.2 .4 .6 .8]*pi; % [h,rs] = firemb(M,mag,hmw,del); % % M = 42; % mag = [1 0 1 0 1 0]; % del = [0.05 0.05 0.05 0.05 0.05 0.05]; % hmw = [0.1667 0.3333 0.5000 0.6667 0.8333]*pi; % [h,rs] = firemb(M,mag,hmw,del); % ------------------ initialize constants --------------------------- mag = mag(:)'; del = del(:)'; hmw = hmw(:)'; K = length(mag); L = 2^ceil(log2(10*M)); w = [0:L]*pi/L; % frequency axis NR = M +4 - 2*K; % number of _nonspecified_ interpolation points SN = 1e-8; % Small Number (stopping criterion) Z = zeros(2*(L+1-M)-3,1); v = [0, hmw, pi]; Ahm = (mag(1:K-1)+mag(2:K))/2; % value of A at half-magnitude frequencies. up = mag + del; lo = mag - del; PF = 1; % PF : flag : Plot Figures % ------------------ initialize reference set ---------------------------- % parity requirements ==> -1 : doesn't matter, 0 : even, 1 : odd pv = [-1]; for k = 2:K-1 if ((mag(k)>mag(k-1))&(mag(k)>mag(k+1))) | ((mag(k) 1 [temp,l] = max(nb); nb(l(1)) = nb(l(1)) - 2; t = t - 2; end if t == 1 if nb(1) > nb(K) nb(1) = nb(1)-1; else nb(K) = nb(K)-1; end end % calculate initial reference set rs = []; for k = 1:K if nb(k)>1 rs = [rs, v(k)+(v(k+1)-v(k))*[1:nb(k)]/(nb(k)+1)]; else rs = [rs, (v(k)+v(k+1))/2]; end if k < K rs = [rs, hmw(k)]; end end % ------------------ initialize interpolation values --------------------- if mag(1) < mag(2) Y = lo(1)*(1-(-1).^(nb(1):-1:1))/2 + up(1)*((-1).^(nb(1):-1:1)+1)/2; else Y = up(1)*(1-(-1).^(nb(1):-1:1))/2 + lo(1)*((-1).^(nb(1):-1:1)+1)/2; end Y = [Y, Ahm(1)]; for k = 2:K if mag(k)>mag(k-1) Y = [Y, up(k)*(1-(-1).^(1:nb(k)))/2 + lo(k)*((-1).^(1:nb(k))+1)/2]; else Y = [Y, lo(k)*(1-(-1).^(1:nb(k)))/2 + up(k)*((-1).^(1:nb(k))+1)/2]; end if k < K Y = [Y, Ahm(k)]; end end % ------ calculate derivative constraint vector --------- V = ones(K-2,1)*(0:M) .* [sin((hmw(1:K-2))'*[0:M])-sin((((-1).^pv(2:K-1)).*hmw(2:K-1))'*[0:M])]; % begin looping Err = 1; while Err > SN % --------------- calculate cosine coefficients ----------------------- a = [cos(rs(:)*[0:M]); V]\[Y'; zeros(K-2,1)]; % --------------- calculate frequency response ------------------------ H = real(fft([a(1);a(2:M+1)/2;Z;a(M+1:-1:2)/2])); H = H(1:L+1); % --------------- determine local max and min ------------------------- v1 = localmax(H); v2 = localmax(-H); if v1(1) < v2(1) s = 0; else s = 1; end ri = sort([v1; v2]); rs = (ri-1)*pi/L; rs = frefine(a,rs); nb = []; f = find(rsmag(k-1) Y = [Y, up(k)*(1-(-1).^(1:nb(k)))/2 + lo(k)*((-1).^(1:nb(k))+1)/2]; else Y = [Y, lo(k)*(1-(-1).^(1:nb(k)))/2 + up(k)*((-1).^(1:nb(k))+1)/2]; end end % --------------- slim down the set of local max and min -------------- % --------------- to obtain new reference set of correct size --------- if length(rs) > NR [rs,Y,Er] = dropw(rs,Y,Er,length(rs)-NR); end % calculate error Err = max(abs(Er))-1; fprintf(1,' Err = %20.15f\n',Err); % --------------- update no of ref freq in each band ---------------------------- nb = []; f = find(rs