I am struggling with implementing FM demodulation for IQ samples that has 0 center frequency from RTL-SDR ... I have found the following algorithm for FM demodulation, see FM demodulation:

analytic_signal = scipy.signal.hilbert(vfo_channel_fm.real)
baseband = analytic_signal
demod_channel = np.angle(baseband[1::1] * np.conjugate(baseband[0:-1:1]))
demod_channel = (demod_channel * (sampling_freq/decimation_factor)) / (2 * np.pi)

where vfo_channel is just IQ signal shifted by SDR receiver to 0 frequency

This algorithms works, but it has some issue with base sinusoidal signal (I see my voice decoded on sinusoidal signal), see image bellow: Sinusoidal signal with demodulated voice

As you can see, my voice has a base sinusoidal signal and also some big signal changed in the middle of the signal

Is there anything that I missed implementing FM demodulation ? Maybe there are a better algorithm ?

  • $\begingroup$ "I have found" -- where have you found? You should cite any references, in this case by editing your question with a link to the page you found, or a reference to the source material if it's in a printed book. $\endgroup$
    – TimWescott
    Feb 18, 2023 at 19:36
  • $\begingroup$ While you are editing your question, explain what the signals are. In particular, vfo_channel implies the output of a local oscillator; this would not contain any information unless you have done something with it -- in which case, you should say what that is. I.e., "vfo_channel is a test signal that I made that contains ...". $\endgroup$
    – TimWescott
    Feb 18, 2023 at 19:42
  • $\begingroup$ @TimWescott I have found this algorithm here dsp.stackexchange.com/a/18616/66279 $\endgroup$ Feb 18, 2023 at 20:11
  • $\begingroup$ @TimWescott vfo_channel is just IQ signal shifted to 0 center frequency, it was shifted by SDR receiver $\endgroup$ Feb 18, 2023 at 20:15
  • $\begingroup$ This is Stackexchange, where we like the entire question and entire answers to be in the question and answers. Not buried in the comments. Could you please edit your question with this information. $\endgroup$
    – TimWescott
    Feb 18, 2023 at 20:19

1 Answer 1


Your error lies in misinterpreting the source material.

This line is not something to stick in randomly. It is given in your reference as a way to get an I/Q signal from a real-valued FM signal that is not centered on 0Hz.

analytic_signal = scipy.signal.hilbert(vfo_channel_fm.real)

You state that your signal vfo_channel_fm is already an I/Q signal. In the following line of code, when you just the real part of it you're mangling the signal -- you're basically throwing away half of the information. Presumably the reason that your output has that enormous glitch right at the center sample is because scipy.signal.hilbert is transforming the whole signal.

If you've done what you've said, your vfo_channel_fm is already a baseband signal. All you need to do is assign that value to baseband in your code and proceed.

  • $\begingroup$ Hmm interesting, looks like i understooyyour point ... I will try tomorrow, it is to late in my time zone. Thanks for quick feedback ;) $\endgroup$ Feb 18, 2023 at 20:30

Your Answer

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

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