Random Quote Board

Demodulating NOAA APT Signals

Gary Schafer, Blursday, Pandemic Quarantine Time, Still Probably December 2020

I'm writing this article because I think it's fun. The US' National Oceanic and Atmospheric Administration (NOAA) operates a fleet of satellites to look at earth's weather. Several of those transmit relatively low frequency (137 - 138 MHz) signals that contain low resolution visible and infrared imagery (roughly 4 km) of earth. These are the Automatic Picture Transmission (APT) signals. These signals are all-analog, as well. This makes them a perfect target if you want to try out using Gnu Radio Companion (GRC) on something a little different.

If You're Just Looking for An Image

There are two straightforward methods if you just want an image.

  1. The Wxtoimg program can give you beautiful images pretty-much automagically. It will (if I understand it correctly) already control your RTL-SDR and audio card to process the data and give you beautiful, synchronized images.
  2. You can frequency demodulate the NOAA APT signal, create a WAV file, then use Martin Bernardi's "NOAA APT Decoder" program to give you beautiful images.


NASA launched the first weather satellite, TIROS (Television Infrared Observation Satellite) into space on April 1st, 1960. It was the greatest April Fool's non-joke ever. Since then, new satellites have been launched to both augment or replace those that reached end-of-life. TIROS-8, launched on 23 December 1963, added a continuous, analog video signal called "Automatic Picture Transmission" or "APT". Currently, NOAA operates a set of polar orbiting satellites that transmit both high resolution and low resolution (APT) weather imagery. There are currently (as of December 2020) three operational satellites that provide APT transmissions. These are NOAA-15, NOAA-18, and NOAA-19. These signals are meant to provide access to weather data for those with minimal access to equipment and budgets. Their set-up means that, aside from the computer required (which is now lessened to a Raspberry Pi, if you're so inclined), you can receive such signals for less than $50 in parts (SDR and antenna).

The APT Signal

The Automatic Picture Transmission (APT) signal is an analog signal used to transmit low resolution imagery. Here's the shortened version. The imagery is bandwidth limited to 2080 Hz and amplitude modulated (AM) onto a 2400 Hz carrier with bandwidth of 4160 Hz. That signal is then modulated onto a 137+ MHz signal using frequency modulation (FM) with a 17 kHz deviation.

If you're interested in reading more of the technical details of the APT signal, your two, primary documents are:

Also, SIGIDWiki does a pretty good job of covering the specifics, including going into details of the telemetry information.

Quick Setup

Here's my setup for the signals and images in this post.

This is the setup I used to collect the signals and images for this post. It consists of a half-wave dipole (aka "rabbit ears" antenna laid flat), a Nooelec RTL-SDR and an oooooooold Sony Vaio laptop running Linux Mint 19.2 and GRC version 3.7. TV tray is optional. I'm setup at the end of my driveway in a suburban area.

The rest of this post will go into details of the NOAA APT signals themselves, the antenna and the GRC flowgraph.

Finding the Satellite

