I am trying to demodulate an AM signal in GNU Radio, and I am having problems with the sampling rates. I will start off with an example where the flow graph was working. The sampling rate is 256kHz, and it works just fine: Figure 1 - sampling rate 256K (works)

Next, I tried a sampling rate of 192kHz, and then it didn't work. Is there a problem with this flow graph?

Figure 2 - sampling rate 192kHz (not working)

Next, I modified the 2nd flow graph (changed the sampling rate, but didn't need to), and it worked almost perfectly, other than that the voice sounded very slightly too low pitch/slow. This sampling rate suffered from the same problem as that of figure 2, however I tweaked the rational resampler block until the voices sounded normal. Figure 3 - sampling rate 320K (mostly works)

As some background, I am running an RTL SDR (DVB-T) dongle, on an Odroid U3 (ARM architecture). I have a "Ham it up" upconverter, so that the AM (810Kkz) is shifted up by 125MHz, into the VHF band that the dongle can actually receive.

UPDATE: There were two issues with the flow graph:

  1. The filter cutoff frequency needed to be calculated using normalized frequency (see MBaz's detailed answer).

  2. The R820T chip does indeed, as MBaz ascertained in the comment section, have only a limited set of sampling rates that it supports.

In order for the flow graph to output natural sounding audio, it must use one of the acceptable sampling rates, and also have the proper filter setting. The 2nd and 3rd flow graphs didn't work because they had the wrong sample rates.


1 Answer 1


In order to make the filter calculations easer, you should specify its sampling rate equal to the source's. Assume that:

  • $D$ is the filter's decimation factor
  • $f_s$ is the source sampling rate
  • $f_c$ is the filter's specified cutoff frequency
  • $f_f$ is the filter's specified sampling rate

The actual cutoff frequency from the point of view of the filter's output, $f_a$, is calculated as: $$f_a=\frac{2Df_c}{f_f}\frac{f_s}{2D}=\frac{f_cf_s}{f_f}.$$ This is because the filter doesn't care what the actual sampling rate is; what it needs to know is the cutoff frequency as a fraction of the normalized Nyquist frequency, which is $2Df_c/f_f$ after accounting for the decimation.

In your first flowgraph, the actual cutoff frequency is $5\cdot256/64=20$ kHz, not 5 kHz (the same problem occurs in the second flowgraph; in the third, the cutoff is 25 kHz). If you specify the filter sampling rate equal to the source rate ($f_s/f_f=1$), then your signal will actually be filtered at 5 kHz.

You also need to make sure that the product of the source sampling rate, times all your interpolation, divided by all your decimation, is equal to the sink sampling rate. In the third flowgraph, the sampling rate into the sink is 16 kHz, not 48 kHz.

Having said that, I think there's another problem in your flowgraph. I assume that you're demodulating AM DSB-LC. If the RTL-SDR device is centered exactly at the carrier frequency, then you only need the low-pass filter; no complex to mag conversion is necessary. You only need to keep the real part of the signal (send the imaginary part to a null sink -- you can do this right after the RTL-SDR and save some computations).

You only need to do envelope detection when the AM signal is not in baseband. In that case, you calculate its absolute value and then low-pass filter it. You also need a final high-pass filter to eliminate the DC bias present at the LPF output.

  • 1
    $\begingroup$ This is correct; the sample rate used for calculating a filter is always the highest rate involved: input rate for decimation, output rate for interpolation, or input · interpolation = output · decimation for rational resampler. $\endgroup$
    – Kevin Reid
    Commented Jun 10, 2015 at 3:25
  • $\begingroup$ Thanks for the help! The GNU Radio LPF block does downsampling before filtering, so the 192K sample rate coming from the RTL source gets reduced to 48KHz, filtered, and output to the next block. (I verified this by putting a resampler in front of the LPF, with the LPF decimation set to 1.) Also, the first flow diagram (with LPF sampling=64KHz and downsampling=4 and RTL sample rate=256KHz) actually did work. It seems like this flow graph only works the way I expect it to for the first case, with 256KHz sampling rate on the RTL. $\endgroup$
    – Luke Snow
    Commented Jun 11, 2015 at 0:02
  • $\begingroup$ @LukeSnow, I have expanded my answer quite a bit. Let me know if that helps. $\endgroup$
    – MBaz
    Commented Jun 11, 2015 at 2:19
  • $\begingroup$ @MBaz, thanks for the additional explanation. Yes, I am trying to decode AM DSB (just AM radio). I will definitely try your new approach. However, by your reasoning the second flow graph should still work, right? It may have a too-wide band LPF, but the sample rates should match up. For the second flow graph, sample rate * interp / decim = 192K * 1 / 4 = 48KHz, which is also the sink rate. I get "O's" (for overflow), and the voices sound slow and deep, (so slow, it is hard to tell if there is any voice at all). This seems to me like a bug in GNU Radio, but I am not sure. $\endgroup$
    – Luke Snow
    Commented Jun 13, 2015 at 6:01
  • $\begingroup$ @LukeSnow Yes, the numbers for the second flograph look right, except the filter is too wide. If you're getting "O"s, then your problem is that your computer is not fast enough to execute the flowgraph. I would try: 1. Send the imaginary signal to a null sink right out of the RTL. 2. Give a gain of 10 to the filter instead of having a separate multiplier. 3. Deleted the rational resampler, which is not doing anything useful. $\endgroup$
    – MBaz
    Commented Jun 13, 2015 at 14:39

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.