// ZPWR-SYNTH — DOCS

GitHub

>_ZPWR-SYNTH

A patchable polyphonic synthesizer — wire modular oscillators (analog, wavetable, FM, additive, granular, physical), filters, envelopes and modulators into your own voice, in a cyberpunk WebView UI. There is no fixed signal path: a patch is the voice, instantiated across a polyphonic pool. Builds as AU, VST3, CLAP and Standalone on macOS (Apple Silicon / Intel) and Linux (x86_64 / aarch64). The module reference below is generated from the live module registry the plugin runs, so it never drifts from the build.

Overview

The whole synth is one modular patch graph. The graph engine is the shared zpwr-patch-core (libs/zpwr-patch-core, a git submodule) — the same signal-agnostic cable-routing core that powers zpwr-fx. A patch — a grid of DSP nodes wired by per-input source selection — is the voice, instantiated across a polyphonic pool.

It is a fully modular instrument in the lineage of VCV Rack, Cherry Audio Voltage Modular and NI Reaktor Blocks: you build the entire voice by wiring DSP blocks with cables.

Part of the MenkeTechnologies audio stack alongside zpwr-fx, zpwr-midi-fx, and zpwr-patch-core.

Formats & Platforms

Builds as AU, VST3, CLAP and Standalone on macOS (Apple Silicon / Intel) and Linux (x86_64 / aarch64). On macOS the default build is a universal binary (x86_64;arm64), so the VST3/AU/CLAP load on both Intel and Apple Silicon hosts. Windows builds VST3 + CLAP (AU is macOS-only).

The Standalone hosts the full WebView editor and takes MIDI from any connected input. User presets are .zsynthpatch files under ~/Library/zpwr-synth/Presets.

Patch Model

The default voice is Osc(Note) → VCA ← Env(Gate). There is no fixed signal path: a patch — a grid of DSP nodes wired by per-input source selection — is the voice, instantiated across a polyphonic pool. Each node carries a type, 4 inputs, up to 12 params and one output:

ZpwrSynthProcessor (JUCE AudioProcessor)
  └─ zsynth::PolyEngine                 # pool of voices, one zpc::RuntimeGraph each
       └─ zpc::RuntimeGraph (per voice) # the shared core graph, evaluated per sample
            ├─ nodes[N]   each: type + 4 inputs + up to 12 params + 1 output
            ├─ external sources fed per voice (id → value, supplied each sample):
            │    In L/R, Noise, Soft Keys (expandable pool), Note, Gate, Velocity, Mod Wheel,
            │    Pitch Bend, Aftertouch, MPE Pressure / Slide / Bend
            ├─ mods[ ]     route list: source → (node, param) × depth
            └─ out L / out R  (each selects a source)

The synth-specific node types (dsp/SynthModules.cpp, namespace zsynth) are a DSP pack registered onto the core registry; the generators (Osc, Wt, Sample, Granular) read each voice's Note/Gate straight from the core's ComputeContext::external array, so one patch definition plays polyphonically. The patch is saved as JSON in plugin state. MIDI/MPE reaches the synth from the host or the standalone's MIDI input.

Modules