Before you can demodulate an APT signal, you have to receive such a signal. There are three satellites constantly transmitting. The problem is those satellites are constantly moving. How to find out when they'll be one near you? Here are my recommended steps:

  1. Determine your latitude and longitude. You need to know where you are, specifically your latitude and longitude. The easy way is to use Google Earth. Just zoom in on wherever you want to collect from, place your cursor over the point of interest, then write down your latitude and longitude in "decimal" format. This means that you don't want "degrees / minutes / seconds", you want "degrees and decimal fraction of degrees". If you go into "Settings" of Google Earth, it will let you set the latitude / longitude readout to "Decimal". You could also use an app on your smartphone. I use GPS Status & Toolbox.
  2. Determine your time zone difference between you and Greenwich. For example, I'm on the East Coast of the US. I'm currently five hours behind (UTC-5) London (Greenwich) time.
  3. Go to the Amateur Satellite Online Satellite Pass Predictions page. Enter the satellite you want to see (NOAA-15, NOAA-18, NOAA-19), your latitude and longitude from Step #1 above, and press the "Predict" button. You'll be provided a table showing a bunch of data. Here's what that data means:
    • Date: The date, in UTC (universal coordinated time, aka "Zulu" or "Greenwich" time).
    • AOS: "Arrival of Signal", meaning the earliest you're likely to see the signal.
    • Duration: The amount of time that you're likely to see the signal as the satellite passes over.
    • AOS Azimuth: The azimuth of the satellite at the time that it first appears on the horizon.
    • Maximum Elevation: The elevation at the point when the satellite is highest in the sky.
    • Max El Azimuth: The azimuth of the satellite at the time that it is at its highest point in the sky.
    • LOS Azimuth: The azimuth of the satellite at the time that it drops back below the horizon.
    • LOS UTC: The time at which the satellite will drop below the horizon.
  4. Note the "Maximum Elevation". If you're in the suburbs, I recommend that you look for a time when this value is 30 degrees or greater.
  5. Note the "AOS UTC" of whichever pass you want to collect. That's the time when the signal will start to appear. Now, change that time UTC time to your local time. For example, if the UTC time is 1434, and I'm five hours behind, then the AOS local time will be 0934 (2:34 pm minus five hours). This means that some times might move the date back a day. For example, if I collect a signal that is 0134 UTC, this equates to 2034 local time of the date before.
  6. Note the "AOS Azimuth" and the "LOS Azimuth". If the AOS is roughly north and the LOS roughly south, then the satellite is moving from north to south. If the AOS is roughly south and the LOS is roughly north, then the satellite is moving south to north. If the satellite is passing from south-to-north, you'll need to rotate the final image by 180 degrees.. (Hat tip to Martin Bernardi and his noaa-apt decoder program page for the information on when to rotate. It will need to be modified and rotated to account for this.

Each satellite operates on a different frequency. Here's the quick translation between the satellite and its transmit frequency. Note the frequency of the satellite from which you're going to collect.

SatelliteFrequency (MHz)

The Antenna

NOAA APT receive antenna used to capture the first APT transmissions from TIROS-8 in 1963. No, you do not need an antenna like this to receive APT transmissions. (Image credit: NOAA)
Basic, "rabbit ears" dipole antenna. I used this antenna to collect every signal and image in this post. This is a pair of telescoping, whip antennas. This is now a half-wave dipole. I set it to be half-wave for a 137.5 MHz (middle of the satellite signal band). That equates to a length of roughly 1.1 m, or 42 inches. Each whip is 21 in long.

Yes, you need an antenna. Here's the thing.

What do you need? Whichever antenna works for you. Quick digression. At this point, I tell people how a friend of mine told me the "perfect wine" story. To wit, what is the perfect wine for you? Whichever one you like. The analogy works for antennas. Whichever one works for your setup is maybe not your perfect antenna, but your good enough antenna. Yes, if you're going to be serious about collecting such signals, you can make a "quadrifilar helix antenna" (QFH). But if you just want to see some signals for yourself, then pretty much any antenna that works in the 137 MHz range should suffice. And how will you know it works? When you see and/or hear the signal from the GRC demodulated output. I'm using a basic "rabbit ears" set of whip antennas. Most likely, even a simple whip antenna would suffice. You might ask, "Would I get a better signal if I used a better antenna?" Yes. That's how RF works. "Better antenna" in this context would be "better gain towards the satellite" (kinda hard to do when the satellite is moving so quickly) and/or one that is circularly polarized. The bigger problem is not the antenna; it's the path loss due to trying to pick up the satellite when it's low on the horizon. In that case, the signal is having to work through and around houses and trees and cars and other objects. Being in the middle of an open field would be better. That gives you an unobstructed view towards the horizon. Another option? Put your antenna higher in the air. That has its issues, too. Mainly safety. Don't put an antenna high in the air when a thunderstorm is nearby. That. Would. Be. BAD!


I used three different brand of RTL-SDRs while making this post. These were a Nooelec SDR Smart, a RTL-SDR Blog v3, and a Face2Face RTL-SDR. I obtained almost identical performance from the Nooelec and RTL-SDR Blog SDRs. The Face2face has an oscillator that is looser than the ones in the other two SDRs, but otherwise identical in performance.

GRC Flowgraph

