FIR Digital Filter Design
Hilbert Transform Design Example
Windowing an ``Ideal'' Impulse ResponseSearch Spectral Audio Signal Processing
Would you like to be notified by email when Julius Orion Smith III publishes a new entry into his blog?
As explicated in §E.6, the convolution kernel of the continuous-time Hilbert transform is defined by
Note that we cannot allow a sample at time 0 since it would be infinity. Instead, time 0 is typically taken to lie half way between two samples. As a result, our digital Hilbert-transform filter will have a non-integer delay. In closest to ``zero-phase'' form, it will give a half-sample delay (or advance). We'll choose a half-sample delay below. As a result, we'll need to delay the real part by half a sample also.
% Analytic version: Sample the ideal kernel 1/pi*t: n = [-N/2+0.5:N/2-0.5]; % Time axis in samples; hi = T ./ (pi*n*T); % Sampled ideal Hilbert transform kernel hr = sin(pi*n) ./ (pi*n); % Delay real part 1/2 sample h = (hr + j*hi)/2; % Put together the negative-frequency filter plot(f,fftshift(max(-100,20*log10(abs(fft(h)))))); grid; s = sprintf(... 'FFT of Truncated Analytically Specified "Ideal" Impulse Response'); title(s); xlabel('Normalized Frequency (cycles/sample)'); ylabel('Gain (dB)') if saveplots, saveplot('AnalyticHilbertIdealFR.eps'); end; if dopause, disp 'Pausing... RETURN to continue'; pause; end;
h = [h(N/2+1:N),h(1:N/2)]; % Back to zero-phase form
% (actually 1/2 sample delay)
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)
= 0.0378
disp(sprintf(['Analytic-Derived Stop-band energy is %g percent',...
' of total spectral energy'], 100*ierr));
Stop-band energy is 3.776308 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 Analytic-Derived FIR Frequency Response, ', ...
'FFT size = %d'],M,N);
title(s);
xlabel('Normalized Frequency (cycles/sample)');
ylabel('Gain (dB)')
if saveplots, saveplot('AnalyticHilbertFR.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(['Analytic-Derived Low-Frequency Transition Band,',...
' f1/fs=%f (marked by "+")'],f1/fs);
title(s);
xlabel('Normalized Frequency (cycles/sample)');
ylabel('Gain (dB)')
if saveplots, saveplot('AnalyticHilbertZoomedFR.eps'); end;
if dopause, disp 'Pausing... RETURN to continue'; pause; end;
We see that the main problem with the analytically specified impulse response is a poorly positioned transition region from positive to negative frequencies. We can repair this by bandpass-filtering the ideal impulse response. We did bandlimit the real-part of the ideal impulse response to [-fs/2,fs/2], and we even gave it a half-sample delay as necessary to avoid a singularity in the imaginary part. However, the results here show that we also need transition bands in both the real and imaginary parts to provide for the transition region which is inherent in any FIR filter of the specified (window) length.
