Auracle is a modular synthesizer you play in the browser. Pick between two sounds, and it learns what you like, breeds new sounds toward it, and shows you what it learned. Every sound is a patch you can open and change.
▶ Watch the launch film (1:38) · How Auracle learns what you like (1:49) · Under the hood (2:17) · The math (2:46) · The sound engine (2:49)
In your browser: https://auracle.alexnodeland.com/play/. It is free, with
no account and nothing to install, and your sounds and your taste stay in your
browser. Every push to main rebuilds the engine and redeploys it.
Offline: every release
comes with a ready-built web bundle. Unzip it, run python3 serve.py, and open
the address it prints. No Rust needed.
You need rustup and Node 22, the version in
.node-version.
git clone https://github.com/alexnodeland/auracle.git && cd auracle
make setup # the wasm target, wasm-pack, the test browser and git hooks, then the engine
make serve # http://localhost:8642make setup is idempotent: run it again after pulling. Open
http://localhost:8642, let the pool fill, and play from your computer keys
(a w s e d f t g y h u j …), a MIDI keyboard, or the keys on screen. Press
? in the app for the key map and gestures.
- The guide: playing it. The four views, teaching it your taste, reading what it learned, the key map, accessibility, and troubleshooting. Start at your first session.
- The reference: how it works, with the math. The grammar, the audition, the features, the taste model, the search, and the safety layers, with the design decisions and rustdoc for every crate.
docs/: for contributors. Architecture notes, decisions (ADRs), proposals, plans, and runbooks.
Sound design usually means a choice. Presets are fast, and nothing you hear today helps tomorrow. Patching from scratch goes deep, slowly. Auracle grows: it keeps what you teach it, across sessions, and breeds toward it.
| Idea | What it gives you |
|---|---|
| Every sound is a term in a typed grammar (a probabilistic context-free grammar over quiver modules) | Every sample, mutation, and hand edit is a valid, playable patch by construction |
Breeding is typed Metropolis–Hastings toward a Boltzmann target, π(x) ∝ p_grammar(x) · exp(β·u(x)), through fugue-evo |
The grammar supplies parsimony, your taste supplies direction, β is one dial between them, and locked knobs give exact conditional refinement |
| Taste is a max of linear experts, with its own posterior | One player can love several unrelated kinds of sound; the model names them as styles, shows how sure it is, and guesses each pick before you make it |
| The instrument and the search share one compiler | What you play is the same patch that was bred, vetted, and measured |
- Play it. Four voices of polyphony in an AudioWorklet; your computer keys, the keys on screen, or Web MIDI (velocity, pitch bend, sustain); an arpeggiator, glide, and unison; every sound loudness-normalized; WAV recording of your playing; and sound changes that keep held chords ringing.
- Open it. Every knob is a trace address. Turning one writes the running voices' parameters (no recompile) and the genome. Rewire by dragging typed jacks; a structural edit is a grammar operation, so an edit always leaves a playable patch. Undo and redo, and locks per knob and per module.
- Forty-five modules. Seven sources (a wavetable, a physically modeled pluck, a formant oscillator, and AUDIO IN, your own input, among them), twenty-two processors (CAPTURE, which records into the sound, among them), and sixteen modulators. Seven processors take two inputs: a mix and a ring modulator that merge two chains into one; a compressor, ducker, gate, and vocoder whose second input is a control, so sidechaining lives in a typed tree; and TRACK, which plays its first chain from the pitch of its second. Nearly all of them carry a modulation slot with a named destination, the oscillators included, where it bends pitch.
- Modulation chains. A cable can carry
s&h rand → quantize → slewbefore it reaches a cutoff, with a depth bound so the grammar's parsimony still applies. The module rail shows what each module does to a signal, where it can go, and, only where the evidence supports it, what the model has learned about it.
- It learns from picks, stars, and edits. Bradley–Terry picks and ordinal stars feed one max-of-experts posterior, whose number of styles grows with the evidence. It guesses each pick before you make it and shows how often it was right; styles can be named, and keep their color everywhere; older picks fade with a recency half-life. A keep/kill likelihood is fitted too: a cut in the bank records a kill once its undo window closes.
- It breeds toward your taste. EVOLVE POOL runs one generation: a short
local Metropolis–Hastings walk from each of the sounds it rates highest, on
the Boltzmann target (the pool moves uphill on
π_β; it is not sampled from it), with the grammar's proposal weights tilted by what it has learned about structure. Lock what you love in PATCH, and ⚡ EVOLVE FROM THIS walks everything else. - It keeps your session. The whole session (the bank, names, the taste log, lineage, and style names) saves itself to IndexedDB. Taste profiles and single patches download as files you can share.
Two loops share one record of what you taught it. The breeding loop runs when you press EVOLVE POOL: each generation renders and rates hundreds of candidate sounds against what the model has learned, with no one listening, and keeps only the few that earn a place in the pool. The taste loop moves only when you pick.
flowchart TD
subgraph patch["breeding loop · machine-paced"]
prior["grammar prior"]
vet["render · vet · measure φ"]
pool[("pool")]
refine["MH walk toward π ∝ p·exp(βu)"]
prior --> vet
vet --> pool
pool --> refine
refine --> vet
end
subgraph taste["taste loop · human-paced"]
pair{{"which would you reach for?"}}
log[("observation log")]
post["posterior · u = maxₖ θₖ·φ"]
pair -->|"picks · stars · edits"| log
log --> post
end
pool -->|"pairs dealt at random"| pair
post -->|"θ tilts the proposals"| refine
The reference takes both apart.
| Crate | Role |
|---|---|
auracle-grammar |
The typed grammar over quiver combinator terms; the term ⇄ trace codec; the term → Patch compiler with live parameter handles; structural edit operations; presets |
auracle-features |
Deterministic phrase rendering, the vetting gate, BS.1770 LUFS normalization, and the audio and structural features (φ) |
auracle-taste |
The max-of-experts utility, three likelihoods, recency weighting, the MCMC posterior, label alignment, and portable profiles |
auracle-session |
The two-loop engine: the pool, dealing pairs (at random by default; BALD selectable), locked refinement, taste-tilted proposals, and session persistence |
auracle-wasm |
WasmEngine (the worker's engine) and LivePoly (the worklet's instrument) |
apps/web |
The instrument: PERFORM, PATCH, EVOLVE, TASTE and LEARNING as levels of one space, the bank, the keyboard dock, and MIDI |
Auracle builds on quiver-dsp
(patch-graph DSP), fugue-ppl, and
fugue-evo (evolution as Bayesian
inference), all from crates.io.
While the version is 0.x, the public API and the save format may change between commits. Sessions written by older builds are migrated on load, but migrations are code: ⋯ → Download your taste before updating is the only backup there is. See Your data.
make check # the CI gate: fmt-check, clippy (-D warnings), app syntax, dev-check, wasm32, and the tests
make test # cargo test --workspace --profile test-fast (the DSP tests need optimized code)
make fmt # rustfmt
make lint # clippy
make help # every target, with what it doesThe site:
make site-tools # install the pinned doc toolchain, once
make site # build all four sections into site/
make site-serve # http://localhost:8643
make site-check # every link, asset, and anchor must resolvemake film-setup adds what the films need: the voice's Python environment and
models, the film tools, and the shared sound.
In the repo:
CONTRIBUTING.md: working on Auracle. The layout, the workflow, the quality bar, the sharp edges, and cutting a release.AGENTS.md: the working rules for coding agents and people, one file per area of the repo, each linking deeper.www/README.md: how the site is assembled, and the things about it that fail quietly.www/brand/: the mark, the lockups, the icon set, andvoice.md, the rules for every word Auracle says. The full spec is at/brand/.apps/web/README.md: the web app's architecture (the worklet, the worker protocol, the node bank) and its design system.www/video/README.md: how the films are made, from script to site, with every tool.CHANGELOG.md: what changed, release by release.
Contributions are welcome: see CONTRIBUTING.md, and run
make check before opening a pull request.
MIT; see LICENSE.
© 2026 Alex Nodeland.