GRC flowgraph for NOAA APT demodulator. The frequency on the RTL-SDR is set 200 kHz below the actual frequency. This helps to deal with the LO leakage. The "Frequency Shifter" section shifts the NOAA APT to the center frequency. The "Shifter" output is filtered and decimated by a factor of 10 (the 1 MHz sample rate is dropped to 100 kHz) for the two spectral displays. The signal is filtered again to just the FM signal and frequency demodulated. The output goes to a WAV file sink and to the AM demodulator section. The WAV file can be used in conjunction with "Wxtoimg" or the "NOAA APT Decoder" programs. The AM demodulator section uses asynchronous amplitude demodulation to recover the video signal. The "Time Raster Sink" block is used to reconstruct the original image. The only block that is not shown here is a "File Sink" after the first lowpass filter. That allows me to reprocess the signal later.

I go through the settings for the various blocks below. You can also download the GRC file itself (works on both GRC version 3.7 or 3.8), if you're so inclined.

The SDR and Frequency Shifter

You can just take the output of the SDR and input it directly into the lowpass filter. The problem is "LO leakage". You know you have LO leakage when you look at the spectrum of your SDR output and you see a spike at the center. To help get around this, I add a "frequency shifter" at the output of the SDR. The SDR itself is set with a center frequency that is 200 kHz below the NOAA APT signal. This means that the NOAA APT signal will be 200 kHz above the center frequency. The "frequency shifter", consisting of a "Signal Source" block and "Multiply" block, shifts the spectrum down by 200 kHz. In other words, the SDR shifts the spectrum to the right, while the "frequency shifter" section shifts it to the left.

Spectrum of a RTL-SDR (specifically, from "RTL-SDR.com V3") showing LO leakage.

Yeah, if you're confused, don't feel bad. It takes a while to wrap your head around these ideas.

The two, key parameters here are the "Ch0: Frequency" (which is the center frequency setting of the SDR) and the "Ch0: RF Gain" setting. The frequency has a "-200e3". This is the 200 kHz frequency shift, again to deal with LO leakage. The "RF Gain" is set using a "Range" block and slider so that you can adjust the gain as needed. I've found that 32 - 35 dB of gain is needed to get a good image. NOTE: This is without using a special NOAA APT filter and amplifier. If you use one of those, you will definitely need to turn down the gain, possibly to just 0.
"Frequency Shift" signal source block parameters. This shifts the center frequency down by 200 kHz to match the fact that the center frequency was set 200 kHz low in the "RTL-SDR Source" block in order to get around the LO leakage.

Spectral Displays

I'm used to having a spectral display for any signal I'm analyzing. The waterfall is actually better for determining when the signal is coming into view. The 2D display gives me an idea of how strong the signal is. I also prefer to see a bit of the spectrum around the signal I'm analyzing to determine if there are other signals that might be interfering. For that reason, I'm using a 100 kHz bandwidth for my spectral views.

This is a waterfall display of a NOAA APT signal over the entire time of its passage. Note the frequency shift due to the Doppler effect. This shift is roughly 5.2 kHz for this particular signal.

Below is the spectrum of a NOAA APT signal I captured using the GRC "QT GUI Frequency Sink". This spectrum has a 100 kHz span and roughly 200 Hz resolution bandwidth (RBW).

Frequency Demodulator

The RF carrier is frequency modulated (FM) with a 17 kHz deviation. If you know anything about me and this website, it's that I've covered just about any frequency demodulator you can make with GRC. I could even argue that I've covered pretty much any frequency demodulator you can make digitally. These were covered in Post #1, Post #2 and Post #3.

For this graph, we're just going to use the straightforward polar discriminator with the "Quadrature Demod" block. As always, we start by filtering the signal so that we're only demodulating the signal, and getting rid of as much noise and interference as possible. Remember: the signal is centered at 0 Hz. That's because we're using complex samples. A lowpass filter, in this case, will be a bandpass filter on our signal. We set the filter to include the deviation (17 kHz) plus some wiggle room for the Doppler shift, which can be upwards of 3+ kHz. This gives a deviation of +/-20 kHz.

If you want to use Martin Bernardi's "NOAA APT Decoder" program, you would create a WAV file of the frequency demodulated signal, then import that WAV file into the decoder program.

