xtc/docs/decisions/0010-modern-plugin-effects.md

42 lines
2.7 KiB
Markdown
Raw Normal View History

# 0010 — Bounded CLAP, VST2 and VST3 effect loading
Accepted for Phase 31. The user's request to support these three formats
supersedes the earlier recommendation to choose only one external format.
Keep the engine/model/host adapters in C99. CLAP uses pinned MIT headers and VST3
uses the upstream BSD-3-Clause generated C ABI. No SDK runtime library is needed;
Linux dynamic loading and POSIX thread identity are existing platform facilities.
VST2 uses original minimal compatibility declarations, not the discontinued SDK.
See third_party/README.md and LICENSES.md for exact revisions and notices.
Reuse the existing plugin graph node, paired mono instances and immutable plan
ownership. The common facade routes LADSPA to its existing implementation and
modern formats to a separate adapter. This preserves LADSPA controls/automation
and metadata behavior. All three new adapters initially accept one mono input
and output, float32, zero reported latency and no event buses. Default plugin
configuration is used; no parameter/controller/editor or opaque-state access is
exposed. These are usable effect loaders, not complete implementations of every
extension in the formats. Unsupported layouts fail explicitly.
Project v11 adds format plus CLAP stable ID or VST3 class ID to each saved plugin.
Older plugins migrate to LADSPA with an empty extra ID. VST2 retains its integer
unique ID. Reopening checks format/index/identity/name/layout; metadata operations
never open modules. This does not authenticate a binary or freeze defaults across
plugin releases. No modified opaque state exists in this initial API to persist.
Discovery and instance creation execute trusted module code on one serialized
main/control thread. A module cache balances CLAP entry init/deinit and Linux
VST3 ModuleEntry/ModuleExit across overlapping graph instances and retired plans.
CLAP start_processing runs on the processing owner; stop_processing runs after
quiescence with the symbolic audio-thread context. CLAP callback requests use
lock-free flags and are serviced by xtc_plugin_idle on main/control (the GUI timer
calls it). Restart/I/O-change requests latch an error for re-preparation; the audio
callback does not reconfigure or wait for GUI work. CLAP process wakeups need no
queue because playback processes every block, including silence.
Only preallocated buffers and plugin processing occur in audio. Error status
silences the failed block; nonfinite/subnormal samples are sanitized. Plugin code
can still allocate, block, corrupt memory or crash; there is no sandbox, scanner
subprocess or recoverable crash boundary. Modules unload only after destruction
on a quiescent/control owner. Real third-party plugins and hardware timing remain
unqualified; original ABI fixtures demonstrate the bounded contracts.