Digital Modes with Linux SDR

Using digital modes with a Linux Software-Defined Radio adds another layer of complexity, because in addition to setting up your SDR software, you also have to set up software for the digital communications. These pieces of software then must then communicate audio streams, at the very least, and likely also a "rig control" protocol.

Your SDR software translates energy in the baseband IF signal from the hardware radio device into audio representing a signal transmitted by another radio (or multiple radios, for narrow digital modes!). This audio is normally played back through your computer speakers for phone or human CW operation. For digital modes, however, this audio is taken directly from the SDR software to a piece of software implementing a digital modem, which interprets the audio and presents you with the decoded information. You can think of this like replacing the audio cable which normally connects your HF radio's speaker/mic (or dedicated data) port and a sound card for digital mode operation on a traditional transciever with a software "audio cable" to the SDR transceiver.

Note: If you don't yet have your SDR working in Linux, you may want to visit my SDR in Linux page and get that hammered out before you continue. Like my other SDR pages, this page is focused on SDRs using a sound card for communicating I/Q signals with the radio.

In addition, these instructions are currently receive-only; transceiver operation will come later!

Inter-process Audio Streams

Any long-time Linux user will tell you that audio interfaces are one of the most fragmented and frustrating pieces of the Linux experience. In addition to having two major kernel interfaces (ALSA and OSS), there have been literally dozens of sound libraries and services which run on top of those interfaces. Some of these services have provided mechanisms for processes to communicate audio streams, in effect becoming a "sound device" for another process. Of the various projects in use today, three are relevant to us for digital modes on Linux SDR.

The first of these is JACK. If you have been through my SDR in Linux page, you will remember this service from DttSP and sdr-shell. JACK provides a low-latency, synchronized audio connection between hardware devices and software programs. Both hardware and software may act as capture or playback devices in Jack, effectively shipping audio between components in nearly any configuration you can imagine.

Next is PulseAudio. On the surface, PulseAudio appears to provide a similar service to JACK — it also provides an audio connection between hardware devices and software programs in flexible configurations. PulseAudio does not, however, provide many of the synchronization and latency guarantees that JACK does, which can be important in some situations. For our purposes, we're not too worried about that. It also provides an API (Application Programming Interface) which is somewhat more "traditional" for audio services in the Linux world. Because of this, many applications which do not support JACK without modification can easily support PulseAudio. In addition, PulseAudio can proxy between a non-JACK application and the JACK service.

The third sound interface which is of interest to us is PortAudio, and it is somewhat different from the previous two in that it is not an audio service, but simply a library for accessing audio devices. Its relevance to us is that it can speak to both the PortAudio and JACK services, and it is widely supported in Linux digital mode and SDR software.

The good news about this proliferation of audio interfaces is that, in many instances, you won't have to worry with them directly. This is because many software applications take care of the details for you, and allow you to (for example) select appropriate audio devices from a dropdown menu or list. The bad news is that we're going to have to worry with them at least a little bit. We'll be revisiting this topic later.

Digital Mode Software

As you are probably already aware if you have been using digital modes on any platform, Fldigi is possibly the premier digital mode package, and certainly the premier package in Linux. It supports dozens of digital modes for both receive and transmit, as well as integration with logging, callsign lookup, rig control, and many other features. While there are many other digital mode packages for Linux (including those for the few digital modes which Fldigi does not support, such as SSTV), we will focus our efforts on Fldigi for now.

Fldigi and sdr-shell

sdr-shell/Fldigi software stack

Figure 1. Fldigi sits on top of the sdr-shell software stack, communicating audio streams with sdr-core by way of the JACK service, and using sdr-shell for control of the hardware radio (frequency, sideband, PTT, etc.).

The first complete solution we will look at is Fldigi for digital communication, using sdr-shell as the radio. This combination is chosen for several reasons. Not only is Fldigi compiled with appropriate sound and rig control support for sdr-shell integration available readily on many distributions (including Ubuntu 10.10), but the light CPU load of sdr-shell makes it reasonable to run both Fldigi and sdr-shell together on even an older machine or portable machine where battery life is a concern. Other SDR programs, such as Quisk, may be used as the radio backend, but may require building against some non-system libraries, and will be addressed at a later time.

Fig. 1 depicts the software stack from the DttSP/sdr-shell discussion with Fldigi added into the mix. Fldigi gets its receive audio from, and sends its transmit audio to, sdr-core by way of the JACK service. Rig control (frequency, sideband, PTT, etc.) passes through sdr-shell, with sdr-shell coordinating the local oscillator on the hardware radio and the demodulation performed by sdr-core.

Connecting Fldigi to sdr-core audio

In order to connect Fldigi to the demodulated audio from sdr-core, we're going to connect to the sdr-core JACK playback device. If you used my sdr startup script to start sdr-shell, that device is named sdr_rx. If you used another method of configuring and starting sdr-shell, you will need to determine the name of the device on which sdr-core is providing demodulated audio.

Fldigi audio preference pane

Figure 2. Fldigi audio preference pane with the sdr-core demodulated audio output device selected.

Once you have determined this device, start sdr-shell and then Fldigi, in that order. Pull down the Configure menu in Fldigi and select Sound Card. You should see a dialog similar to Fig. 2. If your dialog does not have a section for PortAudio, your Fldigi has not been compiled with PortAudio support, and you will not be able to use this method. Assuming it does, check the PortAudio box, then pull down the capture device pulldown, select "JACK Audio Connection Kit Devices" and then your sdr-core demodulated output (as shown). If you see no selection for JACK devices, your PortAudio was not compiled with JACK support, and this method also will not work for you. Punch Save and Close, and you should see your SDR audio coming down the waterfall! Feel free to tune around a bit in sdr-shell and view the results.

You should not need to modify the other Audio settings panels in the Fldigi preferences. Leave the sample rates on "Native", and let sdr-core handle the mixer settings.

Connecting Fldigi to sdr-shell rig control

Audio demodulation is only part of the picture for comfortable Fldigi usage, particularly if you want to use its auto-logging and macro features. You're also going to want rig control! This allows Fldigi to tune the sdr-shell VFO, control its demodulation mode (upper vs lower sideband, CW, etc.), activate the PTT on your behalf, and other features.

Fldigi rig preference pane

Figure 3.Fldigi rig control preference pane configured for sdr-shell control.

Fortunately for us, sdr-shell presents a hamlib2 rig control server which Fldigi can connect to for rig control. Pull down your Fldigi Configure menu again, and this time select Rig Control. You should see the dialog in Fig. 2, or something like it; click the Hamlib tab if necessary. in the Hamlib tab, check Use Hamlib, then drop down the Rig selector and select Hamlib NET rigctl. sdr-shell does not listen on the default Hamlib NET rigctl port of 4532, but on port 19090, so edit the Device box to read localhost:19090. Ignore the rest of the settings for now. At this point, the Initialize button in the lower right should be red (don't worry too much if it's not); click it, then click Save and Close to get out of here!

You should notice that either sdr-shell jumped to the VFO setting in Fldigi, or Fldigi jumped to the VFO setting in sdr-shell. If not, twiddle the VFO setting in Fldigi a little bit and make sure that sdr-shell tracks. If they do not track together, something isn't right, and it's debugging time. However, you should find that changing the VFO or operating mode in either program updates the other almost immediately.


You're all set for operating digital modes with your Linux-based SDR!