Settings for the frequency demodulator lowpass filter. This filters the signal to +/-20 kHz. It also decimates the output sample rate by a factor of 10. The output sample rate is 100 kHz.
The gain for the "Quadrature Demod" block starts with a basic value of "sample rate / (2*π)". By also dividing by the deviation (20 kHz, to account for 17 kHz deviation plus 3 kHz of Doppler shift), the output should be amplitude limited between +/- 1.
Time-domain graph of the frequency demodulated NOAA APT signal. This shows the 2400 Hz subcarrier. It's double-sideband AM. I made this image using "Audacity" and a WAV file of the NOAA APT signal.
Spectrogram of the frequency demodulated output of the NOAA APT signal. This image is annotated to show the two sync bursts and the 2400 Hz subcarrier. I made this image using "Audacity" and a WAV file of the NOAA APT signal.

At this point, if you were to listen to the output when the signal is strong, you'd hear the following sound:

FM demodulated audio from NOAA APT signal. The high-pitched whine is the 2400 Hz subcarrier. The "tick-tock" is the repetition of the 1040 Hz and 832 Hz sync bursts that each occur once every second.

AM Subcarrier Demodulator

The APT signal is the video signal modulated onto a 2400 Hz subcarrier using double-sideband (DSB), full carrier (FC) amplitude modulation. To demodulate this signal, I'm using a modified "Asynchronous Complex Square-Law Envelope" detector. Unlike Dr. Lyons' suggestion, I'm not using a lowpass filter on the output. I've found that there's no discernible difference with and without the filter.

The first part of the "AM Demodulator" section converts the 2400 Hz real signal into a complex signal, then shifts it down to 0 Hz. The lowpass filter, again because it's operating on complex samples, bandpass filters the signal to a width of 4160 Hz (+/-2080 Hz). The "Complex to Mag" calculates the magnitude of each sample, which effectively amplitude demodulates the signal.

The AM demodulator signal source uses a complex sinusoid of -2400 Hz frequency. This will shift the signal at +2400 Hz down to 0 Hz. This could be 2400 Hz sinusoid and the result would be identical. Since the subcarrier is DSB-AM, the signal source frequency could also be +2400 Hz.
The lowpass filter both filters the signal before being demodulated, and decimates the output to a frequency of 10 kHz.
This is the time-domain graph of the signal after demodulating the 2400 Hz AM subcarrier. This shows several lines of the image. Image made using "Audacity".
Spectrogram of the baseband video signal after being demodulated from the 2400 Hz subcarrier.
Audio from the demodulated subcarrier. You still hear the "tick-tock" sounds of the 1040 and 832 Hz sync bursts, but without the high-pitched tone from the subcarrier itself. It also sounds muffled compared to the audio output direct from the frequency demodulator due to the fact that it has been filtered to just over 2 kHz.

The Image Display

The whole point of the NOAA APT signal is to get an image. The various programs that you can use to get a pretty image will demodulate the subcarrier, synchronize each line of video, adjust the amplitudes so that the image goes from white to black using as large of a span as possible (to improve the image quality), and raster the image. We're just going to raster the signal. We're not going to use the signal itself for sync; we're just going to use the timing of the samples, which is based on the timing accuracy of the digitizer of your SDR. According to the NOAA information on the APT signal, each line is 0.5 seconds long. The output of the subcarrier demodulator is 10 kHz. If we set the number of columns to 5000, we'll roughly have the timing for an image. No, it will not be perfectly synchronized. As a matter of fact, if your SDR does not have a good oscillator, you may see a fair amount of drift from one line to the next. But you'll get a decent image.

As for the appropriate contrast, I eyeballed the white and black levels in the time-domain display, then set those as the maximum and minimum levels, respectively, in the time raster sink. That gave me a pretty decent image that even running through Gimp could not improve.

The time raster sink block will provide the image. The number of columns ("Num. Cols") is 5000. With the sample rate of 10 kHz, this means each line will be 1/2 second. This is the timing provided by the NOAA APT standard. The minimum ("Int. min") and maximum ("Int. max") levels set the contrast of the image. I set them based on the measured black and white levels, respectively, from the time sink.
Image captured using the hardware setup and flowgraph discussed above. This came from NOAA-18. The maximum elevation was 49 degrees. Note the slight bowing of the image. This is from Doppler shift. I guesstimated the minimum and maximum levels for contrast based on the time-domain signal shown below.
This is the image from a NOAA-15 satellite using the Face2face RTL-SDR. The drift is probably due to the oscillator of the Face2face RTL-SDR not being as tight as those on the RTL-SDR Blog or Nooelec SDRs.
This is one line of the image annotated to show the different parts.

