# python how to demodulate iq fm signal that was moved to 0 frequency

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:

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 ?

• "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. Feb 18, 2023 at 19:36
• 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 ...". Feb 18, 2023 at 19:42
• @TimWescott I have found this algorithm here dsp.stackexchange.com/a/18616/66279 Feb 18, 2023 at 20:11
• @TimWescott vfo_channel is just IQ signal shifted to 0 center frequency, it was shifted by SDR receiver Feb 18, 2023 at 20:15
• 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. Feb 18, 2023 at 20:19

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.