Voice on the SignaLink USB with Linux

I (John Goerzen / KR0L) wanted to use my SignaLink USB for voice keying during contests and the like. I use Linux for Amateur Radio, and so a natural thought would be using shell scripts for this.

As I explained on the SignaLink USB page, one solution to this problem is to mix in a 21000Hz tone into a 44100Hz 16-bit file. I got tired of doing that manually, so I now do it automatically.

In any shell script, you can put this function:

  playcmd () {
    sox -V0 -m "$1" "|sox -V0 -r 44100 $1 -t wav -c 1 - synth sine 21000 gain -1" -t wav - \
     | aplay -q  -D default:CARD=default
  }

  playcmd file.wav

Let’s break this down:

  • I will be using sox to merge in the 21000Hz tone.

  • -V0 says that I want no status output from sox

  • -m says that I will be merging two files into one using sox.

  • "$1" is the parameter for the main file

  • Then the rest of it is the command to generate the 21000Hz tone. We set it to rate 44100, output type wav, one channel. We pass the input file to it as well, simply to get a length. We then generate the tone.

  • The result is passed to aplay (for whatever reason, play from sox doesn’t work right here). You may need to adjust the -D value based on the output of aplay -L on your system.

Then, we can simply say playcmd file.wav to play the file.

You’ll want to use a mixer program such as alsamixer to first set the playback gain to 99 on the SignaLink USB interface before running this script.

Automatically calling CQ

During contests, it is helpful to automatically call CQ. Here’s a script that will do that:

  # NOTE: use alsamixer and set playback gain to 99

  set -e

  playcmd () {
    sox -V0 -m "$1" "|sox -V0 -r 44100 $1 -t wav -c 1 - synth sine 21000 gain -1" -t wav - \
    | aplay -q  -D default:CARD=default

  }

  DELAY=${1:-1.5}

  echo -n "Started at: "
  date

  STARTTIME=`date +%s`
  while true; do
          printf "\r"
          echo -n $(( (`date +%s`-$STARTTIME) / 60))
          printf "m/${DELAY}s: TRANSMIT"
          playcmd ~/audio/cq/sweeps.wav
          printf "\r"
          echo -n $(( (`date +%s`-$STARTTIME) / 60))
          printf "m/${DELAY}s: off         "
          sleep $DELAY
  done

This will, by default, transmit the file ~/audio/cq/sweeps.wav. It will pause for 1.5 seconds after each TX, then start transmitting again. When you hear a station answering your CQ, just hit Ctrl-C to halt transmissions. When you’re ready to transmit again, if you’ve saved the script under the name cq, just type cq and you’re off and running again.

Some of what you see is a little fancy screen display. Here’s what it will look like while it’s actively transmitting:

  Started at: Wed Dec  1 22:05:03 CST 2010
  0m/1.5s: TRANSMIT

The date at the top is the precise time when you started running the script. The 0m is how many minutes have elapsed since that date (in other words, how many minutes you have gone without hearing a station call you). The 1.5s is the delay between transmissions.

When it’s waiting to transmit again, it will just look like this:

  Started at: Wed Dec  1 22:05:03 CST 2010
  1m/1.5s: off

The string TRANSMIT changes to off.

If you prefer a different delay, you can pass it as a parameter; for instance cq 2.0 will use a 2-second delay between CQ calls.


Ths SignaLink USB is a small radio interface for use with Digital Amateur Radio. It appears to your computer as a USB sound card. It has a completely isolated radio interface and is sold in various configurations with prebuilt cables for many popular rigs. It’s less than $100, which means it’s very popular.

Here is a collection of tips for using Amateur Radio on Linux.