The Whole Thing

Here's the screen with all of the displays shown.

This is the display from the flowgraph above showing all of the displays.

Next Steps

My next post will cover a bit more about GRC's filtering, this time covering the filters that require some Python code. After that, I'll probably go into all of the different forms of demodulation (AM, FM, PM).

Understanding Gnu Radio Blocks: Filtering

Gary Schafer, Blursday, Pandemic Quarantine Time, Maybe December 2020

Now that I've beaten to death the different ways you can create a frequency demodulator in GRC, I thought I'd step back and take a look at some basic signal processing functions and how you perform them in Gnu Radio Companion (GRC). Let's start with filtering. If you don't understand filtering, signal processing becomes well-nigh impossible.

A lot of the knowledge for this post didn't come from either my undergraduate or graduate classes. It came from two books. These are Richard Lyons's "Understanding Digital Signal Processing" and Steven Smith's "Digital Signal Processing". Smith's book is even available for free as a PDF download (on a per-chapter basis, not the whole book at once). These books are expensive, but if you're looking for texts that actually explain the underlying concepts of digital signal processing, these are your starting point.

Filtering Overview

Filtering is the most-oft used form of signal processing. GRC not only provides explicit filter blocks, it is also built into many other GRC blocks. For example, several of the frequency demodulator blocks (FM Demod, NBFM Receive, WBFM Receive) also include not only frequency demodulation, but filtering as well.

The filters we're going to discuss are frequency-selective filters. There are four basic filter blocks we'll cover. The specific blocks we're going to cover are:

A filter is divided into three, basic sections. These are as follows:

A filter is divided into a passband (the area of minimal attenuation; this is the where signals will pass through unhindered), stopband (the area where signals are removed), and the transition band (the area where the filter is going from passband to stopband). I created this filter using the GRC "Low Pass Filter" block with a 100 kHz cutoff frequency, a 10 kHz transition width, and a 1 MHz sample rate.
This is a bandpass filter showing the three sections. A bandpass filter is essentially a highpass and lowpass filter combined.


If you study digital signal processing and filtering, you find out that filters come in two forms. These are finite impulse response (FIR) and infinite impulse response (IIR). The difference between them is that IIR filters use feedback, while FIR filters do not. This means that IIR filters have to be carefully designed; otherwise, they could be unstable. This means that the algorithms for designing IIR filters are more complicated than those for FIR. The advantage of IIR filters is that they tend to be easier to process (fewer computations required).

All of the filters on this post ("Low Pass", "High Pass", "Band Pass", "Band Reject") are FIR. This is why you'll see the term "FIR Type" at the top of the "Properties" window for each of these filter blocks.

We can use GRC to create a basic FIR filter. A FIR filter is, essentially, a combination of delays and multiply blocks. This is a simple, 5-tap filter that averages the input. Each "Multiply Const" is a "tap", and the "Constant" value in each block is the "tap coefficient". The GRC filter blocks that we'll cover will create filters that may have hundreds of taps. This is a simple example so that you understand a FIR filter and the terms "tap" and "tap coefficient".

This is the GRC graph of a basic, 5-tap finite impulse response (FIR) filter. This filter averages the input signal. Each "Multiply Const" block is a "tap", and the "Constant" value in each "Multiply Const" block is the "tap coefficient". While this filter uses 5 taps, a usable filter for an actual signal may have hundreds of taps.
Spectrum from the 5-tap averaging filter above. As is this a 5-tap averaging filter, and the sample rate is 100 kHz, we get drop-outs (nulls) at 20 kHz (100 kHz / 5) and harmonics of 20 kHz.

Float (Real) vs Complex

If you want to truly understand digital signal processing, you really have to understand complex signals. I'm not going to provide any kind of deep background on complex signals. I will provide the following bullet points, though:

