Reference
Manual.
A complete description of Brume's synthesis engines, modulation, effects, and Lua scripting surface.
Overview
Brume is a multi-timbral instrument built on a CM5 reference platform. It runs four synthesis engines across four independent parts, each with six voices of polyphony (24 total), an SVF filter per voice, dedicated modulation routing, and a shared effects chain. The entire interface runs on a 10.1-inch touchscreen.
The four engines correspond to four distinct approaches to electronic sound design: a dual-oscillator complex architecture with FM, AM, and wavefolding; an additive harmonic engine with spectral scanning; a triangle-core timbral engine with wave-multiplier shaping; and a granular engine that generates pitched clouds of micro-oscillator grains.
Character
Brume runs four synthesis engines with a shared voice tail (SVF filter, amp envelope, modulation router), so patches stay coherent across very different sources. Each engine has its own mechanism for continuous spectral change: cross-FM feedback in Complex, a scanning window in Harmonic, cascaded wavefolding in Timbral, grain scatter in Granular. No samples sit anywhere in the signal path; every voice is generated from live math.
The lineage worth naming is the Buchla 259 and Serge wavefolder tradition, the DX family’s phase-modulation surface, and the patch-on-a-small-computer approach of Norns and Plaits, rendered in software and unified under a single touchscreen. The default transition shape is Caffeinated, a pseudo-random walk, which sets the bias for the whole instrument: engines reveal themselves over tens of seconds rather than on first press, and loops rarely repeat quite the same way.
Interface
The top menu bar provides access to all pages: the four engine mode tabs (COMPLEX, HARMONIC, TIMBRAL, GRANULAR) on the left, and navigation pages (MOD, MIX, MIDI, SYS, LIBRARY) on the right. Tapping a mode tab selects that engine for editing on the synth page.
Signal path
Complex Oscillator
◆ Part 1 — Dual oscillator · FM · wavefold
The Complex engine pairs a carrier and modulator oscillator, both capable of continuous waveshape morphing from sine through triangle, sawtooth, and square. The modulator feeds into the carrier through several modulation paths — phase-modulation FM, amplitude modulation, ring modulation, through-zero FM, and hard sync — while a cross-FM feedback path returns the carrier's output to the modulator.
Interactive illustration rendered in the browser — the on-device DSP has more subtlety, but the parameter behaviours follow the same shape.
OSC tab — Oscillator waveforms and frequency relationship
| Parameter | Range | Default | Description |
|---|---|---|---|
| CARRIER | 0 – 1 | 0 | Carrier waveform morph. Sweeps continuously from sine (0) through triangle (0.33), sawtooth (0.66), to square (1.0). |
| MOD WAVE | 0 – 1 | 0 | Modulator waveform morph, using the same sine-to-square progression as the carrier. |
| RATIO | 0.5 – 16 | 3.0 | Frequency ratio of modulator to carrier. Integer values (1, 2, 3) produce harmonic spectra; non-integer values create inharmonic, bell-like tones. |
| FOLLOW | off / on | off | When enabled, the modulator tracks the carrier's pitch with the ratio applied as a Hz offset rather than a multiplier. |
MOD tab — Modulation paths
| Parameter | Range | Default | Description |
|---|---|---|---|
| FM INDEX | 0 – 10 | 2.0 | Phase-modulation FM depth. The modulator's output displaces the carrier's phase, producing sidebands whose density increases with depth. |
| X-FM | 0 – 1 | 0 | Cross-FM feedback. The carrier's previous output feeds back into the modulator's phase, creating a self-referential loop with chaotic character at higher values. |
| AM | 0 – 1 | 0 | Amplitude modulation depth. Produces tremolo at low modulator frequencies and spectral sidebands at audio rates. |
| RING | 0 – 1 | 0 | Ring modulation depth. Crossfades between the clean carrier and the product of carrier and modulator, producing sum-and-difference frequencies with a metallic character. |
| TZFM | 0 – 1 | 0 | Through-zero FM depth. Modulates the carrier's instantaneous frequency bidirectionally, allowing it to pass through zero Hz and invert. |
| SYNC | off / on | off | Hard sync. Resets the carrier's phase to zero whenever the modulator completes a cycle. |
Harmonic Oscillator
The Harmonic engine generates sound through additive synthesis, combining eight individually controllable harmonics with spectral shaping tools. A Gaussian scanning window sweeps across the harmonic series, isolating or blending partials as its center and width change.
SCAN tab — Spectral scanning and waveform morph
| Parameter | Range | Default | Description |
|---|---|---|---|
| CENTER | 0 – 1 | 0.5 | Position of the scanning window across the harmonic series. At 0 the window centers on the fundamental; at 1 it centers on the 8th harmonic. |
| WIDTH | 0 – 1 | 1.0 | Width of the scanning window. Intermediate values produce a Gaussian falloff from the center. |
| MORPH | 0 – 1 | 0 | Per-harmonic waveform morph. Coupled to the scan window — harmonics near the center receive more morph. |
| SPREAD | 0 – 1 | 0 | Phase randomization between harmonics. Thickens the sound without changing its spectral content. |
Timbral Oscillator
The Timbral engine starts from a triangle-wave core and shapes it through a wave-multiplier circuit that transitions from soft saturation to cascaded wavefolding as the timbre control increases. An expanded symmetry parameter tilts the triangle core before it enters the shaper.
SHAPE tab — Wave multiplier and feedback
| Parameter | Range | Default | Description |
|---|---|---|---|
| TIMBRE | 0 – 1 | 0 | Wave multiplier drive. At 0 the output is a pure triangle. From 0 to 0.3 a soft-clip saturator rounds the peaks; above 0.3 a triangle wavefolder blends in. |
| SYMMETRY | -1 – 1 | 0 | Triangle tilt and asymmetric bias. Positive values stretch the rising slope; negative values produce the inverse. |
| STAGES | 1 – 4 | 1 | Number of wavefolding stages. Each stage cascades another triangle-fold pass, densifying the harmonic spectrum. |
| FEEDBK | 0 – 1 | 0 | Self-modulation feedback. The oscillator's previous output sample modulates its own frequency, producing growling textures at higher values. |
Granular Oscillator
The Granular engine generates pitched clouds of micro-oscillator grains — short bursts of waveform output (1–500 ms) that overlap to produce evolving textures. Unlike sample-based granular systems, Brume synthesizes each grain from scratch.
CLOUD tab — Grain generation
| Parameter | Range | Default | Description |
|---|---|---|---|
| DENSITY | 0 – 1 | 0.3 | Grain spawn rate. Maps from 1 to 200 grains per second. Spawn timing includes a 30% jitter. |
| SIZE | 0 – 1 | 0.2 | Grain duration. Maps from 1 ms to 500 ms. Each grain's actual length varies by ±20%. |
| SCATTER | 0 – 1 | 0 | Pitch randomization per grain. At maximum, each grain's pitch is randomized within ±2 octaves of the fundamental. |
| SPREAD | 0 – 1 | 0 | Stereo pan randomization per grain. |
| DRIFT | 0 – 1 | 0 | Slow pitch random walk applied to the base frequency. Creates gradual, organic pitch wandering. |
SVF Filter & Envelope
Each voice includes a state-variable filter operating in lowpass mode, with a dedicated ADSR envelope that modulates the cutoff frequency. The filter and envelope parameters are identical across all four engines.
| Parameter | Range | Default | Description |
|---|---|---|---|
| CUTOFF | 20 – 20,000 Hz | varies | Filter cutoff. Smooth resonant rolloff above this frequency. |
| RESO | 0 – 1 | 0.1 | Resonance. Values near 1.0 produce self-oscillation. |
| ENV DEP | 0 – 1 | 0.3 | Envelope depth. Modulates cutoff above its static value. |
Modulation — LFOs & Step Sequencers
Each of Brume's parts has an independent modulation router with two LFOs and two step sequencers. These four sources can be assigned to any synthesis parameter through the MOD page.
Shape library · 24 transitions
Brume’s LFOs, step sequencer transitions, and modulation assignment response curves all draw from the same 24-shape library — ported from the Formfactor plugin. Each shape has a descriptive name (shown large) and its engineering enum name (shown below) for scripting and preset editing. The default shape is Caffeinated (ChaosHeavy), a pseudo-random walk chosen as the default because it’s the most musically surprising of the 24.
Mixer
The MIX page provides a four-channel mixer with horizontal faders for each part (Complex, Harmonic, Timbral, Granular), along with mute and solo controls. Each part’s level defaults to 0.8 and can be adjusted from 0 to 1. Each part also has independent delay and reverb send levels that control how much of the signal reaches the shared delay and reverb buses. A master volume control governs the final output level before the limiter. All level changes are smoothed to prevent clicks.
Effects
The EFFECTS panel on the MIX page provides four processing stages organized as tabbed controls: Saturator, Chorus, Delay, and Reverb. Saturator and Chorus operate as inserts on the dry master bus, processing all parts equally. Delay and Reverb operate as send effects, where each part’s independent send level controls how much signal reaches the effect. This architecture follows the model used in hardware instruments like the Elektron Digitone, where a dry bass line can coexist with a heavily reverbed pad without one treatment bleeding into the other.
Saturator
| Parameter | Range | Default | Description |
|---|---|---|---|
| TYPE | Soft / Hard / Tape / Tube | Soft | Saturation algorithm. Soft uses tanh waveshaping; Hard clips at ±1; Tape applies asymmetric soft clipping; Tube adds even harmonics via polynomial distortion. |
| DRIVE | 0 – 1 | 0 | Pre-gain into the saturation circuit. At 0 the signal passes clean; at 1 the input is boosted 5× before shaping. |
| MIX | 0 – 1 | 1 | Dry/wet blend. |
Chorus
| Parameter | Range | Default | Description |
|---|---|---|---|
| RATE | 0.1 – 5 Hz | 0.5 | LFO speed controlling the modulation of the internal delay lines. Left and right voices run at slightly offset rates for stereo width. |
| DEPTH | 0 – 1 | 0.3 | Modulation depth. Higher values produce more pronounced pitch variation and wider stereo field. |
| MIX | 0 – 1 | 0 | Dry/wet blend. |
Delay
The stereo delay supports both free-running millisecond timing and tempo-synced musical divisions. When a sync division is selected, the delay time auto-calculates from the transport BPM. The delay uses cross-channel ping-pong routing with a damping filter in the feedback path to darken successive repeats.
| Parameter | Range | Default | Description |
|---|---|---|---|
| SYNC | FREE / MIDI / 1/1 – 1/8t | FREE | Tempo sync mode. FREE uses the TIME slider directly. MIDI and the musical divisions (including dotted and triplet variants) derive the delay time from the current transport BPM. |
| TIME | 10 – 2000 ms | 300 | Delay time in free mode. Overridden when a sync division is active. |
| FEEDBACK | 0 – 0.95 | 0.3 | Amount of delayed signal fed back into the input. Values above 0.8 produce long, building repeats. |
| DAMPING | 0 – 1 | 0.3 | High-frequency rolloff in the feedback loop. At 0 the repeats stay bright; at 1 they darken rapidly, simulating tape degradation. |
| MIX | 0 – 1 | 0 | Dry/wet blend. |
Reverb
Four reverb algorithms are available, each built from networks of allpass diffusers and parallel comb filters with damped feedback. All algorithms share the same parameter set; the internal topology and delay lengths differ to produce distinct spatial characters.
| Parameter | Range | Default | Description |
|---|---|---|---|
| TYPE | Plate / Room / Hall / Spring | Plate | Plate (Dattorro): dense, bright, classic studio plate character. Room: shorter delays, clearer early reflections, intimate. Hall: long diffusion chains, expansive tail. Spring: allpass cascade with metallic chirp and resonant character. |
| PREDELAY | 0 – 200 ms | 20 | Delay before the reverb onset. Separates the dry signal from the reverb tail, preserving transient clarity at higher values. |
| DECAY | 0.1 – 8 | 2.0 | Reverb tail length. Controls the feedback coefficient in the comb filter network. Higher values produce longer, more sustained reverberation. |
| DAMPING | 0 – 1 | 0.4 | High-frequency absorption in the reverb tail. Low values produce bright, shimmering tails; high values simulate absorptive room surfaces. |
| MIX | 0 – 1 | 0 | Dry/wet blend. |
MIDI
Brume receives MIDI over USB from any class-compliant device — control surfaces, keyboards, sequencers — and from the Meridian USB-C bridge to a host DAW (see below). All sources feed the same engine in parallel, so a controller plugged into a USB-A port and the DAW’s MIDI output over Meridian both reach Brume simultaneously without any routing setup. DIN 5-pin gear connects through any class-compliant USB-to-DIN bridge (e.g. iConnectMIDI4+).
The MIDI page has three sections: channel routing on the left (a part-centric list where each part shows its assigned MIDI channel; tap the channel box to cycle through CH 1–16 or NONE), CC mapping in the middle (the LEARN workflow plus the list of persisted CC→parameter bindings), and the clock controls on the right. Multiple parts can share the same channel for layered playback, and a single channel can be reassigned at any time without stopping playback.
Note-off messages use a promiscuous release strategy: when a note-off arrives on any part, Brume also releases that note on all other parts. This prevents stuck notes when channel assignments change during a performance. MIDI CC messages 120 (All Sound Off) and 123 (All Notes Off) are recognized and release all active voices on the targeted part.
CC Mapping — LEARN workflow
The CC MAPPING panel binds incoming MIDI CCs to Brume’s synthesis parameters. Brume ships with sensible defaults — CC 1 → Filter Cutoff, CC 2 → Filter Resonance, CC 7 → Master Volume, CC 11 → Filter Envelope Depth, plus a few part-specific bindings — and the LEARN workflow lets you add or override any binding directly from the touchscreen. No keyboard required.
| Action | Behavior |
|---|---|
| Tap LEARN | Arms capture mode. The button glows orange and an inline card appears at the top of the binding list reading “LISTENING FOR MIDI CC… (turn a knob or tap LEARN to cancel)”. |
| Move a knob / fader | Capture is continuous — the card updates to show the most recent CH / CC / value, so you can wiggle the intended control and confirm Brume sees the right one. Useful when DAW transport sync is also emitting CCs in the background. |
| Pick a destination | The card’s DESTINATION grid lists every parameter for the part the captured CC’s channel routes to (or every FX-slot parameter when an FX target is picked). Tap one to select; it highlights in the part color. |
| Tap SAVE BINDING | Writes the binding and disarms capture. The new mapping takes effect immediately. |
| Tap CANCEL | Discards the in-progress capture without writing anything. |
| Tap RESET | Two-tap confirm. Wipes all CC bindings, FX bindings, and channel routing back to factory defaults. Use when an experiment goes sideways. |
~/.brume/cc-bindings.json on every change and reloaded at startup. The file is human-readable; advanced users who need keyboard-typed CC numbers (touchscreen-only LEARN doesn’t expose a number pad) can edit it by hand over SSH.
Transport & Clock
The CLOCK window on the MIDI page controls Brume's internal transport, which drives tempo-synced delay divisions and step sequencer timing. Three clock modes determine how the transport derives its tempo:
| Mode | Behavior |
|---|---|
| Off | Internal clock at the configured BPM. No MIDI clock is sent or received. |
| Master | Internal clock at the configured BPM. Brume sends MIDI clock (24 PPQN) to connected devices. |
| Sync | Brume syncs to incoming MIDI clock messages. The BPM is estimated from the tick interval and smoothed to avoid jitter. MIDI Start, Stop, and Continue messages are recognized. |
The BPM slider ranges from 20 to 300 and affects all tempo-dependent features: delay sync divisions, step sequencer beat triggers, and future arpeggiator patterns. When the clock is in Sync mode, the BPM display shows the estimated tempo from the incoming MIDI clock source.
Controllers
Brume supports external hardware control surfaces through two independent paths. Recognised surfaces are identified by their USB / ALSA port name on connect and get a built-in binding tailored to the actual Brume UI, with no configuration step. Any other MIDI controller can still be bound through the MIDI Learn flow on a CC-by-CC basis. The two paths coexist — a recognised surface does not block Learn from working on other controllers connected at the same time.
The tradeoff: a built-in binding covers the full surface out of the box but is fixed by the firmware; MIDI Learn is fully user-defined but scales one CC at a time. Power users can also reach the Lua scripting layer (see Extending Brume with Lua) to define per-CC behaviour that neither path provides.
Supported surfaces
The Korg nanoKONTROL2 is the shipped reference controller. Brume detects it on connect by matching the string nanoKONTROL2 in the ALSA port name, then routes its events around the MIDI Control Matrix directly to the UI, where a screen-follows binding maps every control to a current action. Because the binding follows what is on screen, switching engines or sub-tabs silently rebinds the knob row to the new visible parameters.
Full factory-preset mapping — CC numbers + per-control action
| Control | CC | Action |
|---|---|---|
| Top-row knobs 1–8 | 16–23 | First eight parameters of the currently-visible sub-tab on any engine. Tabs with fewer than eight params leave the higher knobs idle. Continuous value, no press edge. |
| Faders 1–4 | 0–3 | Mixer level for Complex / Harmonic / Timbral / Granular respectively. Mirrors the MIX page fader per strip; changes are reflected on the MIX page in real time. |
| Faders 5–8 | 4–7 | Reserved. |
| S buttons 1–4 | 32–35 | Exclusive solo toggle for Complex / Harmonic / Timbral / Granular. Pressing S on part N mutes the other three parts; pressing the same S again un-solos. Press edge only. |
| M buttons 1–4 | 48–51 | Per-part mute toggle. Press edge only. |
| S / M buttons 5–8, R 1–8 | 36–39, 52–55, 64–71 | Reserved. |
| Track ◄ / ► | 58 / 59 | Cycle active engine mode in menu-bar order (Complex → Harmonic → Timbral → Granular, wraps in both directions). Press edge only. |
| Marker ◄ / ► | 61 / 62 | Cycle the active engine’s sub-tabs (e.g. OSC → MOD → FOLD … on Complex). Press edge only. |
| Marker ◎ | 60 | Reserved. |
| Cycle | 46 | Reserved. |
| Transport (Play / Stop / Rec / FF / Rew) | 41–45 | Reserved. |
The Novation Launch Control XL 3 is a second planned reference surface (see the BOM entry on the landing page) and is in development. Once integrated it will expose a deeper mapping appropriate to its 24-encoder, 8-fader, 16-pad layout: each engine likely gets a full page of encoders with the Page Up / Down buttons handling tab switching, and the 16 pads become clip launchers or per-part arm targets. The detection hook will follow the same ALSA port-name pattern.
Bring your own controller
Any controller not in the recognised-surfaces list works through MIDI Learn on the MIDI page. Tap LEARN, turn a knob or press a button, then pick a destination from the binding card. Each binding persists until removed. Because Learn runs at the Control Matrix layer, it is completely independent of the engine on screen and of the recognised-surface path.
The flow has two states, both shown below on a cropped view of the CC MAPPING panel:
~/.brume/cc-bindings.json.~/.brume/cc-bindings.json on the device as part of the full Control Matrix. The file is written after each LEARN save, binding removal, or reset, and read at startup; a missing or malformed file is treated as “no bindings yet” (the defaults load and startup continues). The file is plain JSON, so it can be inspected or hand-edited for bulk operations — for example, exporting a working set of bindings for backup or sharing between devices.
To add a new recognised surface at the code level, three small edits cover it:
| File | Change |
|---|---|
crates/midi-io/src/lib.rs | In start_with_script_tx, extend the port-name match block that sets controller_kind. Add a case matching the new surface’s ALSA port name (substring, case-insensitive) and set a unique kind string such as "LaunchControlXL3". |
crates/ui-app/src/ui.js | In window._onControllerCc / window._onControllerNote, add a branch keyed on the kind argument. The screen-follows pattern (knob index → _tabParams[i]) is reusable; any extra controls follow the same structure as the existing nanoKONTROL2 branches. |
brume-web/docs.html | Add a mapping table under Supported surfaces for the new controller so users can see what every control does. |
The protocol layer (crates/app-protocol/src/lib.rs) already carries EngineToUi::ControllerCc and EngineToUi::ControllerNote with a kind field, so no additional message variants are needed for the common case of routing a new surface through the existing screen-follows logic. Custom behaviour that escapes the screen-follows model — a pad grid triggering chords, for example — is easiest to implement directly in the UI branch that handles that surface’s kind.
Meridian — USB-C to your DAW
A line you cross. Meridian is Brume’s integrated audio-and-MIDI bridge to a host computer — comparable in role to Elektron’s Overbridge for the Elektron range, but built on open USB class-compliant standards so it works on Mac, Windows, and Linux without proprietary drivers. A single USB-C cable carries 8-channel audio out, bidirectional MIDI, and MIDI clock simultaneously.
In a DAW, arm one or more audio tracks with Brume’s capture as the input, route MIDI out from a track to Brume’s MIDI port, and Brume behaves as a first-class external instrument just like a Prophet or Moog patched into a multi-channel audio interface — with the additional convenience that it’s all on a single cable.
Incoming notes, CC, and MIDI clock over Meridian are parsed identically to other MIDI sources — they flow through the channel map, respect CC bindings, and drive the Sync clock mode. Audio output is structured for multi-track DAW workflows by default.
Per-part stems (8 channels)
Each of Brume’s four parts writes its own dry mono signal to a dedicated stereo channel pair on the USB capture endpoint:
| Channels | Source |
|---|---|
| 1 – 2 | Complex (dry, pre-FX, mono duplicated to L/R) |
| 3 – 4 | Harmonic (dry, pre-FX, mono duplicated to L/R) |
| 5 – 6 | Timbral (dry, pre-FX, mono duplicated to L/R) |
| 7 – 8 | Granular (dry, pre-FX, mono duplicated to L/R) |
Stems are dry — no master saturation, chorus, delay, or reverb. The intent is that DAW users already have better plugin FX than anything Brume ships internally, and recording dry preserves total flexibility. Brume’s master FX chain still computes for the local monitoring path (HDMI / DAC) so your touchscreen monitoring still sounds finished, but the USB stems are clean. The SYS page includes a compact channel-mapping reference (Ch 1-2 • Complex / 3-4 • Harmonic / 5-6 • Timbral / 7-8 • Granular) so you can cross-check your DAW’s input picker without leaving the device.
The mapping between channel pair, Brume part, and the spatial label the DAW will display:
| Channel pair | Brume part — DAW spatial label |
|---|---|
| 1–2 | ● Complex — Front L / R |
| 3–4 | ● Harmonic — Front Center / LFE |
| 5–6 | ● Timbral — Back L / R |
| 7–8 | ● Granular — Front L / R of Center |
Use this when wiring input tracks in the DAW, or as the source of truth when performing the one-time channel rename to “Complex”, “Harmonic”, and so on. The same mapping is also available on the device itself in the SYS page, collapsed to save space.
Meridian expands in capability over firmware releases. Already shipped: 8-channel per-part stems, bidirectional MIDI with clock, the channel-mapping SYS reference. Active follow-ons: a USB-NCM virtual network interface for the brumectl companion CLI, optional stripping of the UAC2 Feature Unit so the macOS volume slider disappears for bit-perfect passthrough.
Library
The LIBRARY page provides preset storage and recall for each engine. Presets capture all oscillator, filter, and envelope parameters for a single part and are stored as JSON files on the device’s filesystem, organized by engine type. Mode tabs at the top of the library page switch between the Complex, Harmonic, Timbral, and Granular collections.
Tapping SAVE captures the current state of the active engine and writes it to disk using an atomic write-then-rename operation that survives unexpected power loss. Tapping a preset name in the list loads its parameters into the corresponding engine and switches the display to that engine’s synth page. Presets can be deleted with the × button beside each entry.
~/.brume/library/{complex,harmonic,timbral,granular}/
The preset format is versioned and uses optional fields for future expansion. Current presets store oscillator and filter parameters; future versions may include modulation scenes, effects chain state, and multi-part combinations without breaking compatibility with existing files.
System
The SYS page is Brume’s diagnostic and configuration surface. Every value on the page is read live from the running system — no hardcoded numbers. Plug in a different display, swap controllers, change sample rate, switch audio outputs, and SYS reflects it immediately. Sections are accent-colored: green = audio, cyan = MIDI, orange = system, magenta = display.
Audio Output
The audio-output section picks where Brume’s master mix lands. Brume enumerates every ALSA card on the device — the USB Meridian gadget, the HDMI output through the touchscreen speakers, any DAC hat, plus any USB audio interface plugged into a USB-A port — and renders one row per detected output. The active device shows in the section accent color with a filled dot and an “ACTIVE” label; alternate devices render below as tappable “OPTION” rows. Tapping an option tears down the current audio stream and reopens on the chosen device with a brief (~100–200 ms) silence gap. The choice persists to ~/.brume/settings.json and is restored at startup.
CHANNELS — Meridian stem → DAW spatial label
On-device recap of the mapping between the eight Meridian stems, their Brume part, and the spatial-position label Apple’s class-compliant UAC2 driver shows in the DAW. The full treatment lives in Meridian.
| Channel pair | Brume part — DAW spatial label |
|---|---|
| 1–2 | ● Complex — Front L / R |
| 3–4 | ● Harmonic — Front Center / LFE |
| 5–6 | ● Timbral — Back L / R |
| 7–8 | ● Granular — Front L / R of Center |
SAMPLE RATE shows the actual rate the audio backend opened the device at — 48 000 Hz on Meridian, HDMI, and any modern audio interface. FORMAT shows the engine’s internal sample format.
MIDI
DEVICE shows the connected MIDI input by its OS-reported name (e.g. nanoKONTROL2). PORTS lists every MIDI port currently feeding the engine, joined with “ + ” when multiple sources are attached — a USB control surface and Meridian’s f_midi endpoint commonly run side by side. With no MIDI device connected, both rows show “—”.
Hardware
Hardware diagnostics for the CM5 reference platform. TEMPERATURE reads from the CM5 thermal sysfs and updates once per second. MEMORY shows the in-use resident memory for the Brume process. UPTIME is system uptime since boot. ENGINE reports the configured polyphony layout (4 parts × 6 voices = 24 total).
Display
RESOLUTION is detected from the connected monitor at startup via GDK and used to compute the auto-fit zoom level — Brume is canvas-designed against a 1024×600 logical resolution and auto-scales to whatever panel you plug in (the reference 1920×1200 touchscreen runs at scale 1.875). FPS shows the animation frame-rate cap. TOUCH reads the connected touch input device’s OS-reported name — useful when troubleshooting input issues or confirming the touchscreen probed correctly at boot.
BRUME_UI_SCALE=2.0 in the environment before launching Brume. SYS’s RESOLUTION row still shows the panel’s native size; the override only affects the UI zoom multiplier.
Extending Brume with Lua
Brume embeds a Lua 5.4 scripting engine. Scripts are loaded from ~/brume/scripts/ and managed through the SCRIPT page.
API reference
-- Set any of the 52 synthesis parameters brume.set_param(part, name, value) -- Trigger notes; velocity is 0.0–1.0 brume.note_on(part, note, velocity) brume.note_off(part, note) -- Chord and scale helpers local notes = brume.chord(note.C4, "maj7")
Coroutine clock
clock.run(function() while true do brume.note_on(brume.TIMBRAL, note.C3, 0.4) clock.sync(1/4) -- wait a quarter note brume.note_off(brume.TIMBRAL, note.C3) clock.sync(1/4) end end)
cleanup() on the old version and init() on the new one.
Brumectl — companion CLI
brumectl is the host-side companion command-line tool for Brume. Everything the device can’t do for itself — flashing a blank CM5 from a raw eMMC state, probing live status, opening a maintenance shell, watching device vitals, pushing OS updates — lives here. It is a single Rust binary distributed alongside the instrument; you install it on the workstation you already use to power the device over USB-C. The status, shell, and watch verbs work on any Unix host; the flash wizard currently requires macOS (it shells out to diskutil and ioreg), with a Linux port planned.
The tool is scoped narrowly. It is not a general-purpose Raspberry Pi utility — every subcommand assumes the connected device is a Brume, and authorization is established by physical possession of the USB-C cable rather than any account or token. The default invocation drops into an interactive ratatui wizard for first-boot flashing; the other subcommands are one-shot SSH-backed probes designed to feel like local commands.
Commands
| Command | Status | Description |
|---|---|---|
| flash | shipped | Default subcommand. Interactive ratatui wizard that walks you through flashing a blank CM5 eMMC over rpiboot: gathers WiFi credentials, hostname, SSH public key; writes the image; seeds the boot partition; verifies post-boot. Requires sudo. |
| status | shipped | One-shot SSH probe that reports firmware version, kernel, uptime, memory and temperature, the Brume process state, and network interfaces (eth0 + wlan0). Falls back to ARP-scan discovery when mDNS resolution fails. |
| shell | shipped | Pass-through SSH shell to the connected device. Honours $BRUME_HOST and $BRUME_SSH_KEY as well as the global --host and -i flags. |
| watch | partial | Live three-panel ratatui dashboard: device vitals (working), console stream (stub), script watcher (stub). The console and watch panels light up once the device-side logging socket lands. |
| update | planned | Push a signed image bundle (Phase 2) or app tarball (Phase 1) to the connected device, with A/B slot management and rollback on boot failure. Channels: stable and beta. |
| logs | planned | Tail Brume’s journal or /var/log/brume.jsonl over SSH; will also feed the watch dashboard’s console panel. |
| config get / set | planned | Read and write user-facing config (WiFi, hostname, MIDI channels, audio routing) without a re-flash. |
| recover | planned | Force boot into the read-only recovery partition. Phase 2 only. |
| channel | planned | Switch update channel (stable / beta); each channel is gated by a separate signing key. |
| doctor | planned | Diagnostic mode — checks Audio MIDI Setup, USB-NCM enumeration, Meridian UAC2 endpoint visibility, and the like. |
Build & install
# From a clone of the brume repo cargo build --release -p brumectl # Resulting binary ./target/release/brumectl status
A Homebrew tap (brew install aftertonesignal/tap/brumectl) and direct GitHub release downloads are planned but not yet live. Until then the cargo build is the canonical install.
How it talks to the device
Brume exposes a USB Network Control Model (NCM) interface, so the moment you plug it into your Mac it appears as a USB-Ethernet peer with a stable link-local address and announces itself as brume.local over Bonjour on that interface only. Every brumectl subcommand other than flash is a thin layer over SSH to that address — no bespoke protocol, no API tokens, no pairing flow. The flash subcommand is the exception: it uses rpiboot to talk to the bare CM5 over USB mass-storage before any operating system is on the device, then hands off to SSH once the first boot completes.
brumectl never connects over WiFi or the open internet, never reads or writes credentials beyond the SSH key already on your Mac, and binds brume.local exclusively to the USB-NCM interface. If you can plug it in, you can manage it; if you can’t, you can’t.
End of manual · rev 0.9.2 · Aftertone & Signal