Skip to content

Capabilities Reference

A categorized inventory of what Pulp can do today. Each capability lists its current status, the module that provides it, and pointers to relevant documentation and examples.

Status vocabulary: stable | usable | experimental | partial | planned | unsupported

See docs/guides/status-ladder.md for the evidence rule on usable labels.


Known Limitations

The following section is auto-generated from the limitations: block of docs/status/support-matrix.yaml. Run python3 tools/docs_generate.py generate to refresh.

Known limitations (20 items across 13 capabilities)

Capability Limitation Tracked in
formats.clap Bus 0 routes to Processor::process(), bus 1 routes to Processor::set_sidechain(), and descriptor-declared secondary output buses are routed through ProcessBuffers; a multi-out processor that overrides process(ProcessBuffers&) writes each aux output bus, while additional input buses beyond the sidechain are not exposed. planning/production-readiness/01-format-adapters.md#1.1
formats.clap CLAP PARAM_MOD note_id/port/channel/key fields are accepted as parameter modulation but are not routed with per-note modulation scope. planning/production-readiness/01-format-adapters.md#1.1
formats.vst3 Bus 0, one sidechain input, and descriptor-declared secondary output buses are routed through ProcessBuffers; a multi-out processor that overrides process(ProcessBuffers&) writes each aux output bus, and single-output processors leave aux buses silent. planning/production-readiness/01-format-adapters.md#1.2
formats.vst3 Dynamic bus arrangements are limited to descriptor-declared bus counts and mono/stereo layouts; unsupported layouts require host-quirk silence accommodation. planning/production-readiness/01-format-adapters.md#1.2
formats.vst3 Controller and per-note expression input is host-mediated: CC, pitch bend, and channel aftertouch arrive when the host honors IMidiMapping hidden parameters, and per-note tuning/pressure/timbre arrive for MPE-enabled plug-ins through INoteExpressionController. There is no separate raw poly-pressure event route. planning/production-readiness/01-format-adapters.md#1.2
formats.au_v2 Plugin-side parameter changes do not propagate back to the host (no AUParameterListenerNotify). planning/production-readiness/01-format-adapters.md#1.3
formats.au_v2 Outbound MIDI from AU v2 effects is not wired yet; HandleMIDIEvent / HandleSysEx feed the adapter's MidiBuffer, but effects that set produces_midi=true have no render-notify path to emit MIDI back to the host. planning/production-readiness/01-format-adapters.md#1.3
formats.auv3 Bus 0 and descriptor-declared input bus 1 are routed through ProcessBuffers; additional input buses and secondary output buses are not exposed through the AUv3 adapter surface yet. planning/production-readiness/01-format-adapters.md#1.4
formats.auv3 MIDI arrives as raw bytes; no type dispatch to note/CC/pitchbend/aftertouch. planning/production-readiness/01-format-adapters.md#1.4
formats.auv3 iOS validation is stale — no on-device example or AVAudioSession ↔ C++ bridge. planning/production-readiness/05-auv3-mobile.md
formats.lv2 Atom sysex events are not routed — only 1–3-byte short MIDI messages in the atom input sequence reach Processor::process(). planning/production-readiness/01-format-adapters.md#1.5
audio_io.wasapi Full-duplex render/capture is not exposed as one synchronized WASAPI device: a WasapiDevice wraps either one render endpoint or one capture endpoint, so callers that need synchronized input/output must open and synchronize two devices. planning/production-readiness/02-audio-midi-io.md#2.1
audio_io.alsa No input capture path. planning/production-readiness/02-audio-midi-io.md#2.2
audio_io.alsa Hardcoded sample-rate list; no real enumeration. planning/production-readiness/02-audio-midi-io.md#2.2
audio_io.jack Server-backed open/start/stop smoke depends on a reachable JACK server and skips otherwise; JACK hotplug/device-manager policy remains pending. planning/production-readiness/02-audio-midi-io.md#2.2
midi_io.coremidi MIDI 2.0 channel-voice input is flattened to MIDI 1.0 where representable; per-note and other unsupported UMP statuses are not delivered through MidiInputCallback. planning/production-readiness/02-audio-midi-io.md#2.6
midi_io.win32_midi Default legacy mmeapi path has no Windows MIDI Services / MIDI 2.0 transport and no hotplug; SysEx input is routed via MIM_LONGDATA. The opt-in WinRT MIDI 2.0 backend requires PULP_HAS_WINRT_MIDI and the Windows MIDI Services SDK. planning/production-readiness/02-audio-midi-io.md#2.4
midi_io.alsa_midi Hotplug notifications depend on runtime libudev/udevd; when unavailable, the port-change callback is stored but will not fire, so clients must re-enumerate manually. planning/production-readiness/02-audio-midi-io.md#2.5
platform_maturity.accessibility.windows Direct UIA client and screen-reader regression tests remain pending; provider tree, WM_GETOBJECT, and value/focus/name event helpers are implemented in source. planning/production-readiness/04-accessibility.md#4.1
platform_maturity.accessibility.linux Real AT-SPI registry/Orca signal receipt remains pending; per-widget Accessible/Component/Value objects and event-hook marshalling are loopback-tested on the session bus. planning/production-readiness/04-accessibility.md#4.2

