# Envelop detection using matlab hilbert function

I am trying to detect the envelope of a high-frequency signal (similar to below) using Matlab Hilbert function

This is my output

It generally follows the envelope, but there is a high-frequency ripple in the envelope, see zoomed version below

Here is my code:

t =out.tout';
x =out.Itxmod';
y = hilbert(x);
env = abs(y);
figure;
plot_param = {'Color', [0.6 0.1 0.2],'Linewidth',2};
plot(t,x)
hold on
plot(t,[-1;1]*env,plot_param{:})
hold off
xlim([0.001 0.002])
title('Hilbert Envelope')


Question: How can I get a smooth envelope the signal without this high-frequency ripple?

This must be an artifact of the implementation for the hilbert function, in that any implementation of finite length will have a finite ripple. It doesn't appear the underlying filter using in the hilbert function can be modified, so there are three suggestions to obtain a smoothed demodulated result:

Method 1: Implement the Hilbert using the FFT: take the FFT of the original signal, set all the negative frequencies to zero (the upper half of the FFT) and double the positive frequencies leaving bin 0 (DC) as is (and as Overlord pointed out in the comments, leave the Nyquist bin at $$N/2$$ as is when the FFT length $$N$$ is even). The IFFT will be the Hilbert Transform and taking the absolute value of this signal will be the desired envelope. (As @aconcernedcitizen pointed out in the comments, this IS the method specifically implemented by Octave using the hilbert function from the signal package.)

Method 2: Implement the Hilbert with quadrature phase tracking filters where the filter length versus ripple can be traded.

Method 3: Use a traditional AM demodulator by multiplying the modulated signal with the coherent carrier and then low pass filtering the result.

A demonstration of Method 1 is shown below, which is a suitable solution for the OP's case:

Zooming in on the start of the signal shows the distortion limited to the start-up condition and the smooth envelope after that.

The Matlab code for this is as follows:

N = length(sig);
sig_spectrum = fft(sig);
hilbert_spectrum = zeros(1, N);
hilbert_spectrum(1) = sig_spectrum(1);
hilbert_spectrum(2: ceil(N/2) - 1) = 2 * sig_spectrum(2:ceil(N/2) - 1);
if mod(N, 2) == 0
hilbert_spectrum(N/2) = sig_spectrum(N/2);
endif
hilbert_time = ifft(hilbert_spectrum);
envelope = abs(hilbert_time);

• Caveat, Nyquist bin shouldn't be doubled (even N). – OverLordGoldDragon Apr 23 at 20:44
• Good point! The bin at N/2 should not be doubled when N is even. – Dan Boschen Apr 24 at 0:24
• I thought method 1 is the one that it's done by default with hilbert()? I know Octave uses it like that. – a concerned citizen Apr 24 at 8:07
• @aconcernedcitizen you're right, I just looked at the code in Octave and it is exactly method 1 – Dan Boschen Apr 24 at 11:01