Double-sided spectra of complex (top) and real (bottom) signals. Note that the real spectrum is symmetrical around the center, while the complex spectrum is not. Normally, real spectra are shown as single-sided because the two sides are essentially identical.

There is one thing you need to understand about filtering. There are complex samples and there are complex tap coefficients. The samples are what gets filtered; the tap coefficients determine whether the filter will operate on both sides equally (real taps) or can operate on each side uniquely (complex taps). I'll point out where this makes a difference as we go.

NOTE: If the filter does not explicitly state whether the taps are real or complex, then the taps are real.

How GRC Creates Filters & The Windowed-Sinc Method

Again, we're talking about four filter blocks. These are "Low Pass", "High Pass", "Band Pass", and "Band Reject". These four filters are all FIR filters. GRC calculates the tap coefficients for these blocks using the windowed-sinc method. Starting with the "Low Pass" filter, there are four steps:

  1. Calculate the number of taps required for the filter using the "harris approximation".
  2. Calculate the base sinc pulse using the number of calculated taps.
  3. Calculate the window values.
  4. Multiply the sinc pulse with the window on a point-by-point basis. The values of the windowed sinc pulse are the tap coefficient values.

A lowpass filter is the basis for all of the other filters. We can create a highpass filter from the lowpass filter values above by subtracting it from an impulse. We can create a bandpass filter by creating an appropriate lowpass and highpass filter, then calculating the convolution of the impulse responses of the two filters. This sounds complicated. When I say "impulse responses", since we're talking about FIR filters, the impulse response amplitudes are the same as the "tap coefficients" for our filter.

Calculate the Number of Taps

GRC calculates the number of taps using the "harris approximation". The equation is below.

"harris approximation" equation. This calculates the number of taps required for a particular windowed-sinc filter. The "taps" is the number of taps, or points in the impulse response for a FIR filter. The "stopband attenuation" value comes from the table below. "Fs" is the sample rate in Hz. The last value, "transition width", is the same value as would be entered in the "Low Pass" or "Band Pass" filter blocks.

The table below compares the different windows and their stopband attenuation values.

Windowed-Sinc Filter Minimum Attenuation in Stopband
Filter WindowStopband Attenuation, Minimum (dB)
Kaiser (Beta = 6.28)65
Kaiser (Beta = 6.76)70
Kaiser (Beta = 9.42)94.0
Kaiser (Beta = 15.71)>140

As an example, with a sample rate of 2.4 MHz, a transition width of 10 kHz, and a Blackman filter (stopband attenuation of 74), we calculate the number of taps as (74)(2.4 x 106)/(22*10 x 10-3) = 808 taps (rounding up).

Create the Sinc Pulse

For the rest of this example, I'm going to use Gnu Octave to calculate the various values as well as plot the graphs. If you have Gnu Octave loaded, you can download the file yourself and run it, if you're so inclined.

With the number of taps, the frequency cutoff, and the sample rate, we can calculate the sinc pulse. The "sinc", or "sine cardinal", is a quickly decaying sinusoid. The equation used to calculate the sinc pulse is:

The equation for calculating the sinc pulse, where:

  • N = number of taps
  • n = counter used to calculate sinc pulse, with -N/2 ≤ n ≤ N/2.
  • fc = the cutoff frequency
  • fs = sample rate

Note that, when n = 0, you have a "divide by zero" problem. The value hsinc(0) should be set to 2fc/fs.

Sticking with our example of a lowpass filter with a sample rate of 2.4 MHz, a cutoff frequency of 100 kHz, and a 808 tap filter, we get the following sinc pulse:

Sinc pulse for a lowpass filter based on a 2.4 MHz sample rate, 100 kHz cutoff frequency, and 10 kHz transition width. Also, if you're using the "Rectangular" window, this would be the tap coefficient values.

Create the Window

The filters discussed here allow for five possible windows. These are "Hamming" (the default), "Hann", "Blackman", "Rectangular", and "Kaiser". Let's go through them briefly.

The "Rectangular" window is really no window at all. This type of window, also called a "uniform" or "boxcar" window, really means you're not using a window. For a windowed-sinc filter, this means you're using a sinc pulse, and that's it. It provides the least amount of attenuation in the stopband (21 dB), but as a result, it also requires the least amount of processing.

