001.1.000

robson / Exceed presents

unisynth

One soft synth for a 64k intro. Four synth families from two decades of the demoscene, rebuilt as settings of the same voice, and checked against the originals until they agree.

osc1 · typephase-mod operator
lineage: WaveSabre · Logicoma
13,312 B
a WaveSabre reference track, engine and song, packed. The original engine needed 14,336.
43/43
legacy device tests pass parity against the engines they were written for
9.6×
real time on one thread for the heaviest reference track. The original: 7.1×.
15 → 9
legacy effects merged into nine effect kinds, every algorithm kept whole
260
normalized parameters per instrument
the voice

Fixed slots. The song decides what fills them.

A voice is 3 oscillators, a noise source, 4 filters, 4 envelopes, 2 LFOs and a 16-slot mod matrix. A WaveSabre bass and a Tunefish pad are both just values in those slots. Control runs on an absolute 32-frame grid that tightens to 8 frames for 256 frames after every note edge.

Signal flow of one unisynth voice. Three oscillators chain by phase modulation and sum with noise, pass four serial filters, the amp envelope and pan, then the nine effect kinds. Envelopes, LFOs and controllers feed the mod matrix, which can target any slot. osc1pm osc2wt osc3blit pm-outpm-out noise Σ filt1 filt2 filt3 filt4 SVF · ladder · RBJ · notch · feedback SVF · 4-pole × env1 · pan main L/R fx 65–73→ mixer matrix · 16 slots env1–4 lfo1–2 + wheel · bend · CC2–7 · velocity · key
oscillatorfilterenvelopeLFOmodulationvoice
device rack

What is in the box

Every panel is a module a build can include or leave out. The 64k player links only the ones its music touches.

osc · six types

One oscillator slot, six engines

Phase-mod operator, band-limited saw and pulse, spectral wavetable with 1–10 unison layers, a sampler for GSM and GM.DLS, V2's naive oscillator, and the 1997 cauldron waveforms.

3 slotschained by phase modulation
filt · four lineages

Filters that sleep when open

State-variable, ladder, RBJ, resonator notch, V2's feedback SVF and 4-pole. Filters 1 and 2 run single, serial or parallel. An open filter is not run at all.

1–6 %less time with open filters
mod · matrix

Envelopes, LFOs, 16 routes

Each envelope keeps its original curve law. Matrix routes are source, target, amount and operation: scale, offset or add.

16 slotsany parameter is a target
convert · four formats

Four families in, one format out

The converter reads WaveSabre, Tunefish 4, Farbrausch V2 and mini-cauldron music. A failed conversion writes nothing at all.

359/359V2 files loaded byte-identical
threads · opt-in

Same bits, any block size

Output does not depend on how a render is split. Threads are opt-in and bit-identical. A build without them has no thread code at all.

1.7–4.5×faster at 8 workers
speech · channel strip

It talks

V2's formant speech synth with 69 phonemes, and its channel strip: DC filter, look-ahead compressor, 150 Hz bass boost, drive, chorus.

69phonemes
daw · in the browser

A DAW that runs the intro's own code

Arrangement, piano roll, generated device panels, mixer and bounce, compiled from the same Rust to WebAssembly. Live playback is bit-identical from frame 0. A live view draws each voice on its envelope, the LFO phases and the filter spectra.

0.1 msper 128 frames, 24 % of budget worst case
memory

Small voices

About 2.3 kB per voice. Sixteen phase-mod voices fit in 37 kB.

≈ 2.3 kBper voice
fx 65–73

Fifteen effects in, nine kinds out

Nothing was rewritten to sound "close enough". Each legacy algorithm survives whole as a mode of its kind, with its own parameters in their original order. At 44.1 kHz and tempo 120 every mode renders bit-identically to the effect it came from.

Left: WaveSabre in orange, Tunefish 4 in cyan, Screwdriver from the qm210 WaveSabre fork in green. Right: V2 and cauldron modes joined the same kinds later.

size budget

Pay only for what the music plays

Every module is a cargo feature. The converter reads the music and prints the features it needs. Leave a module out and anything that uses it fails at load with UnsupportedModule, never silently.

every module linked34,304 B
WaveSabre track · original engine14,336 B
WaveSabre track · unisynth13,312 B
Tunefish track · original engine17,920 B
Tunefish track · unisynth22,016 B

Not solved yet. Tunefish music is still 18–30 % bigger than with its original engine. Sizes are engine plus music, squishy-packed, i686.

parity

The old engines stayed on as judges

Every legacy test is rendered by the engine it was written for and by unisynth. A result counts only when loudness, octave bands and onsets agree and a human has listened to both and signed off.

octave bands · 63 Hz – 16 kHzoriginalunisynth
0/43
WaveSabre and Tunefish device tests
0/6
reference tracks, A/B approved
0/15
Farbrausch V2 tracks, A/B approved
0/85
mini-cauldron phrases

Pass: BS.1770 loudness within ±1 dB, every octave band within ±3 dB, onsets aligned. Engines with randomness are judged on 8 seeds.

how it was built

One week, as a piano roll

