slowrx 0.3.0

Pure-Rust SSTV (Slow-Scan TV) decoder library — a port of slowrx by Oona Räisänen
Documentation

slowrx.rs

A pure-Rust port of slowrx — the SSTV decoder by Oona Räisänen (OH2EIQ). The original is excellent; this port aims to bring it to the Rust ecosystem with a library-first API while preserving the algorithmic work that made slowrx great.

Crates.io Docs.rs CI License: MIT

Status

🛰️ 0.3.0 — V2.2 published. PD120, PD180, PD240, Robot 24, Robot 36, and Robot 72 decoding from raw audio.

PD120, PD180, and Robot 36 are validated end-to-end against real-radio captures: PD120/PD180 against the ARISS Dec-2017 corpus (6 of 7 fixtures decode to images visually matching the reference JPGs), Robot 36 against the ARISS Fram2 corpus (all 12 fixtures decode to images visually matching the reference JPGs — see tests/ariss_fram2_validation.md). PD240 ships with synthetic round-trip coverage only — a real-radio fixture is pending. Robot 24 and Robot 72 ship with synthetic coverage; Robot 24 inherits Robot 36's evidence by structural identity (same decoder code path, only LineTime differs). Remaining V2 mode coverage (Scottie, Martin) is on the roadmap.

Install

# library
cargo add slowrx

# CLI tool (decodes WAV → PNG)
cargo install slowrx --features cli

Quick start

use slowrx::{SstvDecoder, SstvEvent};

// Construct a decoder at the caller's audio sample rate.
let mut decoder = SstvDecoder::new(44_100).expect("valid sample rate");

// Feed audio chunks; consume events as images complete.
let audio: Vec<f32> = vec![0.0; 1024]; // mono samples in [-1.0, 1.0]
for event in decoder.process(&audio) {
    if let SstvEvent::ImageComplete { image, .. } = event {
        println!("decoded {}×{} {:?} image",
                 image.width, image.height, image.mode);
    }
}

CLI:

slowrx-cli --input recording.wav --output ./out
# → out/img-001-pd120.png, out/img-002-robot36.png, ...

What it does

slowrx.rs decodes Slow-Scan Television images from a stream of audio samples. Mode coverage roadmap:

Mode family Shipped Roadmap
PD PD120, PD180, PD240
Robot Robot 24, Robot 36, Robot 72
Scottie Scottie 1, Scottie 2, Scottie DX
Martin Martin 1, Martin 2

VIS header detection is automatic — feed the decoder audio, get images out as they complete.

Why a Rust port?

Several mature C/C++ SSTV decoders exist (slowrx, QSSTV, MMSSTV) but no production-quality pure-Rust library is available on crates.io. This crate aims to fill that gap with:

  • Library-first design — no GUI dependency. The crate processes audio buffers and emits image-data events; callers render them however they want (Cairo, web canvas, terminal ASCII, file output).
  • Modern Rust idioms — no unsafe, structured error types via thiserror, builder-style configuration.
  • Comprehensive tests — round-trip synthetic encoding, regression fixtures from real ARISS receptions, cross-validation against slowrx on shared test corpora.

Acknowledgements

This crate would not exist without slowrx by Oona Räisänen (OH2EIQ). slowrx's clear, well-documented C source served as both the reference implementation and the sanity check during this port. Algorithm choices, mode-specification tables, frequency-to-pixel mappings, and overall architecture are all directly inspired by — and in many places translated from — slowrx.

If you use this crate, please consider also acknowledging the original project. The SSTV community owes a real debt to Oona's work.

License

Released under the MIT License.

slowrx is distributed under the ISC License. The MIT/ISC pairing is intentional — see NOTICE.md for the full attribution and license preservation notice.