The "Hann", "Hamming", and "Blackman" windows are standard windows. You can see how they are generated by reading fred harris's original paper on digital windows. While the Gnu Radio documentation on windows states that many of the windows are based on information provided in the Oppenheim and Schafer (no relation) text "Discrete-Time Signal Processing", harris's paper also provides the background for these various windows.

The last window, "Kaiser", is a special form of window. It has a parameter, called a "beta" value, that allows its attenuation to be adjusted. With the other windows, the attenuation is fixed. With a beta value of 1, the Kaiser-based lowpass filter is roughly equivalent to the "Rectangular" window filter. Also of note is that, with the first, four windows, you can get stopband attenuations of 21 - 74 dB. With the Kaiser window, you can have attenuation values greater than 140 dB.

For our example, we're using the "Blackman" window. We need a Blackman window made of 809 taps. (NOTE: The original value was 808, but we added one more for the zero index.) The equation for the Blackman window is:

w(n) = 0.42 - 0.5*cos(2*π*n/N) + 0.08*cos(4*π*n/N)


The graph for this particular window appears as follows:

Graph of a Blackman window.

Multiply Sinc Pulse with Window

By multiplying the sinc pulse with the window, we get the final windowed sinc pulse. The values used to create this graph are the "tap coefficient" values used for the FIR filter.

Graph of the windowed sinc pulse based on a 2.4 MHz sample rate, 100 kHz cutoff frequency, 10 kHz transition width, and Blackman window. The values used to create this graph are the "tap coefficient" values used in the lowpass FIR filter.

Here's the spectrum of this lowpass filter.

Spectrum of the lowpass filter made using the windowed sinc method, a 2.4 MHz sample rate, 100 kHz cutoff frequency, 10 kHz transition width, and Blackman window.

Here's the spectrum of the filter in GRC so that you can compare it with the filter calculated with Gnu Octave above.

Spectrum of the same filter as above, except made with GRC. The filter looks noisy on the high frequency end due to the fact that GRC uses 32-bit floating point numbers, while Gnu Octave (used to make the graph above) uses 64-bit floating point numbers. This gives Gnu Octave a higher dynamic range.

Once GRC has calculated the tap coefficients, it uses one of two methods to actually filter the signal. It either uses a straight time-domain convolution or a frequency-based (FFT) convolution.

Filter Examples

Let's look at some examples of various windowed-sinc filters. I'm going to use some FM broadcast stations to demonstrate both the windowed-sinc filters as well as the different types of filters (lowpass, highpass, bandpass and bandreject).

We're going to start with a spectrum of part of the FM band. I captured this using a RTL-SDR centered at 90.9 MHz and a 2.4 MHz sample rate.

Complex Sample Lowpass Filter

This graph will show how the unfiltered spectrum compares with the spectrum after being passed through a complex samples lowpass filter.
These are the properties of the lowpass filter for the complex sampled lowpass filter. The cutoff frequency is set to 100 kHz with a 10 kHz transition width. Here's where the difference between real and complex samples comes into play. The filter operates on complex samples, but since the properties does not explicitly say "complex taps", the tap coefficient values will be real. This means that this filter will operate on both positive and negative frequencies equally. This, in turn, means that this lowpass filter is effectively a bandpass filter.
Spectral display showing the unfiltered spectrum (black) and complex lowpass filtered (red). Because the samples are complex but the tap coefficients are real (see "Properties" above), the filter operates on both positive and negative frequencies equally. A lowpass filter created from real tap coefficients is effectively a bandpass filter centered on 0 Hz. The output of this filter will just be the analog portion of the FM broadcast signal. We could then send the output of the filter into a frequency demodulator, then an audio sink.

Complex Sample Real Tap Bandpass Filter

This is a graph that compares an unfiltered spectrum with that of a complex sampled, real tap bandpass filtered signal.
Properties of the real tap but complex sampled bandpass filter. Note that the "FIR Type" explicitly says "Real Taps". This means that both positive and negative frequencies will be adjusted equally. The settings for this bandpass filter will make it such that the IBOC (in-band on channel) signals will be passed, while all other signals and noise will be removed. NOTE: Even though this filter works on negative frequencies, the high and low cutoff frequencies must be positive frequency values.
Spectrum of a FM signal after the center FM signal IBOC signals have been bandpass filtered. Because these signals are equally spaced around the center frequency, a real tap bandpass filter will work on them. The cutoff frequencies were 100 kHz and 200 kHz. As a result, the bandpassed signals are -200 kHz to -100 kHz, and 100 kHz to 200 kHz.

