Accuracy testing of the PhosphorPSK BPSK decoder using the CLI test harness (PSKDecode). The CLI uses identical DSP code to the iOS app via symlinks — same source files, same binary logic.
The receiver is ported from fldigi's psk.cxx, the reference PSK31 implementation: two matched FIR filters (a 65-tap raised-cosine and the G3PLX pskcore filter) followed by fldigi's amplitude-waveform symbol-timing recovery, differential BPSK decode, and canonical Varicode.
PSKDecode CLI, which shares its DSP source files with the iOS app via symlinks (single source of truth).PSKDecode gen): raised-cosine pulse-shaped BPSK at 8 kHz, matching how a real PSK31 transmitter shapes its keying, with optional carrier offset and additive white Gaussian noise.| Signal | Condition | Result |
|---|---|---|
| Shaped synthetic | BPSK31, clean, fixed carrier | Exact (0 errors) |
| Shaped synthetic | BPSK31 with AWGN, 20 / 10 / 6 dB SNR | Exact |
| Real off-air recording | BPSK31, carrier ~1995 Hz | Decodes a clean CQ call |
| Faster modes | BPSK63 and BPSK125, shaped synthetic, clean | Exact |
A genuine off-air PSK31 recording, decoded at its true carrier:
The Varicode table is verified independently: 128 unique codes, no code contains an internal "00", and an encode→decode round-trip of mixed text is exact.
PhosphorPSK locks onto the strongest signal in the audio passband. There is no on-screen tuning to fiddle with — you isolate the signal you want the way you always would, by tuning your radio and narrowing its filters. This keeps the app to one clean screen and puts tuning where it belongs, on the rig.
On a quiet frequency with a single clear signal, that is all there is to it. On a crowded band, narrow in with the radio until the wanted signal dominates.
Real PSK31 shapes its keying with a raised cosine so the carrier amplitude glides to zero through every phase reversal — that is what makes the mode so narrow. A decoder needs a matched filter to recover it cleanly; a plain low-pass leaves too much inter-symbol interference. PhosphorPSK uses the same two-stage matched filter as fldigi, which is why it reads genuine off-air signals and not just idealised ones.
A very weak signal, or one whose carrier drifts during the over, may not lock cleanly. Tune for a strong, steady signal for best results — the same advice that applies to any PSK31 decoder.