README from GitHub, AGPL-3.0
War Bells
War Bells is a granular-sampling / delay / looping multi-effect module for the
Ableton Move, built on the open-source Schwung
framework. It is a hand-written C audio_fx plugin: eleven effects across four families,
forty-four variations, four grain envelopes, a Hold sampler, a four-mode stereo reverb with
shimmer, a resonant low-pass filter, pitch modulation, scale-locked pitch, a tempo-synced
Motion mod-LFO, a generative Evolve/Dice engine, input-ducking, a 60-second phrase looper,
eight character presets, and a 16-slot user-preset bank that saves your sounds and their loops.
🎛️ Interactive manual & live demo → · 💬 Discuss on the Schwung Discord →
The effects
Eleven effects in four families, each with four named variations:
| Family | Effects | Character |
|---|---|---|
| Loops | Glide · Seq · Stack | layered short loops at different speeds — rhythms & octaves |
| Grains | Cloud · Drone · Chain | clouds of tiny fragments — washes, drones, textures |
| Glitch | Arp · Cutup · Chop | real-time rearrangement — stutters & bursts |
| Delays | Taps · Warp | a stereo multi-tap delay line — rhythmic, filtered, pitched, ping-pong echoes |
Each effect's four variations have their own short labels (e.g. Stack → oct+ / oct- / x2 / range, Taps → line / swng / trip / wide).
Controls
War Bells is a standard Schwung audio_fx module. The host renders menu pages and maps
the 8 knobs per page; metadata is served from the plugin (chain_params + ui_hierarchy)
so every parameter is editable on the device.
- Root — Preset · Effect · Variation · Activity · Repeats · Rv Tone · Mix · Space · Filter
- Tone — Shape · Resonance · FX Vol · Grain Env (Soft / Pluck / Swell / Gate) · Scale (Off / Maj / Min / Pent / Oct / 5th)
- Time — Clock (Free / Sync / Manual) · Subdivision · Tempo
- Space FX — Reverb (Room / Dark / Hall / Vast) · Shimmer (Oct± / 5th) · Width · Mod Depth · Mod Rate
- Motion — Mod Dest (Act / Filt / Space / Mix / Mod) · Rate (8 bar…1/8) · Depth · Wave
- Generate — Evolve · Range (Soft / Mid / Wild) · Dice
- Perform — Reverse · Hold · Hold Mode (Latch / Gate) · Duck
- Looper — on/off · Transport · Reverse · Level · Fade · Speed · Route · Quantize
- Looper 2 — Fade shape · Record order · Looper-Only · Burst
- User Slots — User Slot (1–16) · User Op (Save / Load / Del)
- Config — Input (Stereo / Mono) · Input Gain · Bypass · Bypass Mode (Buf / Trail / True)
The macro knobs Activity, Repeats, Mix, Space, Filter (and Shape, on the Tone page) re-interpret per effect. Activity = more/less of the effect's thing; Repeats = how long it rings on. Rv Tone is a bipolar reverb shaper on its own root knob: centre = flat, turn down to high-pass the tail (thins the lows / tames ambient low-end build-up), turn up to low-pass it (darker, warmer). It filters the reverb send, so it stops mud at the source.
Timing
Timing defaults to Free — a free-running internal tempo that drifts gently, so the rhythmic engines breathe rather than lock metronomically (a free-running, never-quite-locked feel). Sync locks hard to the Move's host clock; Manual holds a fixed BPM. Onset-driven effects (Arp, Chain) also trigger from audio transients and MIDI note-ons.
Saving your sounds
- Character presets — the
Presetrow sets the effect + all macros to one of eight curated starting points (Init, Erase, Edit, Chor, Shimr, Birds, Glass, Pad). - User-preset bank — on the User Slots page, pick a slot (1–16) and Save; it writes every parameter and the recorded loop to disk under the module folder. Load restores both; Del clears the slot.
- Whole-chain patches — War Bells serializes its full state, so a Signal-Chain patch saved via the Schwung Manager captures it too (parameters only — not the loop audio).
MIDI
Channel-wide CCs map the main controls (6 Activity · 7 Shape · 8 Filter · 9 Mix · 11 Repeats · 12 Space · 20 Reverb · 33 Rv Tone · 22 Looper · 28–35 transport · 47 Reverse · 48 Hold · 102 Bypass, plus more). Program Change selects effect + variation directly (effect = PC ÷ 4, variation = PC mod 4).
Web control
War Bells ships a custom web UI (web_ui.html) — believed to be the first Schwung module to
do so. It's dual-purpose:
- Interactive demo + manual on GitHub Pages — the synth panel runs as a simulation alongside the docs (live device control is disabled there because a browser can't open an insecure socket from an https page).
- Live controller when opened from the Move (an http origin), with War Bells in a chain
slot:
http://move.local:7700/api/remote-ui/module-assets/war_bells/web_ui.html. It connects to the Schwung Manager WebSocket, finds War Bells in your slots, drives the DSP, and reflects hardware-knob moves back into the page.
How it works
in -> input gain/mono -> capture ring (frozen by Hold)
-> 6 granular voices + multitap delay -> wet
MIX(dry,wet) -> chorus(pitch-mod) -> SPACE(delay + reverb) -> resonant LP filter
-> looper (thru + base/overdub) -> bypass crossfade -> out
All DSP is hand-written, realtime-safe C (header-only primitives in src/dsp/core/):
windowed granular voices over a rolling live-input buffer (grain.h, four envelope shapes),
a 4-tap delay with a pitch shifter (multitap.h, pitchshift.h), a chorus (chorus.h), a
Schroeder–Moorer reverb with four mode presets (reverb.h), a TPT state-variable resonant
filter (svf.h), a two-buffer 60-second looper (looper.h, WAV save/load), and an onset
detector (transient.h). The per-variation "brain" lives in effects.c.
Install (no build required)
You do not need to compile War Bells — install it through the Schwung Manager
(http://move.local:7700 → Modules):
- From the catalog (once listed — see below) — find War Bells under audio FX and tap Install. One tap; auto-updates when a new release ships.
- Custom → from GitHub URL — paste
seajaysec/war-bells. The Manager readsrelease.jsonand pulls the correct tarball from the latest GitHub Release. - Custom → from file — download the
war_bells-module.tar.gzasset from the latest Release and upload it.
⚠️ Use the
war_bells-module.tar.gzasset, not GitHub's auto-generated "Source code (tar.gz)". The source archive keepsmodule.jsonundersrc/, so the Manager reports "No module.json found in tarball." The packaged asset has the right layout (war_bells/module.json).
Building from source is only for development:
bash scripts/run_tests.sh # host-side C tests (native cc)
bash scripts/build.sh # cross-compile war_bells.so (aarch64) + tarball
MOVE_HOST=ableton@move.local bash scripts/deploy-dev.sh # sideload to a Move
See INSTALL.md. The shared object is war_bells.so and exports
move_audio_fx_init_v2 (audio_fx ABI v2). requires_continuous_processing keeps the
granular / looper / delay state alive through silence.
Status
DSP is verified by tests/test_smoke.c: dry passthrough is unity, all 44 variations render,
the looper records / plays / overdubs / undoes / erases / saves / loads, character presets and
the user-slot bank round-trip (params and loop audio), Hold↔Looper exclusivity holds, and
state / chain_params / ui_hierarchy serialize cleanly. The aarch64 .so cross-compiles
clean and exports the entry symbol. Final analog voicing is tuned on-device.
License & credits
War Bells is released under the GNU Affero General Public License v3.0 © Chris Farrell. Because it's served over a network (the web UI), AGPL §13 applies — the in-app footer links back to this source.
It links the Schwung host ABI: src/host/audio_fx_api_v2.h and src/host/plugin_api_v1.h are
redistributed unmodified from Schwung (MIT ©
Charles Vestal) — see THIRD_PARTY.md. The reverb is adapted from the
public-domain Freeverb (Jezar at Dreampoint). Documentation is illustrative.