Every step was a written change first: proposal, design, task list, then code. Sixteen synth changes landed between 25 and 31 October 2026. Solid notes are done, dashed ones are still open. Scroll to play.

  1. Port first, then unify

    WaveSabre and Tunefish 4 were ported to Rust and checked against upstream before anything was merged. The Tunefish port passed on the first run.

  2. Old engines as oracles

    The legacy engines stay in the tree as judges until a parity report passes and an A/B listen is signed off.

  3. Measurements redesign it

    The first full run found mono noise 3–5 dB low, 2 ms envelopes 1.75 dB quiet, voices that would not die and a matrix scan eating a quarter of the time. Each became a fix.

  4. Reverse-engineer what shipped

    Two 1997 DOS intros by The Black Lotus ran under an x86 emulator until their music started. The rebuilt generator reproduces every sample byte for byte: 32 of 32, 66 of 66.

  5. Measure size, never guess

    Bare i686 probes, packed with squishy and xz, in six compile configurations. Per-module cost and ablation builds. Ideas that made the player bigger are written down too.

  6. Keep the music private

    Released tracks are used for testing on the machine and never committed. The repository holds patches and measurements, not other people's music.

clips

Watch it work

Short films rendered with HyperFrames from plain HTML, each built from real parameter names and measurements. The cards loop while they are on screen.

the whole reel · 85 s · rendered with HyperFramesno sound yet
01 · 14 s

One voice, six engines

The voice diagram assembles while osc1 cycles through its six types.

02 · 12 s

Fifteen into nine

Sixteen legacy effect names wire into nine kinds and become modes.

03 · 10 s

The build shrinks

The converter prints the features, and the size bar drops past the original engine.

04 · 12 s

Until both engines agree

Octave bands lock inside the tolerance, then the parity counters run up.

05 · 10 s

The 32-frame grid

Why a 2 ms hit read quiet, and how the grid tightens to 8 frames around it.

06 · 16 s

From 1997 to now

A DOS intro runs in an emulator until its music starts, and becomes an oscillator.

open it

Play it in your browser

The DAW the songs were checked in runs right here: the same synth compiled to WebAssembly, with the piano roll, every device panel and the mixer. Nothing to install, and nothing you do leaves your machine.

The unisynth DAW: arrangement with clips and automation lanes on top, the unisynth device panel with voice, filter and envelope blocks below.
unisynth /unisynth

Home of this page and the DAW build. The synth, the player and the converter move here next, out of the intro's working tree.

RustTypeScriptGPL-3.0-or-later
  • Read-only. Edit freely; Save downloads the song as a file, Import loads a packed song blob.
  • Bounce renders a song to WAV in the browser.
  • No GM bank. Instruments that use the Windows GM.DLS sampler play silent here.
  • Desktop browser with a keyboard works best.
fr210
greetings

Built on your shoulders

unisynth is a unification, not an invention. Every sound it makes was first made by someone else. These are the teams whose work it learned from, and a word to the coders and musicians in them.

WaveSabre

Logicoma

MIT · github.com/logicomacorp/WaveSabre

The phase-mod and subtractive voices, the GSM and GM.DLS samplers, eight effects, and the track, receive and sidechain model the whole player still uses.

to the codersYou open-sourced a full 64k synth with its tooling. We ported it line by line before touching anything, and your algorithms are still inside, bit for bit, as modes.

to the musiciansThe tracks written on WaveSabre were our test suite. Every parity number on this page was earned against your patches.

Tunefish 4

Brain Control

GPL-3.0 upstream · github.com/paynebc/tunefish

The spectral wavetable oscillator with unison layers, the rate envelopes, seven effect modes and the .tfm format.

to the codersThe wavetable oscillator is the most musical slot in the voice, and it is yours. Your engine was clear enough that our port matched on the first run.

to the musiciansYour patches are the reason the size table still has a yellow row. We are not done making your music smaller.

V2

Farbrausch

github.com/farbrausch/fr_public · v2redux as reference

The naive oscillator, feedback SVF and 4-pole filters, drive, frame envelopes and LFOs, the channel strip, the comb reverb, the look-ahead compressor, and Ronan, the speech synth.

to the codersV2 set the standard a generation of 64k synths measured itself against. Releasing the source let us learn it properly instead of guessing.

to the musiciansFifteen of your tracks pass parity. Ronan still talks.

mini-cauldron · 1997

The Black Lotus

analysis only · no source was available

The cauldron oscillator, the flanger comb and the wrap distortion, recovered from two DOS intros by running them in an emulator until the music started.

to the codersAbout 1.4 KB of x87 code made a whole soundtrack. We needed an emulator, a disassembler and a week to read it. Respect.

to the musiciansYour phrases are now playable instruments in a browser DAW, nearly thirty years later.

Screwdriver

Team210 / QM

qm210's WaveSabre fork

The curve distortion, now mode 1 of distortion.

to qmA fork that adds one good device is how a scene tool grows. It is in.

Also studied: 64klang (Alcatraz), Sointu, 4klang, Oidos and Clinkster, compared from source while choosing the base. Tools: libopenmpt, the unicorn emulator, capstone, Wine, libgsm, squishy and xz.