DSPark 1.6.1
Header-only audio DSP framework in pure C++20 — zero dependencies
Loading...
Searching...
No Matches
dspark::plugin Namespace Reference

Namespaces

namespace  clap_backend
 
namespace  vst3
 
namespace  webview_ui
 

Classes

struct  BlockEvent
 One timestamped in-block event, normalised across formats: a parameter point, a bypass point, or a MIDI event. The backends collect them per block, sort them, and either split processing at quantum boundaries (sample-accurate mode) or apply them all up front. More...
 
struct  Descriptor
 Static identity of a plugin. All fields are plain literals so the whole descriptor can live in a static constexpr of the user class. More...
 
struct  EditorSize
 Editor window size in logical pixels (physical = logical x host scale). More...
 
struct  MidiEvent
 One incoming MIDI-ish event, normalised across formats. More...
 
struct  Param
 One automatable parameter. Plain values run [min, max]; hosts see the normalized [0, 1] projection. steps == 0 means continuous, steps == 1 a toggle, steps == N an N+1-position discrete control. More...
 
struct  PluginBase
 Optional convenience base that makes EVERY contract method visible and overridable from one place - IDE-discoverable, without the virtuals. More...
 
struct  PresetDef
 One factory preset: a name plus a PLAIN value for every parameter, in parameter-table order. Build the table with preset()/presets() so the value count is checked at compile time against the parameter count. More...
 
struct  TransportInfo
 Host transport snapshot, delivered once per audio block. More...
 

Concepts

concept  HasReset
 
concept  HasLatency
 
concept  HasTail
 
concept  HasGetState
 
concept  HasSetState
 
concept  HasEditor
 Custom-editor switch. With hasEditor = false (or absent) hosts show their generic parameter UI. With hasEditor = true AND plugin/webview/DSParkWebViewEditor.h included BEFORE the format headers, the WebView editor layer serves editorHtml() inside the host window.
 
concept  HasSidechain
 Sidechain capability. Implement the two-buffer process - the same shape DSPark's own dynamics take:
 
concept  HasTransport
 Transport capability: void setTransport(const TransportInfo&) noexcept. Called on the audio thread, before processBlock, whenever the host supplied transport data for the block (no call means "same as last block"). This is how tempo-synced delays, LFOs and gates follow the song.
 
concept  HasMidi
 MIDI capability: void handleMidiEvent(const MidiEvent&) noexcept. Its presence grows a note/event input in every format (VST3 event bus, CLAP note port, AU music-device selectors) - which is also why PluginBase deliberately ships no default for it. Required for Category::Instrument, optional for MIDI-driven effects. Audio thread; allocation-free.
 
concept  HasOfflineMode
 Render-mode capability: void setOfflineRendering(bool) noexcept. The host flips it to true for non-realtime bounces (VST3 kOffline setup, the CLAP render extension, AU OfflineRender) - the moment to switch to more expensive algorithms (higher oversampling, longer lookahead). Called outside the audio thread, before processing (re)starts. Default: assume realtime.
 
concept  HasChannelSupport
 
concept  HasFactoryPresets
 Factory-preset capability: a static constexpr auto factoryPresets table built with presets(). The backends publish it natively - a VST3 program list, CLAP preset-load + preset-discovery, AU factory presets - so the host's own preset browser offers them. No PluginBase default on purpose: the table's presence changes what hosts display.
 
concept  HasSampleAccurateOptOut
 Sample-accurate opt-out: static constexpr bool sampleAccurateAutomation = false;. By default the wrappers split each audio block at automation points (snapped to kAutomationQuantum frames) so fast curves land where the host drew them instead of stepping once per block. Opt out when your plugin has a high fixed cost per processBlock CALL and block-rate automation is acceptable.
 
concept  HasEditorHtml
 static const char* editorHtml() - the editor page (HTML/CSS/JS), usually a raw string literal. Required when hasEditor is true.
 
concept  HasEditorSize
 Optional static constexpr EditorSize editorSize { w, h };.
 
