I am testing some Hilbert transform theory in practice. On the practical side I use Python and a soundcard to generate baseband I and Q signals. And an IQ modulator to upconvert with 250kHz. Lastly a spectrum analyzer to inspect the result.

I was under the impression that if you take a real signal, calculate its Hilbert transform, multiply that transform by j and add that to the original signal that you can transmit that as SSB by simply upconverting it.

So I wrote this script:

import numpy as np
from scipy import signal
import sounddevice as sd

def tx(I,Q, d=duration):
    # 'play' I and Q on soundcard (stereo)
    assert len(I)==len(Q), f"inequal IQ lengths"
    assert len(I)>=fs*duration, f"IQ columnlength ({len(I)/fs}s) too short for duration ({duration}s)"
    samples = int(d*fs); I=I[:samples]; Q=Q[:samples]
    v = .1  # volume
    IQ = np.column_stack((v*I, v*Q))
    sd.play(IQ, fs)

fs = 32768
duration = 4

# create 5 tones
t = np.arange(int(fs*duration)) / fs
tones = [440,880,1200,1500,2000]
s = 0; 
for i, f in enumerate(tones):
    s += np.cos(2*np.pi*f*t)
s = s/np.max(s)   # reduce power to avoid clipping

# play original signal 
I = np.real(s); Q = np.imag(s); tx(I,Q, duration)

# play s + j times the hilbert transform of s
h = signal.hilbert(s)
y = s + 1j*h
I = np.real(y); Q = np.imag(y); tx(I,Q, duration)

# play just the hilbert transform of s
I = np.real(h); Q = np.imag(h); tx(I,Q, duration)

Transmission as said is via the audio left and right channel to the I and Q input of the 250kHz upconverter.

The three results of the code are:

s #original signal: original signal (Q=0)

s + 1j*signal.hilbert(s): s plus j times Hilbert transform

signal.hilbert(s): Hilbert transform only

Clearly things are not as I expected for the last two scenarios. What am I doing wrong?

  • 1
    $\begingroup$ I'm not reading your Python code. I just wanna check that you have time-aligned the in-phase component (the original baseband) to the quadrature (Hilbert transformed) component? If there is processing delay in the Hilbert transformer, you need to apply exactly the same delay to the input to the Hilbert transformer. $\endgroup$ Jun 29 at 20:01
  • $\begingroup$ No I have not. I assumed that is not needed. Will check documentation on the transform. I generatie all signals prior to transmitting them, so no risk of delays there $\endgroup$ Jun 29 at 20:05
  • $\begingroup$ A real-time Hilbert transformer cannot have zero delay. It must be a delayed Hilbert Transform. $\endgroup$ Jun 29 at 20:07
  • 2
    $\begingroup$ Doesn't hilbert compute the analytic signal instead of just computing the Hilbert transform? I.e., wouldn't you need to take the imaginary part of the outcome? $\endgroup$
    – Matt L.
    Jun 29 at 20:43
  • $\begingroup$ Ouch! Yes, it does. Checked the documentation. How could I think it did the Hilbert transform? $\endgroup$ Jun 29 at 20:57

1 Answer 1


As commented by Matt L, scipy.signal.hilbert does not output the Hilbert transform itself, but the analytical signal (by using a Hilbert transform).

Same goes for Matlab.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.