Plugin Formats

Pulp wraps a single Processor subclass and exposes it through multiple plugin format adapters.

Capability Status Module Docs Examples
VST3 effect usable format getting-started pulp-gain, pulp-effect, pulp-compressor
VST3 instrument usable format PulpTone, PulpPluck
Audio Unit v2 effect usable format getting-started pulp-gain, pulp-effect, pulp-compressor
Audio Unit v2 instrument usable format PulpTone, PulpPluck
CLAP effect usable format pulp-gain, pulp-effect, pulp-compressor
CLAP instrument usable format PulpSynth
Standalone app usable format pulp-gain
Headless host usable format testing
AU v3 (macOS + iOS) usable format
LV2 (Linux) experimental format
WAM v2 (Web) experimental format web-plugins
WebCLAP (Web) experimental format
AAX native (optional, macOS/Windows) experimental format aax pulp-gain

Key headers: pulp/format/processor.hpp, pulp/format/vst3_adapter.hpp, pulp/format/clap_adapter.hpp, pulp/format/headless.hpp

AAX support is intentionally opt-in. It requires a developer-supplied AAX SDK, is not bundled by Pulp, and is unsupported on Linux and Ubuntu.

Known Limitations (plugin formats)

These are the production gaps currently tracked per adapter. The authoritative list lives at docs/status/support-matrix.yaml under format_limitations:; this section mirrors it for human readers. A status of usable means the adapter compiles and loads — not that every host-facing feature is wired.

  • VST3 — Dynamic bus arrangements limited; setBusArrangements only renegotiates the primary stereo bus today. Descriptor-declared secondary output buses are routed through ProcessBuffers, so a multi-out processor that overrides process(ProcessBuffers&) writes each aux output bus. Tracked: production-readiness workstream 01.
  • Audio Unit v2 — Outbound parameter changes are not emitted to the host; automation read on AU v2 effects only flows host → plugin. Tracked: workstream 01.
  • CLAP — Bus 0 routes to Processor::process() and bus 1 routes to Processor::set_sidechain(). Descriptor-declared secondary output buses are routed through ProcessBuffers, so a multi-out processor that overrides process(ProcessBuffers&) writes each aux output bus; additional input buses beyond the sidechain are not exposed through the simple Processor process surface. CLAP PARAM_MOD note identity fields are accepted but not routed with per-note modulation scope.
  • LV2 — Atom sysex is ignored; the run() loop only promotes 1–3-byte short MIDI messages out of the input atom sequence.
  • AAX — Custom editor surface not wired; Pro Tools shows the auto-generated parameter strip rather than a Pulp ViewBridge editor. AudioSuite role is declared but not exercised end-to-end. Tracked: planning/signalgraph-and-bridge-followups-plan.md rows 7 and 13.
  • AUv3 — iOS jetsam pressure not modeled; heavy V8 / WebView workloads in the AUv3 process risk termination at ~50 MB. Tracked: workstream 05.
  • WAM v2 / WebCLAP — Browser origin sandbox only; no Pulp-side capability manifest yet, and the Pulp browser-host runtime wiring is still scaffolded. Tracked: planning/security/container-and-sandbox-strategy-v4.md.

If you hit a limitation not listed, check planning/production-readiness/01-format-adapters.md and file an issue.


Platforms