concept  HasEditorResizable
 Optional static constexpr bool editorResizable = true; - shorthand for editorResize = EditorResize::Free (default: fixed size).
 
concept  HasEditorResize
 Optional static constexpr EditorResize editorResize = ...; - full resize policy; takes precedence over editorResizable.
 
concept  HasEditorDebug
 Optional static constexpr bool editorDebug = true; - enables the browser DevTools in the editor (WebView2; development builds only).
 
concept  HasEditorDevFile
 Optional static const char* editorDevFile() - absolute path of an HTML file to load INSTEAD of editorHtml() while developing: edit the file, reopen the editor, no recompile. Falls back to editorHtml() when the file is missing, so the same build still works elsewhere. Strip from releases.
 

Enumerations

enum class  Category { Fx , Instrument }
 Plugin category (reflected into each format's class metadata). More...
 
enum class  ChannelSupport { MonoAndStereo , StereoOnly , MonoOnly }
 Bus widths a plugin offers to the host. The DSPark contract is channel-agnostic by construction (prepare() receives numChannels and processBlock honours io.numChannels()), so the DEFAULT is mono+stereo: the plugin appears on every track type. Declare static constexpr auto channels = dspark::plugin::ChannelSupport::...; only to restrict it (e.g. StereoOnly for M/S wideners). All buses of an instance run the same width - a sidechain follows the main pair. More...
 
enum class  EditorResize { Fixed , Free , KeepAspect }
 How the host may resize the editor window. Declare static constexpr EditorResize editorResize = ...; in the plugin class; without it the window is Fixed (or Free if the simpler editorResizable = true shorthand is present). More...
 

Functions

constexpr Param param (const char *id, const char *name, float minValue, float maxValue, float defValue, const char *unit) noexcept
 Continuous parameter helper.
 
constexpr Param toggle (const char *id, const char *name, bool defaultOn) noexcept
 On/off parameter helper.
 
template<typename... Ps>
constexpr std::array< Param, sizeof...(Ps)> params (Ps... ps) noexcept
 Builds the parameter table (use inside static constexpr auto).
 
constexpr double toNormalized (const Param &p, double plain) noexcept
 Plain [min, max] -> normalized [0, 1] (steps snap on the way back).
 
constexpr double toPlain (const Param &p, double normalized) noexcept
 Normalized [0, 1] -> plain [min, max], snapped for stepped params.
 
int parseToggleText (const char *text) noexcept
 Case-insensitive "On"/"Off" recognition - the inverse of the toggle display below. Returns 1 for On, 0 for Off, -1 for anything else. Hosts round-trip displayed strings through text-to-value (automation lanes, typed values), so toggles must parse their own output.
 
void formatValue (const Param &p, double plain, char *out, int outSize) noexcept
 Formats a plain value for host display ("3.5 dB", "On", "440 Hz").
 
constexpr uint32_t hash32 (const char *s) noexcept
 FNV-1a 32-bit over a C string - the per-parameter host id.
 
constexpr uint64_t hash64 (const char *s, uint64_t salt) noexcept
 FNV-1a 64-bit with a salt (two runs build a 128-bit class UID).
 
template<typename P >
constexpr bool paramIdsUnique () noexcept
 Compile-time guarantee that every parameter id hashes uniquely and collides with neither reserved state id ('PRGM', 'BYPS'). A collision would silently cross-wire automation and state between two parameters, so the backends refuse to build: static_assert(paramIdsUnique<MyPlugin>());.
 
constexpr std::array< uint8_t, 16 > makeUid (const char *productId, uint64_t salt) noexcept
 Deterministic 16-byte class UID from the stable productId. Each backend salts differently so VST3/CLAP/AU ids never collide.
 
template<typename P >
constexpr ChannelSupport channelSupportOf () noexcept
 The declared channel support of P (default: mono+stereo).
 
template<typename P >
constexpr bool supportsChannelCount (int numChannels) noexcept
 True when P accepts a bus width of numChannels (1 or 2).
 
template<typename P >
constexpr int defaultChannelCount () noexcept
 The width every backend starts in before the host negotiates.
 
template<typename... Vs>
constexpr PresetDef< sizeof...(Vs)> preset (const char *name, Vs... values) noexcept
 Builds one factory preset: preset("Warm", 6.0f, 0.8f, ...) - one PLAIN value per parameter, in table order.
 
template<typename First , typename... Rest>
constexpr std::array< First, 1+sizeof...(Rest)> presets (First first, Rest... rest) noexcept
 Builds the factory preset table (all presets must cover the same parameter count - enforced here; matched against the parameter table by the backends). Declare as static constexpr auto factoryPresets = ....
 
template<typename P >
constexpr int factoryPresetCountOf () noexcept
 Number of factory presets of P (0 when none declared).
 
template<typename P >
constexpr double presetNormalized (int presetIndex, size_t paramIndex) noexcept
 Normalized value of parameter paramIndex in factory preset presetIndex (bounds already validated by the caller).
 
template<typename P >
constexpr bool sampleAccurateOf () noexcept
 
void sortBlockEvents (BlockEvent *events, int count) noexcept
 Stable insertion sort by offset (tiny N, allocation-free - audio-thread safe; equal offsets keep arrival order).
 
template<typename P >
constexpr EditorSize editorSizeOf () noexcept
 The declared (logical) editor size, or the 480x320 default.
 
template<typename P >
constexpr EditorResize editorResizeOf () noexcept
 The effective resize policy for plugin class P.
 
template<typename P >
constexpr void constrainEditorSize (double &width, double &height, double scale) noexcept
 Applies the resize policy of P to a size the host proposes: Fixed pins it, Free clamps each axis to the 0.5x..3x window, KeepAspect fits the declared ratio INSIDE the proposal - never exceeding it on either axis. That last property is essential: hosts size the plugin area inside a window the user controls, so answering "larger" on any axis pushes the plugin outside its own window (clipped bottom in REAPER).
 
template<typename P >
std::vector< uint8_t > buildState (const P &user, const double *normalized, size_t numParams, int programIndex=-1, int bypassState=-1)
 
template<typename P >
bool applyState (P &user, const uint8_t *data, size_t size, double *normalized, int *programIndex=nullptr, int *bypassState=nullptr)
 Parses a state blob; fills normalized (defaults pre-loaded by the caller), reports a persisted program index / bypass through programIndex and bypassState (left untouched when absent) and forwards the user section. Returns false on a foreign blob.
 

Variables

constexpr int kAutomationQuantum = 32
 Sub-block grain: automation/event splits snap to this many frames (bounds the per-call overhead; ~0.7 ms at 48 kHz is inaudible).
 
constexpr int kMaxBlockEvents = 256
 Hard cap of timestamped events handled per block; the (very unlikely) excess applies at the position of the last captured event.
 
constexpr double kEditorMinSizeFactor = 0.5
 Resize bounds: hosts may shrink to half and grow to 3x the declared size.
 
constexpr double kEditorMaxSizeFactor = 3.0
 
constexpr uint32_t kStateMagic = 0x4453504Bu
 
constexpr uint32_t kStateVersion = 1u
 
constexpr uint32_t kProgramStateId = 0x5052474Du
 Reserved entry id persisting the active factory-preset index ('PRGM'); never a user parameter. Older builds skip it (unknown id).
 
constexpr uint32_t kBypassStateId = 0x42595053u
 Reserved entry id persisting the host bypass ('BYPS' - the same value every backend uses as the bypass ParamID). Hosts treat bypass as one more parameter, so it must survive a state round-trip like any other. Older builds skip it (unknown id).
 

Enumeration Type Documentation

◆ Category

enum class dspark::plugin::Category
strong

Plugin category (reflected into each format's class metadata).

Fx processes audio in place (optionally keyed by a sidechain or driven by MIDI - a vocoder, a MIDI-gated effect). Instrument GENERATES audio: it has no main audio input in any format (VST3 instrument class, CLAP "instrument" feature, AU aumu music device) and almost always pairs with handleMidiEvent (see HasMidi). The wrapper clears the output buffers before calling an instrument's processBlock, so voices ADD into io without reading it.

Enumerator
Fx 

Audio effect (audio in -> audio out).

Instrument 

Audio generator (MIDI in -> audio out, no audio input).

Definition at line 83 of file DSParkPlugin.h.

◆ ChannelSupport

enum class dspark::plugin::ChannelSupport
strong

Bus widths a plugin offers to the host. The DSPark contract is channel-agnostic by construction (prepare() receives numChannels and processBlock honours io.numChannels()), so the DEFAULT is mono+stereo: the plugin appears on every track type. Declare static constexpr auto channels = dspark::plugin::ChannelSupport::...; only to restrict it (e.g. StereoOnly for M/S wideners). All buses of an instance run the same width - a sidechain follows the main pair.

Enumerator
MonoAndStereo 

Negotiates 1->1 or 2->2 with the host (default).

StereoOnly 

Strictly 2->2 (inherently stereo DSP).

MonoOnly 

Strictly 1->1 (rare; metering/utility plugins).

Definition at line 443 of file DSParkPlugin.h.

◆ EditorResize

enum class dspark::plugin::EditorResize
strong

How the host may resize the editor window. Declare static constexpr EditorResize editorResize = ...; in the plugin class; without it the window is Fixed (or Free if the simpler editorResizable = true shorthand is present).

Enumerator
Fixed 

The window is exactly editorSize; hosts cannot drag-resize it.

Free 

Drag-resizable between 0.5x and 3x the declared size.

KeepAspect 

Drag-resizable, locked to the declared width:height ratio.

Definition at line 641 of file DSParkPlugin.h.

Function Documentation

◆ applyState()

template<typename P >
bool dspark::plugin::applyState ( P &  user,
const uint8_t *  data,
size_t  size,
double *  normalized,
int *  programIndex = nullptr,
int *  bypassState = nullptr 
)
inline

Parses a state blob; fills normalized (defaults pre-loaded by the caller), reports a persisted program index / bypass through programIndex and bypassState (left untouched when absent) and forwards the user section. Returns false on a foreign blob.

Definition at line 935 of file DSParkPlugin.h.

◆ buildState()

template<typename P >
std::vector< uint8_t > dspark::plugin::buildState ( const P &  user,
const double *  normalized,
size_t  numParams,
int  programIndex = -1,
int  bypassState = -1 
)
inline

Definition at line 880 of file DSParkPlugin.h.

◆ channelSupportOf()

template<typename P >
constexpr ChannelSupport dspark::plugin::channelSupportOf ( )
constexprnoexcept

The declared channel support of P (default: mono+stereo).

Definition at line 457 of file DSParkPlugin.h.

◆ constrainEditorSize()

template<typename P >
constexpr void dspark::plugin::constrainEditorSize ( double &  width,
double &  height,
double  scale 
)
constexprnoexcept

Applies the resize policy of P to a size the host proposes: Fixed pins it, Free clamps each axis to the 0.5x..3x window, KeepAspect fits the declared ratio INSIDE the proposal - never exceeding it on either axis. That last property is essential: hosts size the plugin area inside a window the user controls, so answering "larger" on any axis pushes the plugin outside its own window (clipped bottom in REAPER).

Definition at line 710 of file DSParkPlugin.h.

◆ defaultChannelCount()

template<typename P >
constexpr int dspark::plugin::defaultChannelCount ( )
constexprnoexcept

The width every backend starts in before the host negotiates.

Definition at line 477 of file DSParkPlugin.h.

◆ editorResizeOf()

template<typename P >
constexpr EditorResize dspark::plugin::editorResizeOf ( )
constexprnoexcept

The effective resize policy for plugin class P.

Definition at line 687 of file DSParkPlugin.h.

◆ editorSizeOf()

template<typename P >
constexpr EditorSize dspark::plugin::editorSizeOf ( )
constexprnoexcept

The declared (logical) editor size, or the 480x320 default.

Definition at line 664 of file DSParkPlugin.h.

◆ factoryPresetCountOf()

template<typename P >
constexpr int dspark::plugin::factoryPresetCountOf ( )
constexprnoexcept

Number of factory presets of P (0 when none declared).

Definition at line 531 of file DSParkPlugin.h.

◆ formatValue()

void dspark::plugin::formatValue ( const Param p,
double  plain,
char *  out,
int  outSize 
)
inlinenoexcept

Formats a plain value for host display ("3.5 dB", "On", "440 Hz").

Definition at line 188 of file DSParkPlugin.h.

◆ hash32()

constexpr uint32_t dspark::plugin::hash32 ( const char *  s)
constexprnoexcept

FNV-1a 32-bit over a C string - the per-parameter host id.

Definition at line 205 of file DSParkPlugin.h.

◆ hash64()

constexpr uint64_t dspark::plugin::hash64 ( const char *  s,
uint64_t  salt 
)
constexprnoexcept

FNV-1a 64-bit with a salt (two runs build a 128-bit class UID).

Definition at line 217 of file DSParkPlugin.h.

◆ makeUid()

constexpr std::array< uint8_t, 16 > dspark::plugin::makeUid ( const char *  productId,
uint64_t  salt 
)
constexprnoexcept

Deterministic 16-byte class UID from the stable productId. Each backend salts differently so VST3/CLAP/AU ids never collide.

Definition at line 252 of file DSParkPlugin.h.

◆ param()

constexpr Param dspark::plugin::param ( const char *  id,
const char *  name,
float  minValue,
float  maxValue,
float  defValue,
const char *  unit 
)
constexprnoexcept

Continuous parameter helper.

Definition at line 127 of file DSParkPlugin.h.

◆ paramIdsUnique()

template<typename P >
constexpr bool dspark::plugin::paramIdsUnique ( )
constexprnoexcept

Compile-time guarantee that every parameter id hashes uniquely and collides with neither reserved state id ('PRGM', 'BYPS'). A collision would silently cross-wire automation and state between two parameters, so the backends refuse to build: static_assert(paramIdsUnique<MyPlugin>());.

Definition at line 235 of file DSParkPlugin.h.

◆ params()

template<typename... Ps>
constexpr std::array< Param, sizeof...(Ps)> dspark::plugin::params ( Ps...  ps)
constexprnoexcept

Builds the parameter table (use inside static constexpr auto).

Definition at line 142 of file DSParkPlugin.h.

◆ parseToggleText()

int dspark::plugin::parseToggleText ( const char *  text)
inlinenoexcept

Case-insensitive "On"/"Off" recognition - the inverse of the toggle display below. Returns 1 for On, 0 for Off, -1 for anything else. Hosts round-trip displayed strings through text-to-value (automation lanes, typed values), so toggles must parse their own output.

Definition at line 177 of file DSParkPlugin.h.

◆ preset()

template<typename... Vs>
constexpr PresetDef< sizeof...(Vs)> dspark::plugin::preset ( const char *  name,
Vs...  values 
)
constexprnoexcept

Builds one factory preset: preset("Warm", 6.0f, 0.8f, ...) - one PLAIN value per parameter, in table order.

Definition at line 499 of file DSParkPlugin.h.

◆ presetNormalized()

template<typename P >
constexpr double dspark::plugin::presetNormalized ( int  presetIndex,
size_t  paramIndex 
)
constexprnoexcept

Normalized value of parameter paramIndex in factory preset presetIndex (bounds already validated by the caller).

Definition at line 547 of file DSParkPlugin.h.

◆ presets()

template<typename First , typename... Rest>
constexpr std::array< First, 1+sizeof...(Rest)> dspark::plugin::presets ( First  first,
Rest...  rest 
)
constexprnoexcept

Builds the factory preset table (all presets must cover the same parameter count - enforced here; matched against the parameter table by the backends). Declare as static constexpr auto factoryPresets = ....

Definition at line 508 of file DSParkPlugin.h.

◆ sampleAccurateOf()

template<typename P >
constexpr bool dspark::plugin::sampleAccurateOf ( )
constexprnoexcept

Definition at line 577 of file DSParkPlugin.h.

◆ sortBlockEvents()

void dspark::plugin::sortBlockEvents ( BlockEvent events,
int  count 
)
inlinenoexcept

Stable insertion sort by offset (tiny N, allocation-free - audio-thread safe; equal offsets keep arrival order).

Definition at line 611 of file DSParkPlugin.h.

◆ supportsChannelCount()

template<typename P >
constexpr bool dspark::plugin::supportsChannelCount ( int  numChannels)
constexprnoexcept

True when P accepts a bus width of numChannels (1 or 2).

Definition at line 467 of file DSParkPlugin.h.

◆ toggle()

constexpr Param dspark::plugin::toggle ( const char *  id,
const char *  name,
bool  defaultOn 
)
constexprnoexcept

On/off parameter helper.

Definition at line 135 of file DSParkPlugin.h.

◆ toNormalized()

constexpr double dspark::plugin::toNormalized ( const Param p,
double  plain 
)
constexprnoexcept

Plain [min, max] -> normalized [0, 1] (steps snap on the way back).

Definition at line 150 of file DSParkPlugin.h.

◆ toPlain()

constexpr double dspark::plugin::toPlain ( const Param p,
double  normalized 
)
constexprnoexcept

Normalized [0, 1] -> plain [min, max], snapped for stepped params.

Definition at line 159 of file DSParkPlugin.h.

Variable Documentation

◆ kAutomationQuantum

constexpr int dspark::plugin::kAutomationQuantum = 32
inlineconstexpr

Sub-block grain: automation/event splits snap to this many frames (bounds the per-call overhead; ~0.7 ms at 48 kHz is inaudible).

Definition at line 587 of file DSParkPlugin.h.

◆ kBypassStateId

constexpr uint32_t dspark::plugin::kBypassStateId = 0x42595053u
inlineconstexpr

Reserved entry id persisting the host bypass ('BYPS' - the same value every backend uses as the bypass ParamID). Hosts treat bypass as one more parameter, so it must survive a state round-trip like any other. Older builds skip it (unknown id).

Definition at line 877 of file DSParkPlugin.h.

◆ kEditorMaxSizeFactor

constexpr double dspark::plugin::kEditorMaxSizeFactor = 3.0
inlineconstexpr

Definition at line 699 of file DSParkPlugin.h.

◆ kEditorMinSizeFactor

constexpr double dspark::plugin::kEditorMinSizeFactor = 0.5
inlineconstexpr

Resize bounds: hosts may shrink to half and grow to 3x the declared size.

Definition at line 698 of file DSParkPlugin.h.

◆ kMaxBlockEvents

constexpr int dspark::plugin::kMaxBlockEvents = 256
inlineconstexpr

Hard cap of timestamped events handled per block; the (very unlikely) excess applies at the position of the last captured event.

Definition at line 591 of file DSParkPlugin.h.

◆ kProgramStateId

constexpr uint32_t dspark::plugin::kProgramStateId = 0x5052474Du
inlineconstexpr

Reserved entry id persisting the active factory-preset index ('PRGM'); never a user parameter. Older builds skip it (unknown id).

Definition at line 871 of file DSParkPlugin.h.

◆ kStateMagic

constexpr uint32_t dspark::plugin::kStateMagic = 0x4453504Bu
inlineconstexpr

Definition at line 866 of file DSParkPlugin.h.

◆ kStateVersion

constexpr uint32_t dspark::plugin::kStateVersion = 1u
inlineconstexpr

Definition at line 867 of file DSParkPlugin.h.