FIR Digital Filter Design
Hilbert Transform Design Example
Windowing an ``Ideal'' Impulse Response computed by the Frequency Sampling MethodSearch Spectral Audio Signal Processing
Would you like to be notified by email when Julius Orion Smith III publishes a new entry into his blog?
We will now create an ``ideal'' Hilbert transformer frequency response with transition bands using the ``frequency sampling'' method. As we saw in the previous section, we must provide transition bands in our ``ideal'' frequency response so that the corresponding ``ideal'' impulse response is not so long that windowing it will give poor results.
If the smallest transition band is
Hz, then the FFT size
should satisfy
. Otherwise, there may be too much time
aliasing in the ``ideal'' impulse response. It is good to try
doubling the FFT size to see if it changes the designed filter. The
only non-obvious part below is ``.^8'' which smoothes the taper
to zero and looks better on a log magnitude scale. It would also make
sense to do a linear taper on a dB scale which corresponds to
exponential tapers to zero.
H = [ ([0:k1-2]/(k1-1)).^8,ones(1,k2-k1+1),...
([k1-2:-1:0]/(k1-1)).^8, zeros(1,N/2-1)];
% rotate buffer so negative frequencies are on the left
% and DC is at N/2+1, and plot:
Hp = [H(N/2+2:N), H(1:N/2+1)];
f = [-0.5 + 1/N : 1/N : 0.5]; % normalized frequency axis
omega = f*(2*pi); % normalized radian frequency axis
plot(f,Hp); grid;
s = sprintf('Desired Frequency Response, FFT size = %d', N);
title(s);
xlabel('Normalized Frequency (cycles/sample)');
ylabel('Gain')
if saveplots, saveplot('hilbertFRIdeal.eps'); end;
if dopause, disp 'Pausing... RETURN to continue'; pause; end;
% Compute impulse response of "ideal" % bandlimited negative-frequency filter: h = ifft(H); hodd = imag(h(1:2:N)); % This should be zero ierr = norm(hodd)/norm(h); % Look at numerical round-off error ierr = 4.1958e-15 % Compute a rough time-aliasing error estimate: aerr = norm(h(N/2-N/32:N/2+N/32))/norm(h) aerr = 4.8300e-04 hp = [h(N/2+2:N), h(1:N/2+1)]; % Plot negative times on the left nzero = N/2; % index of time 0 nshow = (M-1)/2; n = -nshow : nshow; plot(n,real(hp(nzero-nshow:nzero+nshow))); grid; s = sprintf(['Ideal SSB Filter Impulse Response,',... ' Real Part, FFT size = %d'], N); title(s); xlabel('Time (samples)'); ylabel('Amplitude') if saveplots, saveplot('hilbertIRRealIdeal.eps'); end; if dopause, disp 'Pausing... RETURN to continue'; pause; end;
plot(n,imag(hp(nzero-nshow:nzero+nshow))); grid;
s = sprintf(['Ideal SSB Filter Impulse Response,',...
' Imaginary Part, FFT size = %d'], N);
title(s); xlabel('Time (samples)'); ylabel('Amplitude')
if saveplots, saveplot('hilbertIRImagIdeal.eps'); end;
if dopause, disp 'Pausing... RETURN to continue'; pause; end;
hw = wzp .* h; % Apply window to ideal impulse response Hw = fft(hw); % "DTFT" of windowed impulse response % Compute total stopband attenuation: ierr = norm(Hw(N/2+2:N))/norm(Hw) = 3.2350e-06 disp(sprintf(['Analytic-derived stop-band energy is',... ' %g percent of total spectral energy'], 100*ierr)); Stop-band energy is 0.000324 percent of total spectral energy Hwp = [Hw(N/2+2:N), Hw(1:N/2+1)]; % plot (-) freqs on the left Hwpn = abs(Hwp); Hwpn = Hwpn/max(Hwpn); plot(f,20*log10(Hwpn)); grid; s = sprintf(... 'Length %d FIR filter Frequency Response, FFT size = %d',M,N); title(s); xlabel('Normalized Frequency (cycles/sample)'); ylabel('Gain (dB)') if saveplots, saveplot('KaiserHilbertFR.eps'); end; if dopause, disp 'Pausing... RETURN to continue'; pause; end;
% Zoom in on low-frequency transition band
% (same as HF band, by symmetry):
kshow = 2*k1;
krange = kzero-kshow : kzero+kshow;
frange = (krange - kzero)/N;
plot(frange,20*log10(Hwpn(krange))); grid;
hold on; plot((k1-1)/N,1,'+'); hold off;
s = sprintf(
'Low-Frequency Transition Band, f1/fs=%f (marked by "+")',f1/fs);
title(s);
xlabel('Normalized Frequency (cycles/sample)');
ylabel('Gain (dB)')
if saveplots, saveplot('KaiserHilbertZoomedFR.eps'); end;
if dopause, disp 'Pausing... RETURN to continue'; pause; end;
