Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Tree: 6d65527d18
Fetching contributors…

Cannot retrieve contributors at this time

319 lines (282 sloc) 15 KB

Ascii/Iambic morse keyer (and more) using Jack audio connection kit.

This is a morse code keyer consisting of Jack Audio Connection Kit plugins, a Teensyduino hardware interface, and a variety of additional Tcl hosted SDR tools for testing and playing with them.

The larger project growing here is a kit for building building software defined radios which uses Jack and Tcl to solder the pieces together.


I’ve written these instructions as I use them on a laptop running Ubuntu 11.10, the Oneiric Ocelot release. It is also being tested on Ubuntu 12.04, the Precise Pangolin release. Most of it is generic enough to work on other current Linux systems with minor translations of package management tools and package names. It’s also generic enough to port to MacOS or Windows. But I don’t run other Linux systems, MacOS, or Windows so asking me to help you make it work may be a lost cause, unless you want moral support.

I will be assuming that you have installed the keyer sources in your home directory, which I abbreviate as “~”. So I will refer to the keyer source directory as “~/keyer” in all that follows. It doesn’t depend on being there. You can install it anywhere. That isn’t where I install it. But these instructions will depend on you making the necessary translation if you install the sources someplace else.

Required packages

Using your preferred Ubuntu package manager, you want to install the following packages:


These are not all the required packages. Several other packages will be dragged in because they’re required by the packages listed.

The “apt-get” command to install these packages is

sudo apt-get install build-essential git-core jackd2 libfftw3-dev libjack-jackd2-dev qjackctl tk-dev tcllib tkcon libusb-dev

Note that Ubuntu 11.10 has some confusion in the packaging of jackd. Some audio packages were built against jackd1 and some against the jackd agnostic package, so some audio libraries will force installation of the old jackd version 1 package. I force jackd2 because it’s what I use. I don’t know if jackd1 will work.

Also, there is a bug in qjackctl that unnecessarily disables PulseAudio. Edit /usr/bin/qjackctl and make the non-comment part look like this:

#PASUSPENDER="`whereis -b pasuspender | cut -d ':' -f 2 | tr -d ' '`"
#( [ -x "${PASUSPENDER}" ] && ${PASUSPENDER} -- ${PROGRAM} ${@} ) || ${PROGRAM} ${@}
${PROGRAM} ${@}
exit 0

to avoid the problem, or leave it as it is. This project doesn’t use PulseAudio.

Getting the source

The sources are archived at Assuming that you installed the git packages and want the sources to be in ~/keyer,

cd ~ && git clone

will create a new directory named “keyer” in your home directory. The sources will be up to date as of the time that you clone the repository.


cd ~/keyer && git pull origin master

will refresh your sources to the most recent at any time. It’s prudent to run:

cd ~/keyer && make all-clean

before refreshing the sources because the list of things to be built and cleaned up is changing all the time.

If things get messed up (and you have no local changes to preserve) you can always:

cd ~ && rm -fr keyer && git clone

to start over again from a clean copy.


cd ~/keyer && make

will compile everything needed to run. If you have problems, please go back to the list of required packages and make sure you didn’t miss one.

cd ~/keyer && make clean

will remove intermediate files not required to run.

cd ~/keyer && make all-clean

should remove all built files.


I don’t do any install. I usually run the scripts from ~/keyer manually prefixing bin/ to get the commands I want to run.

MidiKey hardware interface

The whole point is to get CW keying information into the computer with the lowest latency possible. To do that you’ll need a MIDI-USB-Keyer dongle to hookup your straight key or paddle.