Capability Status Module Notes
macOS (ARM64) usable platform Primary development platform
Windows experimental platform WASAPI, Win32 MIDI, NSIS installer, CI
Linux experimental platform ALSA, JACK, LV2, CI
iOS experimental platform AVAudioSession, AUv3, UIKit, Metal
Web / WASM experimental platform WAMv2 (Emscripten) and WebCLAP (wasi-sdk) plugins, both exercised in a headless-Chrome CI lane. Pulp's view tree also renders in the browser via Skia Ganesh on WebGL2. DSP is CPU-only today — GPU compute does not yet compile to wasm. Browser WebGPU does support compute shaders, so GPU DSP is reachable (compute in a Worker, blocks handed to the AudioWorklet over a SharedArrayBuffer ring); it is simply not wired yet.

Key headers: pulp/platform/detect.hpp, pulp/platform/native_handle.hpp


Audio I/O

Capability Status Module Docs
BufferView (non-owning channel pointer wrapper) usable audio modules
Audio device enumeration and streaming (CoreAudio) usable audio
Audio file read/write usable audio
WASAPI device I/O experimental audio
ALSA device I/O experimental audio
AVAudioSession (iOS) experimental audio
Live Audio Inspector (RT output-boundary probe, dev window + JSON dump) usable audio audio-inspector
Audio Scope acquisition and measurements (pulp.audio.scope.v1, CLI/MCP live or offline WAV) experimental audio cli

Key headers: pulp/audio/buffer.hpp, pulp/audio/device.hpp, pulp/audio/audio_file.hpp, pulp/audio/wav_decoder.hpp, pulp/audio/audio_scope.hpp


MIDI I/O

Capability Status Module Docs
MidiEvent / MidiBuffer usable midi modules
MIDI device I/O (CoreMIDI) usable midi
MIDI file read/write usable midi
Provider-neutral microtuning usable midi Optional MTS-ESP session/SysEx provider and Scala SCL/KBM local-file provider
Win32 MIDI experimental midi
ALSA Raw MIDI experimental midi

Key headers: pulp/midi/message.hpp, pulp/midi/buffer.hpp, pulp/midi/device.hpp, pulp/midi/midi_file.hpp, pulp/midi/tuning.hpp, pulp/midi/mts_esp_tuning.hpp, pulp/midi/scala_tuning.hpp


DSP / Signal Processing

All signal processors live in the signal module. Each is a standalone, stateless-friendly C++ class.

Capability Status Module Examples
Gain usable signal pulp-gain
ADSR envelope usable signal PulpSynth
Biquad filter usable signal pulp-effect
State-variable filter (SVF) usable signal
Ladder filter usable signal PulpSynth
Linkwitz-Riley crossover usable signal
Oscillator usable signal pulp-tone, PulpSynth
Delay line usable signal pulp-effect
Chorus usable signal
Phaser usable signal
Compressor usable signal pulp-compressor
Noise gate usable signal
Reverb usable signal pulp-effect
Waveshaper usable signal
Panner usable signal
Oversampling usable signal
FFT usable signal
Windowing functions usable signal
SmoothedValue usable signal
Modal synthesis bank + strike/pickup weighting usable signal modal specification fixtures
Versioned modal-spec JSON loading and validation usable signal modal specification fixtures
Circuit-derived bridged-T resonator usable signal
Band-limited square-oscillator bank usable signal

Key headers: all under pulp/signal/ -- e.g., pulp/signal/compressor.hpp, pulp/signal/modal_bank.hpp, pulp/signal/modal_spec.hpp, pulp/signal/bridged_t_resonator.hpp, pulp/signal/osc/va.hpp

Oscillators live in pulp/signal/osc/: a phase accumulator, the polyBLEP/BLAMP kernels, and the virtual-analog shapes built from them, with hard sync and through-zero FM. The older pulp/signal/oscillator.hpp is superseded and kept for existing callers.


DSP DSLs

Capability Status Module Docs Examples
FAUST offline codegen via external compiler + checked-in generated C++ experimental dsl faust guide, pulp-dsl contract faust-gain, faust-filter, faust-tremolo
Cmajor external-toolchain support lane experimental dsl cmajor guide, pulp-dsl contract cmajor-gain (source-only)
JSFX bounded subset support lane experimental dsl jsfx guide, pulp-dsl contract jsfx-gain, jsfx-tremolo, jsfx-delay (source-only)

