Using SDR#, I saved the baseband I+jQ signal centered about a commercial FM station to a *.wav file. I want to write python code to demodulate this signal. I know that SDR# can read in that file and demodulate it, but I want to do it on my own. And no, this is not for a class ...

I assume that the I and Q signals correspond to the left and right (or right and left) stereo channels, although if I'm wrong this is a secondary issue. I also know that there are likely subcarriers that carry other information, but again I think that's a secondary issue.

I thought that demodulating would be easy, but for some reason I can't get it to work. I applied these steps to the real part of the signal:

  • Ran it through a Hilbert transform
  • Calculated the phase versus time
  • Unwrapped the phase
  • Diffed (discrete derivative) on phase
  • Converted to 16 bit PCM and saved to *.wav file
  • Played the *.wav file with the playsound python package

I did this w/ and w/o low pass filtering, fc ~ 100 kHz. All I hear is hissing. At first, I used all frequencies up to ~ 1.25 MHz to reconstruct the AF signal. I also tried using only frequencies up to 100 kHz to reconstruct the AF signal, which changed the time sampling (still should be high enough).

Any help would be appreciated.

  • $\begingroup$ At a minimum, I don't think you can separate the I and Q. They are probably not left and right stereo signals. Rather, they are 2 parts of one complex signal: sig = I + jQ, where j is the imaginary number. This complex signal contains both phase and amplitude information. $\endgroup$
    – Gillespie
    Commented Aug 10, 2022 at 23:43
  • $\begingroup$ This post may help you: dsp.stackexchange.com/questions/38601/… $\endgroup$ Commented Sep 10, 2022 at 4:40

1 Answer 1


I assume that the I and Q signals correspond to the left and right (or right and left) stereo channels.


You're overthinking this. Basic FM modulation is $$y(t) = \cos(\phi(t)) \tag 1$$ where $$\phi(t) = \int A x(t) dt, \tag 2$$

and $x(t)$ is the signal you're trying to send. Real broadcast FM radio gussies this up with stereo channels and subcarriers and whatnot, but that's the basics.

When you run it through your receiver, what comes out at baseband is pretty close to $$y_{bb}(t) = e^{\phi(t)}. \tag 3$$

That's what you want to determine the phase of. If you take that, filter the I and Q channels with 50 or 100kHz wide filters, then calculate the phase point-by-point, then unwind it and high-pass filter it just enough to remove any bias or drift, you should have something intelligible. It'll sound crappy but you should be able to tell what you're listening to.

Then you can dive into the mysteries of preemphasis, and how stereo and other stuff is added to your local broadcast FM signal.


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.