Releases: stoatworks-labs/slowscan
Release list
v0.1.0
Slow-scan television over HF, as an FFGL effect for Resolume Arena and Avenue, shown as SW Slowscan. SSTV sends a still picture down a voice radio channel as audio: each pixel a tone, 1500 Hz for black to 2300 Hz for white, a line at a time, with a 1200 Hz pulse between lines. So the plugin builds the actual chain, source → tones → HF channel → discriminator → line timing → picture, on the CPU at 11,025 samples a second, in Martin M1, Scottie S1 and Robot 36. What reaches the screen is whatever the receiver made of it.
None of the look is drawn. A receiver clock a few ppm off slants every vertical edge, with colour fringes where one scan pulls into the next; Line Sync takes the lean away. The new picture overwrites the old from the top under a cursor. Below the FM threshold the discriminator throws clicks and the picture turns to streaks; fading shows as bands of noisy lines, multipath as ghosts, a carrier on frequency as vertical stripes. The audio routed in goes on air as interference shaped by Resolume's FFT bins. Speed runs a two-minute picture in as little as a second without changing anything per sample. The defaults are Martin M1 at 40x over a 25 dB path, a picture every three seconds.
What is verified
By tools/verify.sh on an M4 Max, macOS 26.4, on 2026-09-24, every physics check at 320×180 and 1280×720:
- Every line start, segment boundary and pixel boundary of Martin M1, Scottie S1 and Robot 36 lands on its constant to the sample; drift over a frame is at worst 0.9997 samples, never a sum.
- At ±100 and ±300 ppm the fitted lean is within 5e-5 px/line of
e × T_line / T_pixel(tolerance 0.0023); fitted again in the rendered frame at ±150 ppm it is 0.14637 px/line against 0.14634. - Flat black, grey and white come back to the exact 8-bit value; an edge's tail decays with τ = 5.797 px against the one-pole's 5.797.
- Above the knee the pixel variance is within 2% of the linearised discriminator's closed form; the knee sits at 3.70 dB SNR against Rice's 3.11 (tolerance 2.78, derived).
- 24 lines of a noisy, fading, multipath picture are bit-identical at 1x and 120x. VIS 44, 60 and 8 decode back to Martin, Scottie and Robot; at 300 ppm, where Free-run would drift 75 px, Line Sync holds the edge within 0.24 px.
- 14 of 14 negative controls fail as they should, and a one-character mutation of the shipped compose shader was caught by
--renderand--rasterat both rasters. - All 20 swept controls change the picture; all 3 shaders compile through
glslc;oxbowseesSW Slowscan/SS01/ effect and renders 120 frames. - Render cost at 40x 1.00 ms/frame at 720p, 1080p and 4K alike: it is the CPU signal chain, which ignores the output size. It scales with Speed, 0.31 ms at 1x and 2.50 at 120x (1080p); with multipath, QRM and audio all on, the chain needs 3.7 ms of CPU a frame at 120x, on the host's render thread. macOS figures only.
- Windows, in Resolume Arena 7.27.1 (win-lab, Mesa llvmpipe, no GPU, 2026-09-24): a CI build of this source loads from Extra Effects, registers as
SW Slowscan/SS01/ effect, all 27 host controls match the declaration, it renders and Arena's log stays clean: 9 of 9 of the fleet gate's checks. 18 controls moved the picture, 4 of them under a precondition; the 3 audio-driven controls (Audio, Audio QRM, Bin Spacing) were not testable, because win-lab has no sound device. Software rendering says nothing about a GPU or about speed.
What is not
- Never loaded into Resolume on macOS. How its controls in four groups, one of them the audio input, present in the inspector there is untested.
- Nobody has measured how Resolume lays out its 64 FFT bins, so
Bin Spacingexposes the assumption (Linear or Log); whether 3.7 ms of CPU a frame at 120x is comfortable on a busy show machine is untested too. - The fading is flat and the channel is one path or two, not a multi-tap ionospheric model. The receiver is one decoder design, not MMSSTV's or QSSTV's, and when a header fails it starts the picture as an operator pressing Start would, without searching by correlation.
- There is a browser demo: the plugin's own shaders in WebGL2 around a JavaScript port of its signal chain, with no audio input. It is a port, not the plugin.
- No OpenFX port, no presets. There is a user guide at https://stoatworks-labs.com/software/slowscan/guide/.
The macOS build is Developer ID-signed and notarised by the release pipeline after publication; if macOS refuses a download, it predates the signing, so download it again. The Windows build is unsigned, so SmartScreen warns once.