Complex Sample Complex Tap Bandpass Filter

Okay, here's where we can go a little nuts with our frequency limits. The "Band Pass Filter" block allows you to select either real taps or complex taps. Again, real taps means the signal will operate equally on both positive and negative frequencies for complex samples. But complex taps can operate differently on positive and negative frequencies.

Graph for a complex sampled, complex tapped bandpass filter. This uses the same frequency limits as the real tapped bandpass filter above.
Properties for the complex sample, complex tap bandpass filter. Note that the "FIR Type" explicitly says "Complex Taps". This means that the positive and negative frequency limits can be different.
This is the spectrum of the complex sample, complex tap bandpass filter. This uses the same limits as the real tap bandpass filter above. However, because it's complex taps, the filter only operates explicitly between the frequency limits. Since the limits are 100 - 200 kHz, the filter only passes signals between these limits on the positive frequency axis. Note that the negative frequencies are completely filtered.
This is the same graph as above, only the frequency limits for the bandpass filter have been changed.
These are the properties for the bandpass filter. This is the same as the previous properties, but with the frequency limits set to the negative frequency axis.
Spectral display showing complex tap bandpass filter with frequency limits between -200 kHz and -100 kHz.

Complex Sample Highpass Filter

Just as a complex sample lowpass filter can effectively be a bandpass filter, a complex sample highpass filter can effectively be a band reject filter.

Graph to create a complex sample but real tap highpass filter. Again, because the filter taps are real, they will operate equally on the positive and negative frequencies.
Properties for the highpass filter. Note that the "FIR Type" does not explicitly say "complex" or "real". This means that the filter taps are real.
Spectral display of the complex sample but real tap highpass filter. The filter cutoff frequency is 200 kHz with a 10 kHz transition width. Because of the real filter taps, this filter effectively removes the center FM broadcast signal and its IBOC signals.

Real Sample Lowpass Filter

We're going to start with the complex sample lowpass filter which extraxts the analog FM broadcast signal. We can pass that through a frequency demodulator to get the baseband spectrum.

GRC graph showing a FM signal being first filtered (complex lowpass, which creates a bandpass filter), frequency demodulated, then lowpass filtered (real samples) to leave only the L+R audio signal from the baseband spectrum.
Properties for the first, complex sample lowpass filter. This filter extracts the analog FM signal at the center of the spectrum. The output is decimated by 10, meaning the input sample rate is 2.4 MHz while the output is 240 kHz.
Frequency demodulator. The GRC "Quadrature Demod" block is a polar discriminator, which frequency demodulates the input signal. The "Gain" of a polar discriminator starts with the sample rate divided by 2π. The sample rate is "samp_rate/10". Then, to normalize the signal, I also divided by the deviation of the signal (roughly 100 kHz). NOTE: The value of pi, listed as "np.pi", comes from the "Import" block. The "Import" block has a value of "import numpy as np".
Properties for the second (and real sampled) lowpass filter. This filter extracts the L+R audio signal from the FM broadcast baseband composite signal.
Baseband spectrum of a FM broadcast tation showing (from left to right) the L+R audio signal, the 19 kHz pilot tone, the 38 kHz L-R stereo signal, 57 kHz RBDS signal, and a 67 kHz SCA signal. The real sample lowpass filter extracts the L+R audio signal, shown in red.

Next Steps

I'd originally started this post to talk about filtering, demodulation and decimation / interpolation. That turned into a veeeeeeeeery long post. So I shortened it just to filtering. Then that turned into a veeeeeeeeeeeeery long post, so I shortened it just to these four filters.

What that means is that I'm now working on covering filters using the various Python command line functions. I'm also working on a post on demodulating NOAA APT signals as well as how to create a stereo receiver. The point of these posts is to allow you to create these receivers using the basic components already available in GRC. I want you to understand what's going on, not just "connect blocks together".

That will be for next time.

Here's a Random Fact...