The full catalog — every patchable block with its inputs and parameters — lives in the Module Reference, generated from the live registry. The synth-specific generator and shaper nodes added on top of the shared core include:

  • Osc — analog oscillator (note-driven): wave, octave, fine, PW
  • Wt — wavetable oscillator: table, position, octave, fine
  • Supersaw — 7 detuned saws (JP-8000 style): octave, detune, mix
  • FM — 2-operator phase-modulation sine: ratio, index, octave
  • Karplus — plucked-string physical model: octave, damping, feedback
  • Additive — summed sine harmonics: partials, rolloff, octave, odd/even
  • Sync — hard-sync sawtooth: tune, sync ratio, octave
  • ChordOsc — one note → 3-note chord of saws: type, octave, detune
  • HardKick — hardstyle/rawstyle kick (gate-struck pitch-sweep + tanh drive): tune, punch, psweep, decay, click, drive
  • Screech — hardstyle/gabber screech lead (detuned saws → drive → formant BP): octave, fine, detune, drive, formant, reso
  • Hoover — Alpha Juno hoover / Mentasm: octave, fine, PWM, chorus, sweep, sweepT
  • Reese — DnB / neurofunk Reese bass (detuned beating saws → LP → drive): octave, fine, detune, voices, tone, drive
  • Sub — sub-oscillator below the note: octave, wave, level
  • Noise — white/pink noise source: color, level
  • Sample / Granular — sample playback / granular: slot, start/pos, size, rate
  • Env — ADSR (gate-driven): A, D, S, R
  • VCAin1 × in2 (audio × CV)
  • Filter — TPT state-variable: cutoff, reso, mode, mod
  • Folder — sine wavefolder (west-coast): fold, bias, mix
  • Waveshaper — 4-curve shaper: drive, shape, mix
  • Crusher — bit + sample-rate reduction: bits, downsample, mix
  • Glide — portamento on the note CV: time
  • SampleHold — clocked sample-and-hold CV source: rate, glide
  • Vector — 4-source XY-morph oscillator (Prophet-VS): octave, X, Y, detune
  • DiodeLadder — 4-pole diode-ladder LP (TB-303 grit): cutoff, reso, mod, drive
  • StepLFO — stepped LFO (stair / random S&H): rate, steps, shape, smooth
  • NoiseLFO — coloured-noise CV (white/pink/brown) + S&H: rate, color, depth
  • Scaler — scale/offset/curve a CV (waveshaper for mod): scale, offset, curve
  • Delay / LFO / RingMod / Drive / Gain / Mixer — shaping + modulation, per-type

Every oscillator (Osc, Wt, Supersaw, FM, Sub, Sync, Additive) has a Voices (1–11) unison param plus Detune (cents) — detuned copies summed and loudness-normalised. Voices = 1 is the classic mono behaviour, so existing patches are unchanged. A first-class Trigger modulation source (a 1-sample impulse on each note-on edge) sits alongside Note / Gate / Velocity for modular-style routing.

Modulation

Modulation is the patching itself: any LFO / Env node output or soft key patched into a node input — or mod-routed to a param — is a mod-matrix connection. The editor exposes a per-param mod matrix; the per-voice graph carries a route list (source → (node, param) × depth).

Per-voice external mod sources fed to every patch each sample are Note, Gate, Velocity, Mod Wheel, Pitch Bend, Aftertouch, MPE Pressure / Slide / Bend, Noise, In L/R, and the soft keys (an expandable pool). A first-class Trigger source (a 1-sample impulse on each note-on edge) sits alongside Note / Gate / Velocity for modular-style routing.

Soft Keys & Automation

Host-automatable parameters are the soft keys (sk0…, an expandable pool, ceiling 32; 16 active by default, the active count saved in plugin state), master_in / master_out / master_bypass, plus a reserved pool of 96 Auto N host params — right-click any block param to bind it (the Kontakt/Reaktor model), so any module parameter becomes host-automatable / CC-mappable. 32 soft keys + 96 auto params = 128 CC-mappable slots, one per MIDI CC. Everything else lives in the patch (saved as JSON in plugin state).

User Interface

The editor is a WebView hosting the shared zpwr-patch-core cyberpunk patcher (libs/zpwr-patch-core/webui, served from BinaryData) — byte-for-byte the same UI zpwr-fx uses: drag-to-patch neon cables (fan-out, feedback, per-cable gain + colour), a dynamic block grid (+ ADD BLOCK / delete any number, no fixed node count), double-click a block for its detail modal, and a per-param mod matrix. Panes:

  • PATCH — the node grid + cable routing + an expandable row of soft-key macro knobs (+/ to add/remove; 16 active by default). The toolbar carries an INIT button (unplug every cable & mod, keep the blocks) and 🗑 (blank the whole patch). An ⚡ EZ MODE toggle lays down (and keeps) a playable voice — generators(Note) → VCA ← amp Env(Gate), then VCA → Filter (cutoff swept by a second filter Env) → out. While on, oscillators you add are summed straight into the voice; your generator types are kept. Two toolbar toggles drive the stereo image: Stereo mirrors every block into a right-channel clone (an independent dual-mono voice per side), and Stereo Lock (shown only when Stereo is on) keeps the two channels in sync — moving a knob on either side moves its clone by the same delta, and the mirror is bidirectional.
  • SETTINGS — master in/out (dB) + bypass, Auto Gain Stage + target, the brickwall limiter, the rest of the audio-engine settings, about.