Key headers: pulp/dsl/dsl_processor.hpp, pulp/dsl/faust_processor.hpp


Native Components

Opt-in native-language audio components behind a language-neutral C ABI (Rust first). OFF by default — a default build needs no Rust toolchain. See the native-components reference for scope, the C-ABI contract, and the iOS static-only limits.

Capability Status Module Docs Examples
Rust/C/Zig DSP behind a C++ Processor adapter via a private C-shaped FFI experimental format native-components rust-gain (opt-in)
Native non-RT domain logic behind EditorBridge experimental view native-components, editor-bridge
Source-built custom SignalGraph nodes (toward pulp_node_v1 C ABI) experimental host node-abi, signal-graph
Bake a lowerable SignalGraph into an optimized BakedGraphProcessor (bit-identical to live) usable host signal-graph in-process bake(), trusted
Signed on-disk .pulpbake artifact (write_baked_signed / verify-before-parse load_baked) usable host signal-graph Ed25519 trust-set; no unsigned load; v1 stateless custom
Live plugin-instance swap in a SignalGraph node while audio plays (set_node_live_swap_policy / stage_plugin_replacement / prepare_swap) usable host signal-graph opt-in, fail-closed; loads no new code (no trust surface); eager-prepare fallback

State and Automation

Capability Status Module Docs Examples
ParamValue (lock-free atomic float) stable state modules all
ParamInfo (metadata, range, units) stable state all
ParamRange (normalize / denormalize, linear + skew/symmetric shaped) stable state
StateStore (centralized parameter registry) stable state all
Parameter groups stable state
Binding (reactive UI-parameter link) stable state
Gesture begin/end (host undo grouping) stable state
State serialization / deserialization stable state
CLAP modulation offset stable state
Change listeners stable state

Key headers: pulp/state/parameter.hpp, pulp/state/store.hpp, pulp/state/binding.hpp


View / UI

Core

Capability Status Module Docs
View hierarchy (tree, bounds, hit-testing) usable view modules
Flex layout (full CSS Flexbox L1) usable view web-compat
Grid layout (CSS Grid L1 — templates, fr, gaps) usable view
Theme system (color/dimension tokens, inheritance) usable view design-tokens
JS scripting (QuickJS default, V8 and JavaScriptCore available) usable view js-bridge
Hot reload partial view Scripted UI live reload is runtime-validated in the standalone macOS lane. Plugin targets can load UI_SCRIPT, but live reload is not yet guaranteed across hosts/platforms.
Screenshot capture (headless PNG) partial view Native on mac/iOS; Windows/Linux/Android require a host-registered provider via set_screenshot_provider.
Component inspector usable view
Animation (FrameClock, ValueAnimation, motion tokens) usable view animation
Design export (JSON, SVG) usable view
App framework (commands, menus, key bindings) usable view
Interactive AI design tool (pulp design) experimental view cli
Design debug harness (pulp design-debug) experimental view cli

Widgets

Capability Status Module Notes
Knob, Fader, Toggle, Checkbox, ToggleButton usable view Full interaction + accessibility roles
Label (multi-line, text-transform, decoration) usable view
TextEditor (selection, clipboard, undo, IME) usable view
ComboBox (dropdown, keyboard nav) usable view
ListBox (virtualized, scroll, keyboard) usable view
ScrollView (smooth scroll, fade bars) usable view
Meter (RMS + peak hold), ProgressBar usable view
XYPad, WaveformView, SpectrumView usable view
ImageView usable view File-backed decode with placeholder fallback
TreeView, Tooltip, Panel, Icon usable view
SpectrogramView (scrolling STFT) usable view
MultiMeter, CorrelationMeter usable view
PresetBrowser (search, categories, nav) usable view
MidiKeyboard (display + interaction) usable view
WaveformEditor (selection, zoom, regions) usable view
EqCurveView (draggable band handles) usable view
FileBrowser, FileDropZone usable view
GraphEditorView (canvas-based node editor) usable view SignalGraph UI
ConcertinaPanel, SplitView, Breadcrumb, Toolbar usable view
ColorPicker, Lasso, PropertyList, CodeEditor usable view
CanvasWidget (25 draw commands) usable view custom-rendering
ModulationMatrixWidget (source-to-destination routes) usable view widgets
TableListBox (sortable columns) partial view Click-to-sort columns and themed rows are implemented; built-in table scrolling/scrollbar remains planned
A/B compare planned view Production-readiness workstream 07

