overdub

amino

klaine/amino · ★ 0

Waldorf inspired wavetable synth module for Ableton Move (Schwung) and browsers

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.

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.

  1. Download amino-module.tar.gz from the latest release.
  2. 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.
  3. 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:

TypeControls
ChorusRate, Depth, Delay, Feedback, Spread, Mode
FlangerRate, Depth, Feedback, Delay, Spread, Sync
PhaserRate, Depth, Feedback, Stages, Centre, Spread
TremoloRate, Depth, Shape, Sync, Stereo, Phase
DriveGain, Tone, Curve, Output, Low Cut, Crush
CompThreshold, Ratio, Attack, Release, Make-up, Knee
EQLow, Mid, Mid Frequency, High, Q, Low Cut
DelayTime, Sync, Feedback, Tone, Ping-Pong, Modulation
ReverbSize, Decay, Damping, Pre-delay, Modulation, Width
ShimmerSize, Decay, Damping, Shimmer, Interval, Modulation
Trance GatePattern, 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:

TagCategoryTagCategory
INInit (2)KYKeys (43)
BSBass (52)PLPlucks (48)
LDLeads (52)FXEffects (39)
PDPads (51)DRDrones (19)
MLMulti-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:

#DocumentWhat it answers
01Product requirementsWhat Amino is, for whom, scope per release
02Move & Schwung platform constraintsWhat the host gives and what it forbids
03DSP architectureLayers and voices, oscillators, filter, modulation, effects, CPU budget
04Parameter referenceEvery parameter key, range, unit, default and short label
05UX & Move control designPage plan, knob maps, layer workflow, display, gestures
06Presets & stateState blob, factory bank, layer copy and load
07Wavetables & IPWavetable format, where the tables come from, legal guard-rails
08Roadmap & test planMilestones, repo layout, verification, risks, decisions
09, 10, 13, 14, 16, 17Nostalgia, Modern, genre sets, Expansion, Trance Gate, Expansion IIHow the factory presets were designed
11EffectsThe effect types, routing, parameters, CPU and memory
12Preview rendering & Python toolsRendering the preset gallery with the C engine; the frozen Python emulator
15Implementation notesWhat was built, the Remote UI and browser build, build and test details
18Preset polishExpression 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

PathContents
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.jsonManifest 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.