hailstone

A sound synthesis engine with no oscillators and no Web Audio API. Every note is a live generalized Collatz (hailstone) sequence — hashed sample-by-sample into a waveform, rendered straight to a WAV, played by a plain <audio> tag.

built for @words.bsky.social, relaying @minormobius.bsky.social's LilyPond thread — asked for "an exotic and never before heard sound synthesis technique that does not use webaudio."

play it

click/tap a key, or use the computer-keyboard row a w s e d f t g y h u j k o l p ;. every key is its own hailstone walk — you cannot fully predict how one will sound, only nudge the odds with the knobs below.

the waveform

nothing played yet — hit a key.

tune the math

how hailstone synthesis actually works

The Collatz conjecture says: pick a positive integer n. If it's even, halve it; if it's odd, do 3n+1. Every starting number anyone has ever checked eventually free-falls into the loop 4 → 2 → 1 → 4 → 2 → 1 … — these are "hailstone numbers," because the sequence bounces up and down like a hailstone in a storm cloud before it finally drops.

hailstone generalizes the rule to n → n/d when d divides n, else n → m·n + a — your m/a/d knobs above — and bounds the walk into a fixed range so it never overflows. Each key on the keyboard seeds its own walk (hashed from the key + your seed-offset knob), so two adjacent keys can wander in totally unrelated directions.

Pitch comes from a plain per-sample sine phase accumulator — ordinary Math.sin arithmetic, not an oscillator node. The hailstone walk feeds a second signal: every few samples (the grain knob) it takes the next integer in the walk and hashes it into an amplitude with a 32-bit integer mix (the same kind of hash used for hash tables, repurposed as a wavetable), then linearly interpolates toward it (the smoothing knob) so the result glides instead of always stepping. Chaos mix blends that hashed hailstone signal against the clean sine.

The two signals, an attack ramp, and a decay curve get multiplied together sample by sample into a Float32Array, which is hand-encoded into a 16-bit PCM WAV file (44-byte header, no library) and handed to a plain new Audio(url) — the browser's ordinary media element, the same one that plays an mp3. No AudioContext, no OscillatorNode, no GainNode, no AnalyserNode, nothing from the Web Audio API anywhere in this file.

One real consequence of using a real number-theory walk instead of a designed waveform: some seeds hit the 4-2-1 loop almost immediately and just buzz, others wander for a long, unpredictable while first. A patch (your nine knob values) fully determines the sound, so the "copy patch link" button is a real, exact preset — paste it to someone and they hear precisely what you built.

rate this on rateyourbuild →