Web-Compat Layer

Capability Status Module Docs
document.createElement / appendChild / remove usable view web-compat
element.style (81 CSS properties) usable view web-compat
CSS calc() / min() / max() / clamp() usable view
CSS unit resolution (em, rem, %, vw, vh) usable view
CSS colors (L4: hex, rgb, hsl, 148 named) usable view
StyleSheet (class rules, pseudo-classes) usable view
Selectors (:nth-child, :not, descendant, child) usable view
closest / matches / innerHTML usable view
matchMedia (responsive breakpoints) usable view
Pointer events (W3C Level 2) usable view js-bridge
Gesture events (scale, rotation) partial view macOS trackpad gestures shipped; iOS multi-touch gesture analysis is still incomplete

Platform Maturity

Capability Status Platform Notes
Cursor management (7 styles) usable macOS NSCursor in mouseMoved
Tab focus traversal usable all Tab/Shift+Tab cycles focusable views
VoiceOver accessibility usable macOS NSAccessibilityElement + AccessRole
VoiceOver accessibility usable iOS UIAccessibilityElement with slider increment/decrement
TalkBack accessibility usable Android JNI bridge: role, label, value, table metadata, actions
UIA accessibility partial Windows Provider tree, WM_GETOBJECT, and value/focus/name event helpers exist; direct UIA client regression still pending
AT-SPI accessibility partial Linux Direct D-Bus provider exposes per-widget tree/value paths with loopback tests; real registry/Orca signal receipt still pending
IME composition (marked text) usable macOS Full NSTextInputClient
Right-click context menu partial all on_context_menu/registerContextMenu fire; view-tree ContextMenu is actionable; native showContextMenu currently renders only on macOS and does not report selection
Keyboard shortcuts usable all registerShortcut bridge
File dialogs (open, save, folder) partial macOS, Windows, Linux macOS NSOpenPanel/NSSavePanel; opt-in Windows IFileDialog and Linux xdg-desktop-portal backends via FileDialog::install_native_backend()
Drag and drop usable macOS File + text drop targets
Plugin view hosting usable macOS/iOS, Windows, Linux Native NSView/UIView/HWND/X11 plugin-editor hosts. Windows requires Skia; Linux requires Skia + X11 and degrades to headless capture when no display is available. Android/custom targets still require a host-registered PluginViewHost::Factory. Native child attach/bounds/detach inside plugin editors is built in on macOS/iOS only; non-Apple child embedding remains factory-backed.
Native child view embedding (WindowHost) partial macOS + factory-backed non-Apple Built-in standalone support is macOS-only. Built-in iOS WindowHost does not expose the embedding handles. Windows/Linux/Android require a host-registered WindowHost::Factory that implements attach/bounds/detach.
SDL window host partial all Cross-platform windowing via SDL3. SDL does not provide first-party native child embedding; non-Apple platforms require a host-registered WindowHost::Factory for native presentation. Recording-canvas-only for now.

Key headers: pulp/view/view.hpp, pulp/view/widgets.hpp, pulp/view/theme.hpp, pulp/view/script_engine.hpp, pulp/view/widget_bridge.hpp


Rendering / GPU

Capability Status Module Docs
Dawn/Metal GPU surface experimental render modules
Skia Graphite rendering experimental render
Dawn/Metal iOS surface experimental render
Dawn/D3D12 surface (Windows) experimental render Surface creation implemented, not runtime-validated
Dawn/Vulkan surface (Linux) experimental render X11 surface creation implemented; Wayland extraction exists but presentation is not wired; not runtime-validated
CoreGraphics fallback usable render Default render path on macOS
Skia Ganesh on WebGL2 (browser) experimental render The wasm render path. Paints core/view's widget tree into a browser canvas, driven by a requestAnimationFrame render loop; DOM pointer/key events are translated into the View tree.

Native GPU rendering is Skia Graphite over Dawn. The browser is the one exception: the published Skia wasm slice is Ganesh on WebGL2 and ships no Dawn at all, so Graphite/Dawn-on-wasm is not what runs there. The backend is confined to core/render/src/skia_surface_ganesh.cpp — nothing above the render boundary knows which one it got. WebGL context loss is handled (the surface reports unavailable, the loop keeps pumping, and Ganesh is rebuilt on restore), and a browser without a WebGL2 context is a supported configuration that the host page must be prepared to fall back from (pulp::view::web::browser_host_gpu_available()).

