I'm implementing a discrete Hilbert transformer and I know that an ideal Hilbert transformer is anti-causal and has infinite length so we can only make approximation. There are some FIR and IIR implementations, while MATLAB's
hilbert() uses FFT to modify the spectrum of input.
What I've done is to keep the DC and Nyquist components, double the components between them and make the negative frequencies zero. But I got wrong results when processing signal block by block. A MATLAB example using windowing and overlap add is given below.
fs = 48e3; Ts = 1/fs; t = 0:Ts:1; w = 2*pi*10; sig = sin(w*t).'; N = length(sig); y0 = hilbert(sig); % true result using full-length FFT y1 = zeros(N, 1); % block-wise processing blockSize = 1024; hopSize = blockSize / 2; startIdx = 1; endIdx = blockSize; win = hann(blockSize, 'periodic'); while endIdx < N x = sig(startIdx:endIdx) .* win; % windowing xa = hilbert(x); y1(startIdx:endIdx) = xa + y1(startIdx:endIdx); % overlap add startIdx = startIdx + hopSize; % 50% overlap endIdx = endIdx + hopSize; end figure; subplot(211) plot(t, real(y0), t, imag(y0)); legend('original', 'hilbert') subplot(212) plot(t, real(y1), t, imag(y1)); legend('original', 'hilbert block-wise')
FIR and IIR filters have filter states saved in the memory which deal with this case, but I don't know how to solve it.