← Ordo Artificum

libpsk

PSK31/63/125 + FEC modem library

A zero-dependency, built-from-scratch C99 library for encoding and decoding PSK31, PSK63, PSK125, and their FEC variants — the narrow-band phase-shift-keyed modes widely used for keyboard-to-keyboard HF communication, with optional K=7 convolutional forward error correction for the PSK63F, PSK125R, PSK250R, and PSK500R modes.

Working & available now GitHub

What it is

libpsk is a C99 static library that implements the full PSK31, PSK63, PSK125, and PSK FEC modem stack from scratch — modulation, demodulation, varicode encoding and decoding, carrier synchronization, and K=7 convolutional forward error correction for PSK63F, PSK125R, PSK250R, and PSK500R — with no external dependencies of any kind. No FFTW. No libsamplerate. No operating-system-specific audio framework. It operates entirely on caller-supplied float32 PCM buffers.

The library is designed to be embedded anywhere: Linux applications, Raspberry Pi utilities, and microcontrollers including the ESP32. The entire library compiles with a single gcc or clang command and requires no build system.

The PSK modes

PSK31 was designed by Peter Martinez (G3PLX) in 1998 as a narrow-bandwidth digital mode optimized for keyboard-to-keyboard HF communication. Its 31.25 Hz bandwidth — narrow enough to fit dozens of simultaneous QSOs in a single SSB passband — combined with differential phase-shift keying and a variable-length (varicode) character encoding, made it one of the most spectrum-efficient modes ever deployed on HF.

PSK63 and PSK125 are higher-speed variants that trade bandwidth for throughput: 63 baud and 125 baud respectively, at the cost of wider occupied bandwidth. All three modes use the same modulation scheme and varicode alphabet; only the symbol rate changes.

Despite the appearance of newer modes, PSK31 remains one of the most active HF digital modes in use. Its low power requirements, narrow bandwidth, and support in every major digital-mode application make it a practical choice for low-power and portable operations.

API surface

  • Encode — convert a UTF-8 string to a PSK31/63/125 varicode bit stream.
  • Modulate — convert a varicode bit stream to float32 PCM audio at a caller-specified sample rate and carrier frequency.
  • Demodulate — feed float32 PCM audio into a streaming demodulator; receive decoded characters as they are recovered.
  • AFC — automatic frequency control; the demodulator tracks carrier drift across the passband without caller intervention.
  • FEC modes — PSK63F, PSK125R, PSK250R, and PSK500R add a K=7 rate-1/2 convolutional code and a soft-decision Viterbi decoder, providing meaningful error correction under weak-signal conditions. FEC is transparent to the caller: the same encode/decode API is used for all modes.

The public API is a single header: include/psk.h. No C++ required; compatible with any C99 or later compiler.

Platform support

Linux x86-64
Native
Raspberry Pi
aarch64 / armv7
ESP32 / MCU
C99, no stdlib deps

Building

# clone and build
git clone https://github.com/jfrancis42/libpsk
cd libpsk
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
# output: build/libpsk.a

No system packages required beyond a C99 compiler and CMake 3.16+. All DSP — the cosine table, the carrier NCO, the Hilbert FIR filter, and the varicode table — is generated or embedded at compile time.

Credits & prior work

libpsk is a new implementation, but PSK31 would not exist without the people who invented and refined it:

Peter Martinez (G3PLX)

Inventor of PSK31. His 1998 design — differential binary phase-shift keying, raised-cosine envelope shaping, and a variable-length character encoding optimized for English text — defined the mode that is still in active use on HF more than twenty-five years later. The varicode table and the modulation scheme in libpsk are his.

Steve Ford (WB8IMY) & the ARRL digital community

Early adoption, documentation, and promotion of PSK31 in the amateur radio community established the mode's usage conventions — the 14.070 MHz calling frequency, the USB dial offset conventions, and the keyboard-to-keyboard operating norms — that libpsk is designed to interoperate with.

libpsk is independently authored and released under the MIT license, permitting use in both open-source and commercial applications.