algo-drum

module
v0.0.0-...-d5534e6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 9, 2026 License: MIT

README

algo-drum

An algorithmic drum machine running entirely in your browser. Try it live →

Built with a Go audio engine compiled to WebAssembly and a React UI. No plugins, no backend — just a .wasm file and a browser.

Features

  • 7 voices × up to 16 steps: Bass Drum, Snare, Hi-Hat, two independently tunable Toms, Cymbal, and metallic Percussion, with a runtime-adjustable pattern length (STEPS knob, 1–16)
  • Per-step velocity: click to cycle off → hit → accent, drag across cells to paint/erase, or Shift-drag / use Shift+Arrow to set a continuous level
  • Per-cell probability, centered humanize depth, 1–4-hit ratchets, and evolving trigger conditions (every 2nd/3rd/4th loop, first loop, fill-only, or when the previous step did not fire)
  • Independent 1–16-step track lengths for polymetric patterns, with a live Fill-mode performance control
  • Per-track volume (smoothed, zipper-free) and decay knobs, plus per-track mute
  • Tempo (30–300 BPM) and swing, with tap tempo
  • Global probability and humanize knobs act as master amounts over the per-cell controls; timing humanize is centered instead of only dragging late
  • Four rhythm banks (A–D), clean loop-boundary queueing, complete-bank copy, and a programmable looping 16-entry pattern chain
  • Pattern mutate, per-track Euclidean fill, per-row clear/rotate/copy tools, Clear, undo/redo, and 6 built-in presets
  • A dry quarter-note metronome plus a saved one- or two-bar 4/4 count-in
  • Global reverb control
  • Shareable patterns: state round-trips through a URL hash and localStorage, so reloading or sending a link restores the pattern, tempo, and knobs
  • Keyboard-accessible: Space controls playback; S stops, M mutates, 1–7 mute the visible rows, P/Shift+P cycle presets, Shift+Backspace clears, and ? opens the complete shortcut reference. F2 opens a cell's probability, humanize, ratchet, and condition inspector; pattern undo/redo uses the standard shortcuts, and the knobs are ARIA sliders with full keyboard controls
  • Installable as a PWA: a web app manifest plus a service worker that caches the app shell, the WASM engine, and the audio worklet (a fully offline reload isn't guaranteed yet — the hashed JS/CSS bundle is not precached)
  • Runs entirely client-side

How it works

The audio engine is written in Go and compiled to WebAssembly. It runs inside a Web Worker, so rendering never blocks the UI; an AudioWorklet pulls rendered chunks from the worker over a direct MessageChannel and reports the audible sequencer step back to the UI playhead.

Go engine (WASM, in a Web Worker)  ──512-sample chunks──►  AudioWorklet  ──►  AudioContext  ──►  speakers
     ▲       │                                                  │
     │ edits │ authoritative EngineState snapshots              │ audible step/bank
     │       ▼                                                  ▼
React UI (TypeScript) ◄─────────────────────────────────── playhead

The synthesizer voices are purely procedural — no samples. Each voice uses an exponential amplitude envelope; tonal voices (Bass Drum and both Toms) add pitch sweep, the Snare, Hi-Hat, and Cymbal use filtered noise, and Percussion combines inharmonic oscillators with a short noise transient. The mix passes through a global FDN reverb and brick-wall limiter before reaching the browser. See docs/voices.md for the full per-voice synthesis recipe and parameter reference.

Experimental physical model

An independent, work-in-progress physical path contains a double-headed, cavity-coupled modal tom. It uses circular Fourier–Bessel modes, a passive damped/nonlinear state update, measured-range velocity-dependent stick contact, frequency-dependent loss, mode-dependent radiation, and a batter-side filtered microphone response. In the web demo, open either Tom voice's settings and select Physical — Experimental to A/B it against that track's algorithmic model. The two Toms keep independent model choices and physical parameter banks. Algorithmic remains the default, and older saved patterns and share links continue to select it.

The model itself lives in algo-tom, which algo-drum consumes as a module dependency. Everything about how it works and how far it can be trusted is over there: the modal solve, the nine-term matching objective, the offline fitting and measurement commands, the committed reference recordings, the working paper, and the evidence record in its docs/. It also has its own web demo, which draws the matching rather than describing it, and its own backlog — the open work on the model and on the objective is planned there, not in PLAN.md.

What is in this repository is the adapter that makes it a drum-machine voice: internal/drum/physical_tom.go, the knob bank's binding to tomparams, the UI that exposes the eighteen parameters, and TestPhysicalTomRenderIsBitExact — the digest that is the only assertion here that hears a change to the calibration. Bumping the algo-tom dependency is a change to the shipped sound until that test says otherwise.

Browser requirements

algo-drum needs a browser with:

  • WebAssembly support (to run the Go audio engine)
  • Web Audio API with AudioWorklet support (the engine renders audio in a Web Worker; an AudioWorklet consumes the rendered chunks on the audio thread)
  • A user gesture (e.g. pressing Play) to start the AudioContext — this is a standard browser autoplay restriction, not an algo-drum limitation

All current major desktop and mobile browsers (Chrome, Firefox, Safari, Edge) satisfy these requirements.

Building locally

Prerequisites: Go 1.25+, Bun

# 1. Build the WASM binary (outputs to web/public/)
bash scripts/build-wasm.sh

# 2. Start the dev server
cd web && bun install && bun run dev

The dev server serves the app at http://localhost:5173/algo-drum/ — Vite's base is /algo-drum/ to match the GitHub Pages path, and opening http://localhost:5173/ redirects there. WASM must be built before starting the frontend — the dev server serves web/public/ as static assets.

# Production build → web/dist/
cd web && bun run build

Deployment

GitHub Actions builds WASM + frontend on every push to main and deploys web/dist/ to GitHub Pages automatically. In repository settings, GitHub Pages should be configured with Source: GitHub Actions.

Directories

Path Synopsis
cmd
gen-voiceparams command
Command gen-voiceparams writes the TypeScript mirror of the engine's per-voice parameter table.
Command gen-voiceparams writes the TypeScript mirror of the engine's per-voice parameter table.
wasm command
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL