README from GitHub, MIT
Amino
Amino is an 8-bit wavetable synthesizer for Ableton Move, running as a sound-generator module in Schwung. Up to four layers, each with two stepped 8-bit wavetable oscillators, dirt noise, drive, a gritty multimode filter, four envelopes, two LFOs and an eight-slot modulation matrix, plus two multi-effect slots and 324 original presets, all playable from Move's knobs and pads.
- Play it in your browser: https://klaine.github.io/amino/ (the same DSP compiled to WebAssembly, with WebMIDI)
- Listen to every preset: preset gallery (all 324, with audio previews)
- Download for Move: latest release
- Every page and knob: docs/04-parameter-reference.md
- What changed: release notes
Amino takes its sound from 8-bit wavetable synths such as Waldorf's Protein and Microwave. It is not a Waldorf product and is not affiliated with Waldorf, and it contains no Waldorf code, firmware, wavetables or presets. Its 74 wavetables are generated by its own scripts or built from CC0 waveforms; see THIRD_PARTY_NOTICES.md and docs/07.
Installing on Move
Amino needs a Move with Schwung installed.
- Download
amino-module.tar.gzfrom the latest release. - Install it with Schwung Manager, or by hand: extract the archive so that it lands at
/data/UserData/schwung/modules/sound_generators/amino/on the Move. - Rescan modules in Schwung Manager, or restart Schwung.
Amino then appears under Sound Generators as AMNO.
Developers with SSH access (add a key at http://move.local/development/ssh) can install a local
build with scripts/deploy.sh [host]. It stages the package on the Move's data partition and
renames it into place, so a running Schwung is not disturbed. scripts/logs.sh follows Schwung's
debug log.
How it works
Each voice of each layer runs this path, and each layer goes to the output dry or through an effect slot:
flowchart LR
subgraph voice [Each voice]
O2[Osc 2] -.->|PM / AM / Sync| O1[Osc 1]
O1 --> MIX[Mix]
O2 --> MIX
DIRT["Dirt (noise, or Osc 1 × Osc 2 ring)"] --> MIX
MIX --> DRV["Drive (before or after the filter)"] --> F[Filter] --> VCA["VCA + pan"]
end
VCA --> BUS["Layer bus (up to 4 layers)"]
BUS -->|Dry| OUT([Out])
BUS -->|FX 1 × send| FX1[FX 1]
BUS -->|FX 2 × send| FX2[FX 2]
FX1 -->|Parallel| OUT
FX1 -.->|Serial| FX2
FX2 --> OUT
Everything below is on Move's parameter pages and in the Remote UI.
Oscillators
Two wavetable oscillators per layer. Each of the 74 tables holds 64 waves of 128 signed 8-bit samples; waves 61 to 63 are a triangle, a square and a saw in every table. In Vintage mode the samples play without interpolation at 4× oversampling, so the stepping and aliasing of 8-bit hardware come through. Clean mode plays band-limited copies instead, for pads and smoother sounds.
Each oscillator has Table, Wave (the position in the table, which envelopes, velocity, the matrix and aftertouch can sweep), Semi, Fine, Level, a Wave Env amount, velocity to wave and key tracking. Osc 2 can Link to Osc 1's table and position, and cross-modulates Osc 1 by PM, AM or Sync.
Dirt, drive and filter
Dirt mixes noise in before the filter: Static, Crackle, Geiger, Click or Burst, or Ring for ring modulation of the two oscillators. Drive (Transistor, Tube, Diode or Fold) sits before or after the filter. The filter is a saturating four-pole cascade with LP24, LP12, Ladder 24dB, HP24, HP12 and BP12 modes, or Off, where drive alone shapes the sound. It takes an envelope amount, key tracking up to 200 % and velocity.
Envelopes and modulation
- Four ADSR envelopes per layer: Wave, Filter, Amp and Aux, which drives two destinations of its own.
- Two LFOs with seven shapes (Sine, Tri, Pulse, Saw Down, Saw Up, Random, S&H), free or synced over 14 divisions from 1/32T to 16 bars, Free, Voice or Global phase, fade-in, and mod wheel depth.
- Modulation matrix of eight slots, each with a source, a destination, an amount and a "via" source that scales it. 26 sources (the envelopes, LFOs, velocity and release velocity, key, poly and channel aftertouch, mod wheel, breath, foot, expression, bend, MPE timbre, sustain, random, voice number, layer alternation and more) reach 25 destinations.
- Aftertouch has knobs of its own for wave, cutoff and vibrato, so Move's pressure-sensitive pads do something without touching the matrix.
- Flavour gives every note small random offsets to wave position, pitch, envelope times and cutoff, so repeated notes are never quite identical.
Layers
Up to four layers, each a complete voice setup with its own volume, pan mode, effect route and send. The Layer Mode decides which layer plays a note: Stack (all of them), Round Robin, Random, Key Split (each layer has a key range) or Channel (layer N listens on MIDI channel N, for external controllers). Layer Tools copy one layer to another, and Load Layer takes a layer from any factory preset.
Effects
Two stereo slots, in series or in parallel. Each layer goes to them dry, into FX 1 or into FX 2, with its own send. Each slot runs one of:
| Type | Controls |
|---|---|
| Chorus | Rate, Depth, Delay, Feedback, Spread, Mode |
| Flanger | Rate, Depth, Feedback, Delay, Spread, Sync |
| Phaser | Rate, Depth, Feedback, Stages, Centre, Spread |
| Tremolo | Rate, Depth, Shape, Sync, Stereo, Phase |
| Drive | Gain, Tone, Curve, Output, Low Cut, Crush |
| Comp | Threshold, Ratio, Attack, Release, Make-up, Knee |
| EQ | Low, Mid, Mid Frequency, High, Q, Low Cut |
| Delay | Time, Sync, Feedback, Tone, Ping-Pong, Modulation |
| Reverb | Size, Decay, Damping, Pre-delay, Modulation, Width |
| Shimmer | Size, Decay, Damping, Shimmer, Interval, Modulation |
| Trance Gate | Pattern, Grid, Attack, Release, Length, Floor |
Voices and playing
Eight voices by default and up to sixteen, shared by the layers. Each layer plays Poly, Mono or
Legato with glide and an octave shift, and can lock to a Scale (Set follows the Move set's
scale; or Major, Minor, the modes, pentatonics, Blues, Chromatic) or play a Chord from one key
(Major, Minor, 7, Maj7, m7, sus2, sus4, fifth, octave, or four octaves stacked). Amino responds to
velocity and release velocity, pitch bend, polyphonic and channel aftertouch, the mod wheel,
breath, foot, expression and the sustain pedal, and to MPE. There is no arpeggiator: pair Amino
with Schwung's arp MIDI FX or Move's sequencer.
Presets
324 original presets in one factory bank, sorted by category. Each name starts with a two-letter tag so the list is easy to browse on Move's display:
| Tag | Category | Tag | Category |
|---|---|---|---|
IN | Init (2) | KY | Keys (43) |
BS | Bass (52) | PL | Plucks (48) |
LD | Leads (52) | FX | Effects (39) |
PD | Pads (51) | DR | Drones (19) |
ML | Multi-layer (18) |
The bank is level-matched, so switching presets doesn't jump in volume. IN Init is a plain
starting point.
On Move
Amino's pages are grouped as Move shows them: Main (cutoff, resonance, both wave positions, filter envelope, attack, release and flavour), Presets (Presets, and Category, which picks the category Presets steps through), Oscillators (Osc 1, Osc 2, Wave Env), Filter & Amp (Mixer, Filter, Amp, Aux Env), Play (Play, Voice), Modulation (LFO 1, LFO 2, Pad Matrix, Mod 1-2 to Mod 7-8), Effects (FX, plus a page for each slot's current effect), Layers (Layers, Layer Mix, Layer Route, Key Split, Layer Tools) and Tools (Init, Randomize, Load Layer). Layer pages edit the layer chosen on the Layers page. Every page is eight knobs, and the whole synth is at most two jog steps away. docs/04 lists every parameter with its range and default.
Presets are saved and automated through Schwung like any other module. The Remote UI, served by Schwung in a browser, lays the synth out in signal-flow order instead of eight-knob pages: each wavetable drawn as a waterfall you drag across, the filter's response with its envelope sweep, envelope editors, modulation rings on every knob (drag a source chip onto a knob to route it) with animated cues, LFO previews, layer strips with a key-range editor, the effects routing, a help panel, undo and redo, A/B compare, an on-screen keyboard, and a preset browser with categories, banks and favourites.
Playing in the browser
https://klaine.github.io/amino/ is the whole synth as a single page: the Remote UI plus the same DSP compiled to WebAssembly. Click Start Amino, then play from a WebMIDI keyboard (Chrome, Edge or Opera; Safari has no WebMIDI), from the computer keys A to K (Z and X shift the octave), or from the on-screen keys (a phone gets one octave of larger keys). MIDI channels → layers gives each layer Omni, Off or its own channel. A BPM box and a Transport switch drive the synced LFOs and delays. Your sound is kept in the browser and restored on the next visit.
Building from source
Requirements: zig (brew install zig) and Python 3. Native tests use the
system cc; AGENTS.md covers Windows.
scripts/build.sh
This runs the contract, native, UI and golden tests, then writes
modules/sound_generators/amino/ (the module directory, with dsp.so) and amino-module.tar.gz.
Other targets:
scripts/build.sh --gen # regenerate first, after editing params, presets or src/ UI files
scripts/build.sh --profile # dsp.so with a read-only cpu_us key (render time)
scripts/build_web.sh # browser build: build/site and build/amino.html (run --gen once first)
scripts/deploy.sh [host] # install the build on a Move over SSH
python3 tools/remote_ui/dev_server.py # the Remote UI on http://localhost:7700, no Move needed
build/amino.html is the browser synth as one self-contained file (about 1.7 MB) that opens from
disk. tools/gen/params.py defines every parameter, and gen.py writes the C tables, the
contract and most of the module directory from it, so edit the src/ copy of a UI file, never
the one in modules/. The golden test renders all 324 presets and fails if any of them changes its sound.
See CONTRIBUTING.md before opening a pull request.
Design documents
Amino was specified before it was built, and docs/ keeps that spec alongside notes on what was
built:
| # | Document | What it answers |
|---|---|---|
| 01 | Product requirements | What Amino is, for whom, scope per release |
| 02 | Move & Schwung platform constraints | What the host gives and what it forbids |
| 03 | DSP architecture | Layers and voices, oscillators, filter, modulation, effects, CPU budget |
| 04 | Parameter reference | Every parameter key, range, unit, default and short label |
| 05 | UX & Move control design | Page plan, knob maps, layer workflow, display, gestures |
| 06 | Presets & state | State blob, factory bank, layer copy and load |
| 07 | Wavetables & IP | Wavetable format, where the tables come from, legal guard-rails |
| 08 | Roadmap & test plan | Milestones, repo layout, verification, risks, decisions |
| 09, 10, 13, 14, 16, 17 | Nostalgia, Modern, genre sets, Expansion, Trance Gate, Expansion II | How the factory presets were designed |
| 11 | Effects | The effect types, routing, parameters, CPU and memory |
| 12 | Preview rendering & Python tools | Rendering the preset gallery with the C engine; the frozen Python emulator |
| 15 | Implementation notes | What was built, the Remote UI and browser build, build and test details |
| 18 | Preset polish | Expression and level across the factory bank |
Status
Amino is stable and runs on Move. Known limits:
- Two effect slots, as on the hardware it is modelled on. Add Schwung audio effects after Amino for more.
- Effect parameters are not matrix destinations (a layer's send is), though Schwung's automation, scenes and chain LFOs can move them.
- No arpeggiator, by design (see above), and no user wavetable import yet.
Bug reports and ideas are welcome as issues.
Project layout
| Path | Contents |
|---|---|
src/dsp/ | The engine: layers and voices, oscillators, dirt, drive, filter, envelopes, LFOs, matrix and effects (*_gen.c are generated) |
src/module.json, ui_chain.js, cards.js, help.json | Manifest and on-device UI, copied into the module directory by gen.py |
src/web_ui.html, src/web/ | Remote UI |
tools/gen/ | params.py (every parameter) and gen.py (C tables, contract, factory bank, module directory) |
presets/factory/ | The 324 factory presets as JSON |
tools/wavegen/ | Wavetable generator: procedural recipes plus AKWF-FREE |
modules/sound_generators/amino/ | The module directory, mostly generated |
web/ | Browser build: WebAssembly host, AudioWorklet, MIDI routing, single-file bundler |
tests/ | Contract validator, native tests, golden audio for every preset, web UI tests |
tools/remote_ui/ | Remote UI development harness |
tools/emulator/ | Preset gallery renderer, and the frozen Python emulator |
docs/ | Design documents |
The module does no file I/O and no heap allocation in its audio callbacks.
License
MIT, see LICENSE. Wavetables built from AKWF-FREE are CC0 1.0, and Schwung's API header and set-info reader are MIT; see THIRD_PARTY_NOTICES.md. Schwung and Ableton Move are separate projects under their own licenses.