Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
custom_node_type.hpp
Go to the documentation of this file.
1#pragma once
2
3// Custom-node extension vocabulary for the Pulp host signal graph. This focused
4// header lets registrars describe custom nodes without importing graph runtime
5// state or execution machinery.
6
10
11#include <cmath>
12#include <cstddef>
13#include <cstdint>
14#include <functional>
15#include <string>
16#include <vector>
17
18namespace pulp::format {
19struct ProcessContext;
20} // namespace pulp::format
21
22namespace pulp::host {
23
24using CustomNodeProcessFn = std::function<void(audio::BufferView<float>& output,
26 int num_samples)>;
27
28// ── Bake-layer parameter injection ──────────────────────────────────────
29//
30// A separate, RT-safe path (owned by BakedGraphProcessor) that lets a control
31// thread set a BAKED custom node's parameter and have it applied sample-
32// accurately in process(), WITHOUT re-baking and without touching the live
33// graph's parameter-ingress path. It reuses pulp::state::ParameterEvent /
34// ParameterEventQueue verbatim and mirrors the live mailbox's precedence and
35// per-node exclusive-claim discipline; see baked_graph_processor.hpp.
36//
37// A lowerable custom node opts in by declaring `baked_params` and providing a
38// `process_instance_baked_param` callback. On a BAKED graph the executor calls
39// that callback instead of process_instance, handing it a BakedParamView it
40// queries for the ramped, sample-accurate value of each declared param. This
41// channel is consulted ONLY on a baked graph; on the live graph the node runs
42// via its plain process_instance/process as usual (a node that provides only
43// the baked callback runs neither live — the routed executor falls through to
44// input passthrough — so it is meant to be baked before use).
45
46// Read-only per-sample parameter accessor handed to a param-aware baked custom
47// node. `value_at(id, k)` returns the ramped, sample-accurate value of a
48// declared param at block-relative sample offset `k`; offsets must be queried
49// in non-decreasing order within a block (the backing cursor advances
50// monotonically). `value(id)` reads the value at the cursor's current position.
52public:
53 virtual ~BakedParamView() = default;
54 virtual float value_at(state::ParamID id, int32_t sample_offset) const = 0;
55 virtual float value(state::ParamID id) const = 0;
56};
57
58// Bound param-aware process callback (instance captured). Same audio signature
59// as CustomNodeProcessFn plus the block's BakedParamView. The baked executor
60// runs this for a param-declaring custom node.
62 std::function<void(audio::BufferView<float>& output,
64 int num_samples,
65 const BakedParamView& params)>;
66
67// One declared parameter of a lowerable custom node, for the bake-layer
68// injection path. `id` is node-local (the framework namespaces per node, so two
69// nodes of the same type never collide). Values are clamped to [min, max];
70// `default_value` is the held value until the first injection arrives.
73 float min_value = 0.0f;
74 float max_value = 1.0f;
75 float default_value = 0.0f;
76};
77
78// Transport-aware custom-node callback (additive). Identical to
79// CustomNodeProcessFn plus the host transport for the block. A custom type that
80// registers one of the transport-aware callbacks below is treated as
81// transport-sensitive: its routed binding forwards the live transport and it is
82// excluded from the anticipation interior so it always runs live (see
83// GraphNode::transport_sensitive).
85 std::function<void(audio::BufferView<float>& output,
87 int num_samples,
88 const format::ProcessContext& transport)>;
89
91 std::string type_id;
92 int version = 1;
95 std::string default_name;
96 CustomNodeProcessFn process; // stateless (used when `create` is empty)
97
98 // Optional stateful lifecycle.
99 // When `create` is set, the graph owns ONE opaque instance per node (RAII
100 // via `destroy`). `process_instance` runs instead of `process`, and
101 // prepare/release/reset/save_state/load_state operate on that instance. All
102 // empty == today's stateless process-only node, byte-for-byte unchanged
103 // (no instance is created and no state is serialized).
104 //
105 // Threading mirrors PluginSlot: create/prepare/release/save_state/load_state
106 // are called on the UI/main thread (never from process()); process_instance
107 // runs on the audio thread and must be real-time-safe. As with plugin
108 // state, call save_state/load_state from non-audio control paths (graph not
109 // live, or after invalidate + re-prepare).
110 //
111 // Parallel routing concurrency: the framework owns one DISTINCT instance per
112 // node, so two nodes of the same type never share instance state. But under
113 // levelized parallel routing, process_instance for sibling nodes in a level
114 // may run on different worker threads at once — so a callback that touches
115 // state SHARED across nodes (e.g. a captured global, not the per-instance
116 // pointer) must itself be concurrent-safe, or that graph must not enable
117 // parallel routing. The per-instance `void*` is always single-threaded.
118 std::function<void*()> create;
119 std::function<void(void* /*instance*/)> destroy;
120 std::function<void(void* /*instance*/, double /*sample_rate*/, int /*max_block*/)> prepare;
121 std::function<void(void* /*instance*/)> release;
122 std::function<void(void* /*instance*/)> reset;
123 std::function<void(void* /*instance*/, audio::BufferView<float>& /*output*/,
124 const audio::BufferView<const float>& /*input*/,
125 int /*num_samples*/)>
127 std::function<std::vector<uint8_t>(void* /*instance*/)> save_state;
128 std::function<bool(void* /*instance*/, const std::vector<uint8_t>& /*bytes*/)> load_state;
129
130 // Optional transport-aware callbacks (additive opt-in). When either is set,
131 // the node is transport-sensitive: the graph forwards the host transport to
132 // it and excludes it from the anticipation interior so it always runs live.
133 // `process_transport` is the stateless variant (used when `create` is empty);
134 // `process_instance_transport` is the stateful variant (leading instance
135 // pointer, used when an instance exists). Both default-empty == today's
136 // transport-unaware node, byte-for-byte unchanged. A type that sets a
137 // transport-aware callback alongside its plain `process`/`process_instance`
138 // gets the transport variant on the routed path; the plain one remains the
139 // fallback when no transport is available for the block.
141 std::function<void(void* /*instance*/, audio::BufferView<float>& /*output*/,
142 const audio::BufferView<const float>& /*input*/,
143 int /*num_samples*/, const format::ProcessContext& /*transport*/)>
145
146 // Bake opt-in: whether this type may be LOWERED into a baked artifact.
147 // Default false → bake refuses (a custom instance holds opaque state a frozen
148 // topology cannot otherwise capture). Setting true is a registrar assertion
149 // that the type is deterministic given (state, input), holds no ambient mutable
150 // global state (only the per-instance void*), round-trips completely through
151 // save_state/load_state, is real-time-safe, and is NOT transport-sensitive.
152 // This is a trusted-binary / developer boundary only — NOT a shipped-artifact
153 // security boundary (the framework cannot verify these properties), so the
154 // on-disk load path must additionally require a signature before honoring it.
155 bool lowerable = false;
156
157 // Bake-layer parameter injection (additive opt-in). When `baked_params` is
158 // non-empty AND `process_instance_baked_param` is set, a BAKED instance of
159 // this node can receive sample-accurate ParameterEvents from the control
160 // thread via BakedGraphProcessor::inject(); the baked executor runs
161 // `process_instance_baked_param` (leading instance pointer) instead of
162 // process_instance, handing it a BakedParamView over the injected values.
163 // Both empty == today's node, unchanged: no injection channel, runs via
164 // process_instance. This path is independent of the live-graph parameter
165 // ingress and does not require re-baking to turn a knob.
166 //
167 // Live-graph behavior: `process_instance_baked_param` is consulted ONLY on a
168 // baked graph. A node that provides ONLY this callback (no plain
169 // process/process_instance) does NOT run its baked-param DSP on the live
170 // graph — with no live callback the routed executor falls through to input
171 // passthrough (transparent; it contributes no signal of its own, but is not
172 // hard silence when fed a signal). Such a node is meant to be baked before
173 // use; provide a plain process callback too if it must also run live.
174 std::vector<CustomNodeBakedParam> baked_params;
175 std::function<void(void* /*instance*/, audio::BufferView<float>& /*output*/,
176 const audio::BufferView<const float>& /*input*/,
177 int /*num_samples*/, const BakedParamView& /*params*/)>
179
180 // Prepare-stable intrinsic latency metadata. Evaluated once, off the audio
181 // thread, at the graph's sample rate during compilation; the non-negative
182 // result feeds both the legacy and routed PDC plans. The callback must depend
183 // only on registration-time realization choices and `sample_rate` — a
184 // control that can change it requires a new type / re-prepare. Empty
185 // preserves the historical zero-latency custom-node contract.
186 //
187 // A callback rather than a fixed count because intrinsic latency is
188 // routinely rate-dependent: a lookahead declared in milliseconds and an
189 // oversampler's half-band group delay both resolve to different sample
190 // counts per rate, so a fixed count could only ever be right at one of them.
191 // A rate-independent latency stays expressible as `[](double) { return n; }`.
192 //
193 // Kept after the historical callbacks to preserve source compatibility for
194 // positional aggregate initializers written before the latency contract was
195 // added. The graph captures it at prepare; changing it requires
196 // re-registration/re-prepare and an identity version bump for persisted
197 // graphs.
198 //
199 // The EVALUATED result is range-checked against `kMaxLatencySamples` at
200 // compile time. It cannot be checked at registration, because it is not
201 // known until the sample rate is.
202 static constexpr int kMaxLatencySamples = 65535;
203 std::function<int(double /*sample_rate*/)> latency_samples;
204
205 // Optional block-aware latency contract. This is used by nodes whose
206 // fixed scheduling lead is expressed in host quanta (for example a GPU
207 // transport with a two-block lead). The graph captures max_block_size
208 // during prepare/compile, off the audio thread; it is never queried from
209 // process(). When present it takes precedence over latency_samples.
210 // Kept after the historical callback for aggregate-initializer
211 // compatibility.
212 std::function<int(double /*sample_rate*/, int /*max_block_size*/)> latency_samples_for_block;
213
214 // Optional event-aware process callbacks. The graph already gathers a node's
215 // inbound MIDI before the executor dispatches on binding kind; these are how
216 // a Custom node reads it. Kept after the historical callbacks so positional
217 // aggregate initializers written before the event lane stay valid. The block
218 // and callback types live in custom_node_events.hpp.
221
222 // True when this type declares a usable event-aware execution path.
223 // DERIVED from callback presence rather than stored as a flag, so it can
224 // never disagree with the callbacks it describes.
225 bool consumes_events() const noexcept {
226 return static_cast<bool>(process_events) ||
227 (static_cast<bool>(create) && static_cast<bool>(process_instance_events));
228 }
229
230 bool is_valid_registration() const noexcept {
231 const bool has_plain_callback =
232 static_cast<bool>(process) ||
233 (static_cast<bool>(create) && static_cast<bool>(process_instance));
234 const bool has_transport_callback =
235 static_cast<bool>(process_transport) ||
236 (static_cast<bool>(create) &&
237 static_cast<bool>(process_instance_transport));
238 // A latent transport-aware execution path must have a resolvable plain
239 // fallback: PDC is prepare-stable and cannot change when a block gains
240 // or loses a transport context. Declaring ANY latency callback is the
241 // registration-time stand-in for a non-zero fixed latency, since the
242 // value itself is not resolvable this early.
243 if (type_id.empty() || version <= 0 || num_input_ports < 0 || num_output_ports < 0 ||
244 ((latency_samples || latency_samples_for_block) && has_transport_callback &&
245 !has_plain_callback)) {
246 return false;
247 }
248
249 // A stateful event callback needs a complete instance lifecycle, exactly
250 // as the stateful transport and baked-param callbacks do.
251 if (process_instance_events && (!create || !destroy)) return false;
252
253 // The bake layer carries no event plane, so a lowered event-aware node
254 // would run its audio silently MIDI-less instead of failing. Refuse the
255 // combination at registration, where it is still visible.
256 if (lowerable && consumes_events()) return false;
257
258 // Transport-aware and event-aware execution in one type would need a
259 // dispatch precedence the binding does not define. Carrying transport on
260 // the event block is what lifts this.
261 if (consumes_events() && has_transport_callback) return false;
262
263 // Bake-layer obligations live here too, so that every registrar — the
264 // direct one, the transactional edit, and the node-adding leaf — applies
265 // ONE rule. A descriptor that passes shape but declares an incoherent
266 // bake surface would otherwise stay `lowerable`, be accepted by baking,
267 // and silently degrade to passthrough.
268 const bool declares_baked_params = !baked_params.empty();
269 const bool has_baked_param_process =
270 static_cast<bool>(process_instance_baked_param);
271 if (declares_baked_params != has_baked_param_process) return false;
272
273 if (declares_baked_params) {
274 // The callback takes an instance pointer, so a parameter-aware baked
275 // type without a complete instance lifecycle can never produce the
276 // runnable binding that bake() promises.
277 if (!create || !destroy) return false;
278 for (std::size_t i = 0; i < baked_params.size(); ++i) {
279 const auto& param = baked_params[i];
280 if (param.id == 0
281 || !std::isfinite(param.min_value)
282 || !std::isfinite(param.max_value)
283 || !std::isfinite(param.default_value)
284 || param.min_value > param.max_value
285 || param.default_value < param.min_value
286 || param.default_value > param.max_value) {
287 return false;
288 }
289 for (std::size_t j = 0; j < i; ++j) {
290 if (baked_params[j].id == param.id) return false;
291 }
292 }
293 }
294
295 if (lowerable) {
296 if (create) {
297 if (!destroy || (!process_instance && !has_baked_param_process)) {
298 return false;
299 }
300 } else if (!process) {
301 return false;
302 }
303 }
304 return true;
305 }
306};
307
308// ── Sample-region scalar callback ABI ─────────────────────────────────
309// This is a sibling contract rather than part of CustomNodeType so the
310// historical aggregate layout and positional initializers remain unchanged.
311
312static_assert(sizeof(float) == 4 && alignof(float) == 4,
313 "sample-kernel ABI requires 32-bit, 4-byte-aligned float");
314
315enum class SampleKernelCausality : std::uint8_t {
318};
319
320enum class SampleKernelScope : std::uint8_t {
322};
323
331
337
345
351
357
359 const float* promoted_values = nullptr;
360 std::uint32_t promoted_value_count = 0;
361 std::uint32_t sample_offset = 0;
362};
363
364using SampleKernelConstructFn = bool (*)(void* state,
365 const SampleKernelPrepareContext& context) noexcept;
366using SampleKernelResetFn = void (*)(void* state) noexcept;
367using SampleKernelDestroyFn = void (*)(void* state) noexcept;
368using SampleKernelProcessFn = void (*)(void* state, const PreparedSampleKernelConfig& config,
369 const SampleFrameContext& frame, const float* inputs,
370 float* outputs) noexcept;
371using SampleDelayPublishFn = void (*)(const void* state, const PreparedSampleKernelConfig& config,
372 float* outputs) noexcept;
373using SampleDelayCommitFn = void (*)(void* state, const PreparedSampleKernelConfig& config,
374 const float* inputs) noexcept;
375
377 std::string category;
378 std::string parameter;
379 std::string units;
380 float minimum_value = 0.0f;
381 float maximum_value = 0.0f;
382 bool has_value_range = false;
383 std::uint64_t capability_flags = 0;
384};
385
410
411// Validates the runtime non-aliasing precondition before invoking a scalar
412// callback. Zero-sized ranges may be null; every non-zero range must be present.
414 const PreparedSampleKernelConfig& config,
415 const SampleFrameContext& frame, const float* inputs,
416 float* outputs) noexcept;
417
418// Callback-free description returned by SignalGraph's custom-type discovery
419// API. Every field owns its storage, including the nested parameter list, so a
420// caller may retain a snapshot after the registry or graph has been destroyed.
421// Keep this separate from CustomNodeType: registrars commonly initialize that
422// aggregate positionally, and discovery must never expose executable callbacks.
424 std::string type_id;
425 int version = 1;
428 std::string default_name;
429 bool lowerable = false;
430 std::vector<CustomNodeBakedParam> baked_params;
431 // Mirrors CustomNodeType::consumes_events() for a registered type, so an
432 // edge validator can ask whether a resolved destination reads events
433 // without holding the callbacks themselves.
434 bool consumes_events = false;
435};
436
437} // namespace pulp::host
Non-owning view over multi-channel audio sample data.
Definition buffer.hpp:30
Definition custom_node_type.hpp:51
virtual float value_at(state::ParamID id, int32_t sample_offset) const =0
virtual ~BakedParamView()=default
virtual float value(state::ParamID id) const =0
The event block a Custom graph node receives, and the callback types that take it.
What the product grants a device: the quota table indexed by capability tier and live thermal state.
Definition aax_editor.hpp:31
Bounded event contracts shared by host ingress and graph-authored nodes.
Definition anticipation_eligibility.hpp:9
SampleKernelConfigKind
Definition custom_node_type.hpp:324
@ Invalid
Definition custom_node_type.hpp:325
@ BoundaryIndex
Definition custom_node_type.hpp:327
@ PromotedParameterId
Definition custom_node_type.hpp:329
@ FiniteConstant
Definition custom_node_type.hpp:328
@ None
Definition anticipation_eligibility.hpp:22
void(*)(void *state) noexcept SampleKernelDestroyFn
Definition custom_node_type.hpp:367
std::function< void(audio::BufferView< float > &output, const audio::BufferView< const float > &input, int num_samples, const CustomNodeEventBlock &events)> CustomNodeEventProcessFn
Stateless event-aware process callback.
Definition custom_node_events.hpp:62
std::function< void(audio::BufferView< float > &output, const audio::BufferView< const float > &input, int num_samples, const BakedParamView &params)> CustomNodeParamProcessFn
Definition custom_node_type.hpp:61
SampleKernelCausality
Definition custom_node_type.hpp:315
@ OneSampleDelay
Definition custom_node_type.hpp:317
@ Combinational
Definition custom_node_type.hpp:316
bool(*)(void *state, const SampleKernelPrepareContext &context) noexcept SampleKernelConstructFn
Definition custom_node_type.hpp:364
bool sample_kernel_storage_is_disjoint(const SampleKernelDescriptor &descriptor, const void *state, const PreparedSampleKernelConfig &config, const SampleFrameContext &frame, const float *inputs, float *outputs) noexcept
void(*)(const void *state, const PreparedSampleKernelConfig &config, float *outputs) noexcept SampleDelayPublishFn
Definition custom_node_type.hpp:371
std::function< void(audio::BufferView< float > &output, const audio::BufferView< const float > &input, int num_samples, const format::ProcessContext &transport)> CustomNodeTransportProcessFn
Definition custom_node_type.hpp:84
std::function< void(audio::BufferView< float > &output, const audio::BufferView< const float > &input, int num_samples)> CustomNodeProcessFn
Definition custom_node_type.hpp:24
void(*)(void *state, const PreparedSampleKernelConfig &config, const SampleFrameContext &frame, const float *inputs, float *outputs) noexcept SampleKernelProcessFn
Definition custom_node_type.hpp:368
void(*)(void *state) noexcept SampleKernelResetFn
Definition custom_node_type.hpp:366
SampleKernelScope
Definition custom_node_type.hpp:320
@ RegionOnly
Definition custom_node_type.hpp:321
void(*)(void *state, const PreparedSampleKernelConfig &config, const float *inputs) noexcept SampleDelayCommitFn
Definition custom_node_type.hpp:373
PreparedSampleKernelConfigKind
Definition custom_node_type.hpp:338
@ Invalid
Definition custom_node_type.hpp:339
@ PromotedParameterIndex
Definition custom_node_type.hpp:343
std::function< void(void *instance, audio::BufferView< float > &output, const audio::BufferView< const float > &input, int num_samples, const CustomNodeEventBlock &events)> CustomNodeInstanceEventProcessFn
Stateful event-aware process callback.
Definition custom_node_events.hpp:69
SequencerStateChannel is the audio-safe transport for a plugin's structured NON-parameter state: the ...
Definition audio_device_manager.hpp:48
uint32_t ParamID
Unique parameter identifier, stable across plugin versions.
Definition parameter.hpp:55
Process context — passed every audio callback with transport state.
Definition process_context.hpp:89
Definition custom_node_type.hpp:71
float min_value
Definition custom_node_type.hpp:73
float max_value
Definition custom_node_type.hpp:74
float default_value
Definition custom_node_type.hpp:75
Definition custom_node_type.hpp:423
int num_input_ports
Definition custom_node_type.hpp:426
int num_output_ports
Definition custom_node_type.hpp:427
std::string default_name
Definition custom_node_type.hpp:428
std::string type_id
Definition custom_node_type.hpp:424
bool lowerable
Definition custom_node_type.hpp:429
bool consumes_events
Definition custom_node_type.hpp:434
std::vector< CustomNodeBakedParam > baked_params
Definition custom_node_type.hpp:430
int version
Definition custom_node_type.hpp:425
Definition custom_node_type.hpp:90
std::function< void(void *)> destroy
Definition custom_node_type.hpp:119
std::string default_name
Definition custom_node_type.hpp:95
std::function< void(void *)> reset
Definition custom_node_type.hpp:122
CustomNodeProcessFn process
Definition custom_node_type.hpp:96
std::function< void(void *)> release
Definition custom_node_type.hpp:121
std::vector< CustomNodeBakedParam > baked_params
Definition custom_node_type.hpp:174
std::function< void(void *, double, int)> prepare
Definition custom_node_type.hpp:120
std::function< void(void *, audio::BufferView< float > &, const audio::BufferView< const float > &, int, const BakedParamView &)> process_instance_baked_param
Definition custom_node_type.hpp:178
std::function< int(double, int)> latency_samples_for_block
Definition custom_node_type.hpp:212
bool is_valid_registration() const noexcept
Definition custom_node_type.hpp:230
CustomNodeTransportProcessFn process_transport
Definition custom_node_type.hpp:140
std::function< void *()> create
Definition custom_node_type.hpp:118
CustomNodeInstanceEventProcessFn process_instance_events
Definition custom_node_type.hpp:220
std::function< void(void *, audio::BufferView< float > &, const audio::BufferView< const float > &, int)> process_instance
Definition custom_node_type.hpp:126
std::function< void(void *, audio::BufferView< float > &, const audio::BufferView< const float > &, int, const format::ProcessContext &)> process_instance_transport
Definition custom_node_type.hpp:144
std::function< bool(void *, const std::vector< uint8_t > &)> load_state
Definition custom_node_type.hpp:128
static constexpr int kMaxLatencySamples
Definition custom_node_type.hpp:202
int version
Definition custom_node_type.hpp:92
std::string type_id
Definition custom_node_type.hpp:91
std::function< int(double)> latency_samples
Definition custom_node_type.hpp:203
CustomNodeEventProcessFn process_events
Definition custom_node_type.hpp:219
bool lowerable
Definition custom_node_type.hpp:155
int num_output_ports
Definition custom_node_type.hpp:94
bool consumes_events() const noexcept
Definition custom_node_type.hpp:225
int num_input_ports
Definition custom_node_type.hpp:93
std::function< std::vector< uint8_t >(void *)> save_state
Definition custom_node_type.hpp:127
Definition custom_node_type.hpp:346
std::uint32_t boundary_or_parameter_index
Definition custom_node_type.hpp:348
PreparedSampleKernelConfigKind kind
Definition custom_node_type.hpp:347
float constant
Definition custom_node_type.hpp:349
Definition custom_node_type.hpp:358
std::uint32_t promoted_value_count
Definition custom_node_type.hpp:360
std::uint32_t sample_offset
Definition custom_node_type.hpp:361
const float * promoted_values
Definition custom_node_type.hpp:359
Definition custom_node_type.hpp:332
float constant
Definition custom_node_type.hpp:335
SampleKernelConfigKind kind
Definition custom_node_type.hpp:333
std::uint32_t boundary_index_or_parameter_id
Definition custom_node_type.hpp:334
Definition custom_node_type.hpp:386
SampleKernelMetadata metadata
Definition custom_node_type.hpp:406
SampleKernelProcessFn process
Definition custom_node_type.hpp:402
SampleDelayCommitFn delay_commit
Definition custom_node_type.hpp:404
std::uint32_t state_alignment
Definition custom_node_type.hpp:398
std::string type_id
Definition custom_node_type.hpp:390
SampleKernelResetFn reset
Definition custom_node_type.hpp:400
SampleDelayPublishFn delay_publish
Definition custom_node_type.hpp:403
SampleKernelConfigKind authored_config_kind
Definition custom_node_type.hpp:396
SampleKernelCausality causality
Definition custom_node_type.hpp:394
SampleKernelScope scope
Definition custom_node_type.hpp:395
std::uint32_t num_input_ports
Definition custom_node_type.hpp:392
std::uint32_t state_size
Definition custom_node_type.hpp:397
std::uint32_t num_output_ports
Definition custom_node_type.hpp:393
SampleKernelConstructFn construct
Definition custom_node_type.hpp:399
std::uint32_t abi_version
Definition custom_node_type.hpp:389
std::uint32_t latency_samples
Definition custom_node_type.hpp:405
static constexpr std::uint32_t kAbiVersion
Definition custom_node_type.hpp:387
bool is_valid_registration() const noexcept
int version
Definition custom_node_type.hpp:391
SampleKernelDestroyFn destroy
Definition custom_node_type.hpp:401
Definition custom_node_type.hpp:376
std::string category
Definition custom_node_type.hpp:377
std::uint64_t capability_flags
Definition custom_node_type.hpp:383
bool has_value_range
Definition custom_node_type.hpp:382
float maximum_value
Definition custom_node_type.hpp:381
std::string parameter
Definition custom_node_type.hpp:378
std::string units
Definition custom_node_type.hpp:379
float minimum_value
Definition custom_node_type.hpp:380
Definition custom_node_type.hpp:352
PreparedSampleKernelConfig config
Definition custom_node_type.hpp:355
std::uint32_t max_block_size
Definition custom_node_type.hpp:354
double sample_rate
Definition custom_node_type.hpp:353