I'm looking to understand how signal modulation/demodulation works.

My goal is to be able to demodulate a 315 MHz key fob and be able to tell what buttons are being pressed so I can have a Python script perform actions based on the button presses.

From my understanding, the fob first generates the signal (according to some kind of rolling code), encrypts it, modulates it as Pulse Width Modulation, then modulates it as Amplitude Modulation before transmitting the signal. The FCC ID for the fob is CWT-WB1U331 (the dash is to make it easier to search on the FCC website as I have mistakenly included the WB in the manufacturer code).

Using GQRX I have recorded several signals with AM demodulated and then manually demodulated the PWM output into a csv as binary.

The part that is important to the question itself is learning how to write demodulators so I can demodulate in Python. I'm looking to take a complex signal from a RTL-SDR, convert the signal to a wav file with the PWM modulation for debugging purposes and then decode the PWM modulation into a spreadsheet.

The part I'm currently stuck on is figuring out how to write an AM demodulator. I'd say my main struggle is my not understanding math which is more complicated than algebra.

In my Python script, I have successfully tested demodulating FM radio and saving the demodulated output to a wav file by inserting in an existing FM demodulator I stole from https://stackoverflow.com/a/60208259/6828099.

From what I can tell, there are multiple different ways to demodulate AM, such as https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-661-receivers-antennas-and-signals-spring-2003/lecture-notes/lecture17.pdf and hilbert transforms. I also believe FFTs may be relevant to some methods of AM demodulation, such as the hilbert transform, but I may be wrong.

To help show what it is I'm working with, I've created a Github Repo with my signal saving script, the manual decoding of my recording, and the recording in the form of an Audacity project with a label track at https://github.com/ArchivedProjects/dsp-stack-exchange. The recording was made with GQRX, so it's already been demodulated to PWM from AM and is probably irrelevant to this question. I also just added a fully modulated file called no-demod.wav where I press the lock button once just in-case one does not have a SDR and wants to experiment on some data. The 4 different sections in the one signal are the same message being transmitted 4 times.

I'm not expecting the Python function to just be handed to me, as if it was, I'd not learn anything about digital signal processing. I will say, I am very new to DSP, so a lot of concepts are new to me, and I do apologize for not knowing more about how signal processing works before asking this question. I guess the last thing I should mention is, I am far better at understanding conceptually than I am mathematically, so if there is a way to help me understand this conceptually and then bridge the concept to math, I'd greatly appreciate it. Sadly, I don't have a lot of money, so I can't just buy books or enroll in a college course on signal processing.

TLDR: I want to learn how to demodulate signals such as AM and PWM to be able to read binary data transmitted near the 315 MHz frequency.

Edit: Here's some screenshots of plots of the signal. The first screenshot is what the waveform looks like when recorded without demodulation by GQRX and so looks a lot better than my own recording. The second one is how I recorded it. The third one is what the demodulated output looks like.

First Part Of Lock Button (Recorded With GQRX With The Raw I/Q Mode) - 48 KHz Audio Rate, 1 MHz Sample Rate

First Part Of Lock Button (Recorded With GQRX With The Raw I/Q Mode)

First Part Of Lock Button (Recorded With Python Script With No Demodulation) - The Left Track Are The Real Numbers and The Right Track Are The Imaginary Numbers Of The Complex Signal - 48 KHz Audio Rate, 1 MHz Sample Rate

First Part Of Lock Button (Recorded With Python Script With No Demodulation)

First Part Of Lock Button (Recorded With GQRX With AM Mode) - 48 KHz Audio Rate, 1 MHZ Sample Rate

First Part Of Lock Button (Recorded With GQRX With AM Mode)

  • 1
    $\begingroup$ Demodulating AM is rather straightforward. If you could provide a plot of a segment of your waveform such that the AM features are clear, and details on what the sample rate is you are using, that would be helpful toward a useful answer for you. $\endgroup$ Commented Mar 21, 2022 at 4:33
  • 2
    $\begingroup$ The following web page presents several ways to demodulate an AM signal: dsprelated.com/showarticle/938.php $\endgroup$ Commented Mar 21, 2022 at 11:04
  • 1
    $\begingroup$ GNU Radio is a toolkit to build demodulators, and the main scripting language to use it is Python. In fact, GNU Radio has tutorials that teach you how to design your own demodulators – tutorials.gnuradio.org . What they don't really try to do is to give you the DSP basics, which might, python-orientedly, be more of the domain of pysdr.org $\endgroup$ Commented Mar 21, 2022 at 18:50
  • $\begingroup$ I've just had the realization that my main problem is that I don't understand the relationship between complex numbers and waves. I'll have to learn what the real and imaginary parts of the numbers represent in these samples and see if that'll help me understand the equations for demodulating signals. I believe my signal is Amplitude Key Shifting. I'll have to look at pages.mtu.edu/~scarn/teaching/GE4250/ComplexWave_lecture.pdf more closely when I finish relaxing from my wild day at work today. :P $\endgroup$ Commented Mar 23, 2022 at 23:40
  • 1
    $\begingroup$ "... the relationship between complex numbers and waves..." I know that's been discussed here before, and I can't find any reference. Try searching on "quadrature demodulation". Basically, if you demodulate a radio signal using quadrature demodulation you end up with a pair of signals (known as inphase and quadrature) which have an algebra that acts exactly like the complex numbers (It is "morphologically equivalent" in math-speak). Just pretending that your I/Q signal pair is a complex-valued signal makes the arithmetic much easier, at the expense of having complex numbers. $\endgroup$
    – TimWescott
    Commented Nov 12, 2022 at 22:17

2 Answers 2


For AM signals you can use an envelope detector, you can find an example here:



A simple approach to implement in Python or MATLAB, assuming AM with a modulation index of 100% or less (see this post for modulation index descriptions), is to extract the envelope using the Hilbert Transform:

Given bandpass signal as wfm, use the hilbert function to create the analytic signal, and the envelope is simply the magnitude of the analytic signal.

import numpy as np
import scipy.signal as wfm
wfm_analytic = sig.hilbert(wfm)
demod = np.abs(wfm_analytic)

The relationship of the Analytic Signal to the Hilbert Transform and its use for envelope detection (AM demodulation) is further detailed here.

  • $\begingroup$ You need to do square root if you're using this method. $\endgroup$ Commented Jul 10, 2023 at 4:27
  • 1
    $\begingroup$ How do you get $A(t)$ from $A(t) e^{j \omega_0 t} = A(t) \cos(\omega_0 t) + j A(t) \sin(\omega_0 t)$ without the use of $\sqrt{\ \cdot \ }$? $\endgroup$ Commented Jul 10, 2023 at 22:39
  • 1
    $\begingroup$ My goodness how cooincidental our timing is. $\endgroup$ Commented Jul 11, 2023 at 2:21
  • 1
    $\begingroup$ @robertbristow-johnson I am with you now— I thought you meant a square root in addition to what I did. OP was asking about a Python implementation so what I showed serves the order as is I believe (but yes if we were to implement this in real-time hardware or firmware we would need to do either a square-root, or as often is the case when resources are limited: complex magnitude estimator algorithms. $\endgroup$ Commented Jul 11, 2023 at 2:21
  • 1
    $\begingroup$ (Yes the late night East coast people!) $\endgroup$ Commented Jul 11, 2023 at 2:22

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.