Auto gain staging

Two Settings (both on by default) keep the signal between blocks from clipping no matter how hot the patch-cable gains are, per block, inside every voice graph (and the FX buses):

  • Auto Gain Stage rides levels — a fast-attack / slow-release peak follower whose smoothed gain (≤ 1) pulls each block toward the Auto-Gain Target ceiling.
  • Soft Clip is the guarantee — an instant (sample-accurate) tanh bound at the same ceiling on every block output, catching the fast transients the AGC's ≈2 ms attack would miss.

The live cable glow tracks each block's level; turn either off in Settings for raw gain. Distinct from the master Brickwall Limiter (a single hard ceiling on the final output).

Perform

The PERFORM pane is a play surface with no patching. A PRESET MORPH pad bilinearly interpolates between four corner presets (A/B/C/D, host-automatable morphX/morphY so it runs editor-closed; 🎲 fills all four corners at random). An Omnisphere-style ORB: drag the puck where the angle selects one of 8 randomised scenes and the distance from centre scales intensity, 🎲 rolls fresh scenes, and ⏺ / ▶ record the orb gesture and loop it back. XY macro pads (each drives a pair of soft keys, per-pad HOLD/SPRING release), a row of macro knobs, eight macro-surface SNAPSHOTS (click empty to save, filled to recall, right-click to clear), dice/🎲 RANDOMIZE for all macros, scale/key quantize + CHORD stacking (Oct/5th/Maj/Min/Maj7/Min7/Sus4/Power), and an on-screen keyboard with pitch-bend / mod wheels. The control panel also carries the MIDI IN toggles (PROGRAM = respond to MIDI Program Change, BANK = respond to Bank Select CC0/CC32; both default ON) and the ARP controls — mode (Up/Down/Up-Down/Random/As-Played), rate (1/41/16T) and LATCH.

The editor also has an on-screen keyboard at the bottom plus computer-keyboard input: the home/QWERTY rows (A W S E D F T G Y H U J K …) play a chromatic octave around C4. Click a key once to give the keyboard focus, then type.

Presets

The PRESETS pane ships 256 general factory voices across Factory 1 + Factory 2 (128 each; category-prefixed names: BA bass, LD lead, PD pad, KY keys, PL pluck, BR brass, BE bell, ST strings, DR perc, SEQ/FX etc.) spanning subtractive, FM, additive, supersaw, wavetable, vector, sync and Karplus voices, plus three genre banks designed from documented production techniques — an uplifting Trance bank, a Hard Techno bank, and a Schranz bank (≈160 BPM). Each is generated by an offline tool in tools/gen_*_bank.cpp (shared scaffolding in tools/preset_gen.h). Every preset carries facet tags (Type / Character / Style / Author / Desc) stored in the preset JSON, so the browser's TYPE / CHARACTER / STYLE / BANK facets are fully populated. Plus user presets (.zsynthpatch under ~/Library/zpwr-synth/Presets).

NKS export — every factory voice can be written as a Native Kontrol Standard .nksf preset (RIFF/NIKS container: NISI summary metadata from the facet tags, PLID plugin match, PCHK = the real plugin state, NICA controller page). Each also gets a Komplete Kontrol preview — a 7 s offline render (single sustained C3 + release tail, faded, 44.1 kHz Ogg Vorbis) written to <bank>/.previews/<name>.nksf.ogg. Launch the standalone with ZPWR_EXPORT_NKS=<dir> to export every factory voice into one subfolder per bank.