I started with a paddle interface built on a breadboard from a Teensy 2.0 (from, a stereo audio jack, and three jumper wires.

Blurry image1, Blurry image2, Blurry image3.

The Teensyduino application to translate paddle transitions into MIDI events is in MidiKey/MidiKey.ino. The instructions for building it are in the source code.

I’ve packaged the keyer dongle into an Altoids Smalls tin, shown in the tin, and exposed. The perf board is supported on 5/8” standoffs of the bottom of the tin. The Teensy is mounted on upside down header pins, short end through the perf board long end through the Teensy mounting holes. The Teensy and stereo jack are super glued onto the perf board. The stereo jack lugs are soldered to a set of five header pins. The rest of the connections are wire-wrapped between long legs of header pins.

The set of 11 pins at the left edge of the exposed image is a Sparkfun Blackberry trackball breakout which is unsupported in the software at the moment. You can see the trackball erupting through the tin.

In retrospect, I’d switch to using input pins closer to the stereo jack end of the Teensy.

Glen Overby provoked this project on the dttsp list at yahoo back in November 2011. He has built another MIDI key interface which is described here. It should work with this software if the MIDI note is set properly.

Teensy B0->stereo jack dit
Teensy B1->stereo jack dah
Teensy GND->stereo jack common
Iambic paddle->stereo jack
Teensy USB->computer


My basic usage pattern is to use qjackctl to configure my jack server, start the server, control the server, and manually make connections between modules.

On the qjackctl Setup>Settings panel, I have:

MIDI Driverraw
Sample Rate96000
Port Maximum512

Some of the commands will automatically make connections to a default set of ports, if the port names match with their expectations. You can view what happens and what fails to happen with qjackctl. The most usual problems are that the MidiKey hiccupped and moved from system:capture_1 to system:capture_2, or that you already have another keyer widget running which has claimed the Jack client names.

bin/keyer-control, bin/keyer-scope, and bin/pileup are written to automatically hook themselves up in a useful way, and they are the applications which I try to test to make sure they work before each push back to github.

You can configure your jack server to “autolaunch” whenever an application tries to open it, but the result will be that you get a bunch of messages from jackd which appear to come from your application, the messages look pretty much the same whether jackd succeeds or fails to start, and the autolaunched jackd may or may not be visible and controllable from qjackctl. So turn off the autolaunch feature and use qjackctl so you can see what’s happening.

All of the commands in ~/keyer/bin are Tcl/Tk scripts. I’m only going to talk about the ones that make the keyer work. The rest of it is other parts of a software defined radio software kit that gets soldered together with Jack and Tcl. Some of it may work, some of it used to work, some of it never worked, some of it has been abandoned, some of it is experimental code that may yet be abandoned or changed beyond recognition. So, if you’re curious, try it. If you’re still curious, open it in a text editor. All the code is either in the script file, or part of standard Tcl/Tk, or it’s in ~/keyer/lib.

keyer-control - launch and control ascii and iambic midi keyers

By default, keyer-control starts a complete iambic keyer and a complete ascii keyer. It implements the following command line options to customize its operation. These are all option names preceded by two hyphens.

–ascii 0turns off the ascii keyer module
–debounce 0turns off the debounce module
–dttsp_iambic 1turns on the dttsp keyer
–iambic 0turns off the iambic keyer
–ptt 0turns off the ptt module
–ascii-*passes -* to the ascii keyer
–ascii_tone-*passes -* to the ascii tone generator
–debounce-*passes -* to the switch debouncer
–dttsp_iambic-*passes -* to the dttsp keyer
–iambic-*passes -* to the iambic keyer
–iambic_tone-*passes -* to the iambic tone generator

I’m not going to enumerate all the suboptions that can be passed on to the submodules because they’re all exposed on the keyer-control panel, even the ones that you shouldn’t change. The panel remembers nothing, so if you get wedged, just quit and start over again.

The iambic tone generator gets shared between the iambic and the dttsp_iambic keyers. I haven’t tried running both at once – the control panel gets too tall for my laptop screen.

keyer-scope - watch keyer glitches

This is a work in progress for debugging keyer timing and tone generation. It connects to the system midi capture device to get paddle input events, to the debouncer to get deglitched input events, to the iambic keyer output to get the key logic output, to the PTT outputs to get the final ptt and key outputs, and to the iambic keyer tone generator to get wave forms, and displays all the signals on a multi-panel oscilloscope.

It also demonstrates the advantage of building software components soldered together in Jack. All the traces supplied by Jack are available as test points without any modifications to the underlying computation. You can attach a meter, a scope, a spectrum analyzer, or whatever to any Jack port and watch what its doing.

But it’s sort of rough. The vertical scale control for the wave form display, for instance, is the output gain on iambic tone control. Turn it up before you start recording.

pileup - morse code training

Pileup sends morse code for you to echo back with your keyer.

The words sent are either callsigns from the original pileup program or words with up to N dit clocks from the start of the first element to the end of the last element.

There is a limit on how many simultaneous voices can run. It used to be around 20, but I’m not sure what it is now. The voices all pileup on each other using random frequencies in a specified band, using random speeds in a specified range, using random power levels in a specified range. They all break to hear what you’re keying, then start up again. And the audio mutes the received voices to echo your sidetone according to the ptt settings.

There is a simulated sideways waterfall display, which will become a real waterfall eventually. But you shouldn’t look at it, you should work to hear the code and echo it back. Play with your eyes closed.

I’m doing 11 dit words at 18 wpm with a single voice. I think the judge is corrupt, but I haven’t had time to investigate.

MidiKey - Teesyduino application

The necessary steps should be listed in the comment at the head of MidiKey/MidiKey.ino.

Don’t forget to install the /etc/udev/rules.d rules file for the Teensy.

More details, too much information

I threw a bunch of stuff out of this README so it would be less of a mess. They’re all in the Notes directory of the project, and if you navigate there in the github web interface then github will open files and mark them down for you. This README and all the files in the Notes directory are written in org-mode using emacs, an outline mode. The github markdown processor does a good job of converting them to web pages, but some things get lost or mangled in the translation, like internal links.


This code is derived from many sources.

The largest debt is to the dttsp sources, Copyright (C) 2004, 2005, 2006, 2007, 2008 by Frank Brickle, AB2KT and Bob McGwier, N4HY. Many of the modules here are directly or indirectly derived from their code.

I’ve learned a lot from reading documentation, example applications, header files, and library code for ALSA and Jack.

Perry Cook’s Synthesis Toolkit provided one worked example of how to make adjustments to DSP components on the fly.

Faust,, is a really neat idea, dsp computations described as an algebra on infinite streams of samples. It also provided an example of how not to make adjustments to DSP components on the fly.


Copyright (C) 2011, 2012 by Roger E Critchlow Jr, Santa Fe, NM, USA.

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

Jump to Line
Something went wrong with that request. Please try again.