Key headers: pulp/render/gpu_surface.hpp, pulp/render/skia_surface.hpp, pulp/view/web/web_event_translate.hpp


GPU Audio

Offload heavy DSP to the GPU from a real-time process() block via a fixed-latency, lock-free bridge. The GPU node implementations are gated on the GPU render stack (pulp::render); the GpuAudioTransport bridge and the public node classes still compile in a non-GPU build and report gpu_available() == false, falling back to the signal::* CPU path.

Capability Status Module Docs
GPU audio transport (fixed-latency RT↔GPU bridge) experimental gpu_audio GPU Audio SDK
GPU convolution (GpuConvolver) experimental gpu_audio SuperConvolver example
GPU spectral toolkit (STFT / freeze / morph) experimental gpu_audio Spectral Lab example
GPU WaveNet neural-inference primitive experimental render GPU NAM example

Key headers: pulp/gpu_audio/gpu_audio_transport.hpp, pulp/gpu_audio/gpu_convolver.hpp, pulp/render/gpu_compute.hpp

Not available on the web. No GPU-compute code compiles to wasm. The Skia wasm slice is Ganesh on WebGL2, and WebGL2 has no compute shaders, so a plugin with a GPU engine runs its CPU engine in the browser (SuperConvolver's WAM/WebCLAP builds run the CPU PartitionedConvolver). A GPU-DSP lane in the browser would need WebGPU in a dedicated worker; that is not implemented. Note also that GPU is not automatically faster than CPU for audio — a measured spike found a competent CPU implementation beats or ties the GPU at all musical settings.


Canvas / 2D Drawing

Capability Status Module Docs
Canvas abstraction (paths, fills, strokes, text) usable canvas modules
RecordingCanvas (command capture for testing) usable canvas
CoreGraphics backend usable canvas
Skia backend experimental canvas
SVG rendering experimental canvas
Effects (shadow, blur, gradients) usable canvas
Backend capability query (Canvas::supports(CanvasCapability)) usable canvas

Key headers: pulp/canvas/canvas.hpp, pulp/canvas/cg_canvas.hpp, pulp/canvas/skia_canvas.hpp, pulp/canvas/svg.hpp, pulp/canvas/view_effect.hpp


Runtime Primitives

Capability Status Module Docs
SeqLock (coherent multi-field reads) stable runtime architecture
TripleBuffer (latest-value publication) stable runtime architecture
SPSCQueue (single-producer single-consumer FIFO) stable runtime
ActivityChannel (realtime-to-UI occurrence feedback) stable runtime runtime guide
SpscRingIndex (lock-free ring index; the <pulp/runtime/spsc_ring_index.hpp> type behind a ring buffer) stable runtime
ScopeGuard stable runtime
Logging stable runtime
Assertions stable runtime

Key headers: pulp/runtime/activity_channel.hpp, pulp/runtime/seqlock.hpp, pulp/runtime/triple_buffer.hpp, pulp/runtime/spsc_queue.hpp, pulp/runtime/log.hpp


Events

Capability Status Module Docs
Event loop usable events modules
Timers usable events

Key headers: pulp/events/event_loop.hpp, pulp/events/timer.hpp


Platform Services

Capability Status Module
OS detection usable platform
Clipboard access partial platform
Native file dialogs partial platform
Popup menus usable platform
Native window handle usable platform

Key headers: pulp/platform/detect.hpp, pulp/platform/clipboard.hpp, pulp/platform/file_dialog.hpp, pulp/platform/popup_menu.hpp


OSC (Open Sound Control)

Capability Status Module Docs
OSC 1.0 message encode/decode experimental osc modules
UDP sender experimental osc
UDP receiver experimental osc

Key header: pulp/osc/osc.hpp


Agent / Automation

Capability Status Docs Notes
Repo-level MCP server (pulp-mcp) experimental Project/repo automation server in tools/mcp/pulp_mcp.cpp; not a per-plugin control surface
Plugin CLI harness pattern usable cli tools/plugin-cli/plugin_cli.hpp; usable for batch/headless workflows, but not auto-generated for every plugin
Per-plugin/app MCP control contract planned claim-audit-baseline Not a shipped default capability

Tooling / CLI

The pulp CLI wraps common development workflows.

Capability Status Docs
pulp build (configure + build) usable cli
pulp test (run test suite) usable cli
pulp validate (pluginval, clap-validator, auval, optional AAX validator) usable cli
pulp status (show project info, build state, source counts) usable cli
pulp clean (remove build directory) usable cli
pulp ship sign usable cli
pulp ship package usable cli
pulp ship check usable cli
pulp docs (local docs lookup) usable cli
pulp create (new project from template) usable cli
pulp run (launch standalone binary) usable cli
pulp upgrade (self-update) usable cli
pulp doctor (check system dependencies) usable cli
pulp inspect (component inspector) usable cli
pulp audit (dependency license check) usable cli
pulp add (add dependency) usable cli
pulp cache (build cache management) usable cli
pulp design (interactive AI design tool) experimental cli
pulp design-debug (design debug harness) experimental cli
pulp import-design (import from external design tools) experimental cli
pulp import-design --from designmd (Google DESIGN.md import, Apache-2.0; tokens-only in Phase 1) partial imports/designmd
pulp export-tokens (export design tokens) experimental cli
pulp ci-local (local CI runner — Mac + VM validation) experimental local-ci

Shipping / Release

Capability Status Module Docs
Code signing (macOS) usable ship cli
Notarization submit/check/staple usable ship
DMG creation usable ship
PKG installer creation usable ship
Combined multi-format PKG usable ship
Entitlements generation usable ship
Signing identity listing usable ship
Appcast feed generation (Sparkle-compatible) usable ship
Appcast XML parsing usable ship
Ed25519 update signing usable ship Sparkle appcast signatures via sign_file_ed25519() and pulp ship appcast --sign-key
Semantic version comparison usable ship
Windows code signing partial ship windows — Authenticode via Windows SDK signtool; signing is implemented, but certificate provisioning and real signing validation remain host-owned
Linux packaging usable ship linux — tested .deb path with .tar.gz fallback independent of runtime platform maturity, plus standalone AppImage wrapping when appimagetool is installed

Key headers: pulp/ship/codesign.hpp, pulp/ship/appcast.hpp


Processor Interface

The Processor base class defines what plugin developers implement.

Capability Status Module Docs Examples
Plugin descriptor (name, category, buses, MIDI flags) usable format getting-started all
Multi-bus I/O (sidechain, aux) usable format pulp-compressor
Effect / Instrument / MidiEffect categories usable format
Transport context (tempo, time sig, position) usable format
Latency reporting usable format
Tail time usable format
Non-realtime maintenance tick (on_non_realtime_tick() / non_realtime_tick_pending()) experimental format super-convolver
Plugin registry (multi-plugin bundles) usable format

Non-realtime maintenance tick

Processor::on_non_realtime_tick() (default no-op) gives a processor a place to do control-driven work that process() must never do — decode, resample, FFT-plan, allocate — when the host provides no thread to do it on. The motivating case is the browser: a WAM v2 module lives entirely inside an AudioWorklet and a WebCLAP module has no std::thread.

Processor::non_realtime_tick_pending() (default false) is the realtime-safe query the adapter peeks from process() to discover that a tick is owed. It must be RT-safe: read atomics and compare — no locks, no allocation.

Who calls it — the contract is narrower than "any host":

  • WAM v2 — the adapter marks the processor dirty on a control write and calls the tick once per render turn, so a burst of control messages (a knob drag delivers many in one turn) collapses into a single pass over the latest values. Do not rely on one tick per parameter write; rely on "eventually, with the latest values."
  • CLAP — including native CLAP, not only WebCLAP. clap_on_main_thread and state.load call it unconditionally, and process() peeks non_realtime_tick_pending() each block to request the main-thread callback (the same mechanism already used for latency/tail changes). A processor that already owns a worker thread should do nothing in the tick, or the worker and the host race.
  • VST3, AU, and the standalone host do not call it at all. A processor that depends on it for correctness must also have a worker (or do the work in prepare()), or it will never reconcile in those formats.

It is never called from inside process(). In a worklet-only host it does run on the same OS thread as the render callback (just outside it), so a long tick can still make the next quantum late — keep the work bounded.

Both methods are appended at the end of the Processor vtable to keep vtable ordering additive-only.