Decoding APRS packets with an SDR

One minor goal I had when creating QTH.app was to make it inexpensive and easy to get started with APRS on a Mac. In this post, I’ll show you how to set up what I think might be the least expensive setup for receiving APRS packets over radio, beyond the cost of the Mac itself, of course.

I’m going to be focusing on the receive aspect of APRS. To transmit, you will likely want to invest a bit more money in a quality radio.

Most hams these days have one or more Baofeng radios on hand, and, while you can get your hands on them starting at $35, you would still need a way to interface it to your computer. To do that properly, you probably will need something like a Mobilinkd TNC3 or a SignaLink USB, both of which cost over $100.

However, you can get a RTL-SDR dongle for around $36, plug it into an available USB port and start receiving radio signals.

Step 1: Installing an Audio Router

This is the “secret sauce” to the whole setup. An audio router is a special macOS audio driver that allows you to pipe the audio output from one application to the audio input of another app.

There are two free options:

Both of these function pretty much the same. In my experience, Soundflower implements more of the audio driver API so you get less error messages when it comes to setting volume and such, but it has more trouble keeping up with Mac releases in its support history. It was originally supported by Rogue Amoeba, but is now in the hands of the original author. If you would like a commercially supported option, check out Loopback from Rogue Amoeba.

Choose an option and install it using their instructions. When you are done, you will see a new audio device in your System Preferences → Sound, in both the Output and Input tabs.

Here you can see what my Input tab looks like, with both BlackHole and Soundflower installed:

Step 2: Converting FM to Audio

APRS signals are transmitted as AFSK (Audio Frequency-Shift Keying), which means that audio tones are transmitted using FM modulation. If you’ve ever listened to an APRS packet, you’ll know that it sounds like an old-school modem, because, well, it basically is.

A Software Defined Radio (SDR) like the RTL-SDR captures a portion of the radio spectrum and sends this data via USB as a sequence of I/Q samples. We need to do two things to this stream of data before QTH.app can process it: it needs to be converted from I/Q format and processed by an FM demodulator.

Fortunately, there are a number of applications out there that do this, a subset, of course, that run on macOS:

  • rtl-sdr – command line app. You would need to run rtl_fm and pipe the output to an audio player, like SoX‘s play command
  • GNU Radio – it should be possible to assemble a flowgraph in GRC that reads data from the SDR, processes the signal with a FM demodulator block, and sends the output to an audio device.
  • CubicSDR
  • GQRX

For the purposes of this post, I’ll be using CubicSDR, because I found it to be the easiest to use of all the options.

  1. When CubicSDR starts, choose the RTL-SDR and click Start
  2. Tune the SDR to the national APRS frequency, 144.39 MHz. I made a bookmark in the lower left panel so that I can instantly jump to the right frequency.
  3. Select the FM modem in the upper left panel, and then, under FM Settings, choose the audio router device that you installed in Step 1. In the screenshot, the audio device I have selected is Soundflower. The full name of the device is “ma++ ingalls for Cycling '74: Soundflower (2ch)

Step 3: Decoding APRS packets

  1. Start QTH.app
  2. Open the Connections window. Click on the plug icon on the tool bar, or use Window → Connections
  3. Click the + button to add a new connection, choose ‘Audio Modem’, name it whatever you would like, and click Create.
  4. Click the gear icon next to your new Audio Modem connection to bring up the configuration panel.
  5. For Audio Output, you may choose any device you want, since you will not be transmitting anything. I chose my built-in speakers
  6. For Audio Input, choose the audio router device you installed in Step 1.
  7. Click Save to save the settings and close the panel.
  8. Toggle the switch to start the Audio Modem connection.

And done! Using the audio router, CubicSDR will convert the incoming signal to an audio stream and QTH.app will decode APRS packets from the incoming audio stream.

Bonus Trick: Getting Data From Someone Else’s SDR

Ok, so you might be in my situation – I have an RTL-SDR, but I live in an area where there is very little actual APRS activity on the local airwaves. What if I wanted to listen to the airwaves somewhere else?

You can try out WebSDR.org. This website features a number of SDR receivers that have been connected to the Internet. You can tune to the APRS frequency and listen to the audio.

The only catch here  is that many web browsers do not give you an option to select an alternate audio output device; they simply send all audio to the system default device. If this is the case, and you want to route the audio to QTH.app, you would need to go into System Preferences → Sound and choose the audio router device as your system output device. Just know that while this is set, all other audio, such as alerts or music, will go there as well. This won’t bother QTH.app any, but your computer will be a bit quiet while you have it set up this way.

8 thoughts on “Decoding APRS packets with an SDR”

  1. If my dog and I are in a place with no Internet connection and he is wearing an aprs beacon, am I right I could use this setup to read any packets received from it? More importantly what is the resolution of the map that QTH uses and can I say, load a USGS standard map or equivalent resolution map and use that to plot position of the beacons?

    1. Sending and receiving packets via RF works with no Internet via any of the supported radio connections.

      Internet may or may not be necessary depending on the map layer you are using. By default, QTH.app uses maps provided by Apple. Like Google Maps, Apple Map tiles are fetched from Internet servers on an as-needed basis, because the entire dataset is generally too large for most computers and for copyright reasons. In addition Apple Maps, QTH.app also supports OpenStreetMap, OpenTopoMap, and CyclOSM, but all of these fetch their tiles from the Internet as well.

      QTH.app does support a Local Tile Server map layer. This involves running some sort of map tile server locally on your machine. Here is an article I posted on how to run a local OpenStreetMap tile server for this purpose: https://www.w8wjb.com/wp/2021/07/29/offline-maps-with-qth/

      Right now there are only instructions for OpenStreetMap. This type of tile server generates the image tiles on the fly as you need them from that OpenStreetMap dataset that you download. This is good for road-map style maps. However, if you are looking for maps that show terrain features, elevations, or satellite imagery, OpenStreetMap may not be what you are looking for.

      QTH.app will support any tile server as long as it follows certain tile server conventions. I don’t know if someone has made a tile server for the USGS dataset. If you send me an email describing the maps that you might want to use, I can see if adding support would be feasible.

  2. Hey there –
    Thanks for this fun article, and development on QTH.

    I installed and configured this as you’ve outlined above with the exception that I used blackhole instead of soundflower. I can see the green input bar moving when an APRS transmission breaks the squelch on Cubic SDR, but I don’t see any stations projected on the map, nor do I see anything in the log when packets come through.

    Thanks,
    Marc KN6PNF

    1. Here are a few things that you might try:

      • Try disabling or lowering the squelch on CubicSDR. Sometimes the squelch doesn’t open in time to catch the full packet
      • Try enabling or disabling the 6db emphasis filter. I’m not sure whether CubicSDR applies a de-emphasis filter or not.
      • Make sure that the input levels are around 2/3rds of the way up. It won’t decode if the levels are too low
      1. Thanks! I increased the gain in Cubic SDR, and removed the emphasis filter and now the packets are being recognized. Much appreciated! 73 KN6PNF

  3. Hi there, very nice app, thank you! I’ve downloaded it on an Italian system, which explains the default interface language, but there’s a couple of localization mistakes in the Connections configuration window. “Audio output” is marked “Usciata Audio”, which is a typo for the correct “Uscita”, while “Audio Input” is mistakenly indicated with “Uscita Audio”: it should read “Ingresso Audio”!

Leave a Reply

Your email address will not be published. Required fields are marked *