Skip to content

Struct AudityExecContext

Everything a table-dispatched node’s exec function may touch this block. DarkEffekt.Audity.AudityExecContext.engine is the executor state (engine-internal; built-in defs reach it via Engine()). Deliberately absent: the control pipe and generator arguments - they are ref structs that cannot cross the function-pointer boundary, so the nodes that need them (Output, WavePlayer) run as direct engine calls instead of through the table.

Declaration
public struct AudityExecContext

Engine sample rate for this instance.

Declaration
public int SampleRate { get; }

The instance’s local sample clock: engine frames since instance start, at this block’s first frame. Trigger frame offsets are relative to this, so LocalFrame + offset is a trigger’s absolute local time.

Declaration
public long LocalFrame { get; }

Upper bound of trigger offsets a pin can carry per block.

Declaration
public static int MaxTriggersPerBlock { get; }

True once the instance has been asked to stop. Terminal: it never clears. A node that schedules future triggers (a repeater, a delay line’s pending list) must check this each block and cancel its schedule, or it will keep conjuring sound under the stop fade.

Declaration
public bool Stopping { get; }

The instance’s deterministic random stream, shared by every random node and consumed in executor order: the same program with the same seed replays the same values (the sonic-stability contract). Draw only from exec, never speculatively - an extra draw shifts every consumer after you.

Declaration
public ref Random Random { get; }

The instance’s seed (pinned by the author or salted per play). For a node that wants a PRIVATE random stream instead of DarkEffekt.Audity.AudityExecContext.Random: keep a Random in your State<T>, and on first exec seed it from a hash of this and something node-local. A private stream survives graph edits that would reorder the shared stream’s draws.

Declaration
public uint InstanceSeed { get; }
Declaration
public RealtimeContext realtimeContext
Declaration
public int frames
Declaration
public byte firstBlock

Default per-node state size in bytes when a def does not override DarkEffekt.Audity.AudityNodeDef.StateBytes: 16 floats, the classic DarkEffekt.Audity.AudityExecContext.UserState(DarkEffekt.Audity.AudityNodeDesc%40) scratch.

Declaration
public const int DefaultStateBytes = 64

Seconds to engine frames, the way every built-in seconds-valued input reads: NaN/Inf/negative collapse to 0, single-precision multiply (authored periods round the way the engine always rounded them), capped short of overflow.

Declaration
public long SecondsToFrames(float seconds)

System.Int64

Type Name
System.Single seconds

A float input pin’s block-rate value (fallback when unconnected).

Declaration
public float ReadFloat(in AudityNodeDesc node, int inputPin)

System.Single

Type Name
DarkEffekt.Audity.AudityNodeDesc node
System.Int32 inputPin

ReadFloat(in AudityNodeDesc, int, float, float)

Section titled “ReadFloat(in AudityNodeDesc, int, float, float)”

DarkEffekt.Audity.AudityExecContext.ReadFloat(DarkEffekt.Audity.AudityNodeDesc%40%2cSystem.Int32) clamped to the pin’s safe operating range. Wires can carry anything (LFO excursions, math results, live parameters) - the authoring-side [Range] only bounds the inline default, so sanitize every wired read against the DSP’s real limits, which may be wider than the authoring hint (e.g. a filter’s stability bound).

Declaration
public float ReadFloat(in AudityNodeDesc node, int inputPin, float min, float max)

System.Single

Type Name
DarkEffekt.Audity.AudityNodeDesc node
System.Int32 inputPin
System.Single min
System.Single max

ReadRamp(in AudityNodeDesc, int, float, out float, out float)

Section titled “ReadRamp(in AudityNodeDesc, int, float, out float, out float)”

Reads a float input as a block ramp - the engine-standard zipper for click-free block-rate parameter moves. current is the value to apply this block (already transformed - dB to linear, clamped, whatever the node’s law is); start comes back as the previous block’s applied value (or current on the first read, so nothing sweeps in from silence) and end as current, which is recorded for the next block.

Declaration
public void ReadRamp(in AudityNodeDesc node, int inputPin, float current, out float start, out float end)
Type Name
DarkEffekt.Audity.AudityNodeDesc node
System.Int32 inputPin
System.Single current
System.Single start
System.Single end

Writes a float output pin’s block-rate value.

Declaration
public void WriteFloat(in AudityNodeDesc node, int outputPin, float value)
Type Name
DarkEffekt.Audity.AudityNodeDesc node
System.Int32 outputPin
System.Single value

A Float input pin read at its resolved width (unused lanes 0), adapting the producer Shader Graph-style: scalars splat, narrower pads 0, wider truncates.

Declaration
public float4 ReadVec(in AudityNodeDesc node, int inputPin, out int width)

Unity.Mathematics.float4

Type Name
DarkEffekt.Audity.AudityNodeDesc node
System.Int32 inputPin
System.Int32 width

WriteVec(in AudityNodeDesc, int, float4, int)

Section titled “WriteVec(in AudityNodeDesc, int, float4, int)”

Writes a Float output pin’s first width lanes (the pin’s resolved width).

Declaration
public void WriteVec(in AudityNodeDesc node, int outputPin, float4 value, int width)
Type Name
DarkEffekt.Audity.AudityNodeDesc node
System.Int32 outputPin
Unity.Mathematics.float4 value
System.Int32 width

Resolved value width of a Float output pin.

Declaration
public int OutWidth(in AudityNodeDesc node, int outputPin)

System.Int32

Type Name
DarkEffekt.Audity.AudityNodeDesc node
System.Int32 outputPin

A Float output pin’s lanes as writable memory - the wide counterpart of DarkEffekt.Audity.AudityExecContext.WriteVec(DarkEffekt.Audity.AudityNodeDesc%40%2cSystem.Int32%2cUnity.Mathematics.float4%2cSystem.Int32), for pins past the 4 a float4 holds (a Spectrum Analyzer’s bands). The span is exactly the pin’s resolved width; every lane is the exec’s to fill, and stale lanes are never cleared for you.

Declaration
public Span<float> ValueOut(in AudityNodeDesc node, int outputPin)

System.Span<System.Single>

Type Name
DarkEffekt.Audity.AudityNodeDesc node
System.Int32 outputPin

ReadValues(in AudityNodeDesc, int, Span<float>)

Section titled “ReadValues(in AudityNodeDesc, int, Span<float>)”

Copies a Float input pin’s lanes into dest and returns how many it wrote - the wide counterpart of DarkEffekt.Audity.AudityExecContext.ReadVec(DarkEffekt.Audity.AudityNodeDesc%40%2cSystem.Int32%2cSystem.Int32%40), adapting the producer by the same rules (scalars splat across the whole span, narrower pads 0, wider truncates to dest’s length). Size dest with DarkEffekt.Audity.AudityNodeSpec.MaxValueWidth when the width is not known up front.

Declaration
public int ReadValues(in AudityNodeDesc node, int inputPin, Span<float> dest)

System.Int32

Type Name
DarkEffekt.Audity.AudityNodeDesc node
System.Int32 inputPin
System.Span<System.Single> dest

An audio input pin’s interleaved block (frames × channels); empty when the pin is unconnected (render silence or pass through, per node policy).

Declaration
public Span<float> AudioIn(in AudityNodeDesc node, int inputPin, out int channels)

System.Span<System.Single>

Type Name
DarkEffekt.Audity.AudityNodeDesc node
System.Int32 inputPin
System.Int32 channels

An audio output pin’s interleaved block (frames × channels).

Declaration
public Span<float> AudioOut(in AudityNodeDesc node, int outputPin, out int channels)

System.Span<System.Single>

Type Name
DarkEffekt.Audity.AudityNodeDesc node
System.Int32 outputPin
System.Int32 channels

GatherTriggers(in AudityNodeDesc, int, Span<int>)

Section titled “GatherTriggers(in AudityNodeDesc, int, Span<int>)”

Collects a trigger input pin’s frame offsets for this block, ascending. Size frameOffsets with DarkEffekt.Audity.AudityExecContext.MaxTriggersPerBlock.

Declaration
public int GatherTriggers(in AudityNodeDesc node, int inputPin, Span<int> frameOffsets)

System.Int32

Type Name
DarkEffekt.Audity.AudityNodeDesc node
System.Int32 inputPin
System.Span<System.Int32> frameOffsets

Emits on a trigger output pin at a frame offset within this block.

Declaration
public void EmitTrigger(in AudityNodeDesc node, int outputPin, int frameOffset)
Type Name
DarkEffekt.Audity.AudityNodeDesc node
System.Int32 outputPin
System.Int32 frameOffset

A value from this node’s param blob (layout is the def’s contract).

Declaration
public float NodeParam(in AudityNodeDesc node, int index)

System.Single

Type Name
DarkEffekt.Audity.AudityNodeDesc node
System.Int32 index

This node’s whole param blob (layout is the def’s contract).

Declaration
public ReadOnlySpan<float> NodeParams(in AudityNodeDesc node)

System.ReadOnlySpan<System.Single>

Type Name
DarkEffekt.Audity.AudityNodeDesc node

Number of floats in this node’s param blob.

Declaration
public int NodeParamCount(in AudityNodeDesc node)

System.Int32

Type Name
DarkEffekt.Audity.AudityNodeDesc node

This node’s per-instance DSP state, reinterpreted as T (phase accumulators, filter memories, envelope stages). Zeroed at instance start; persists across blocks for the life of the instance. The def declares the size via DarkEffekt.Audity.AudityNodeDef.StateBytes; T must fit inside it. Layout is the def’s own contract with itself.

Declaration
public ref T State<T>(in AudityNodeDesc node) where T : unmanaged

<T>

Type Name
DarkEffekt.Audity.AudityNodeDesc node
  • T

This node’s per-instance DSP state as floats (DarkEffekt.Audity.AudityNodeDef.StateBytes / 4 of them; 16 by default). The untyped view of the same memory DarkEffekt.Audity.AudityExecContext.State%60%601(DarkEffekt.Audity.AudityNodeDesc%40) reinterprets - use whichever fits the node.

Declaration
public Span<float> UserState(in AudityNodeDesc node)

System.Span<System.Single>

Type Name
DarkEffekt.Audity.AudityNodeDesc node

This node’s DSP-pool region: DarkEffekt.Audity.AudityNodeDef.DspSecondsPerChannel(System.Single%5b%5d) seconds per resolved channel of float memory (delay lines, reverb tanks), sized at Configure. Empty when the def declares none. Contents survive across blocks; layout inside the region is the exec’s own business.

Declaration
public Span<float> DspRegion(in AudityNodeDesc node)

System.Span<System.Single>

Type Name
DarkEffekt.Audity.AudityNodeDesc node

Declares this node still-active for this block’s finish gate: a non-idle envelope, a scheduled future trigger, a running repeater. A finite instance will not finish during a block in which any node held it. The engine clears the hold before each block’s exec - assert it every block the condition holds.

Declaration
public void HoldFinish()

Counts triggers this node had to drop (per-block capacity overflow, see DarkEffekt.Audity.AudityExecContext.MaxTriggersPerBlock) into the instance’s telemetry.

Declaration
public void ReportDroppedTriggers(int count)
Type Name
System.Int32 count

Holds a finite instance open for tailFrames engine frames past the start of this block: an effect whose memory still carries audible signal (an echo not yet landed, a decaying tank) reports its tail here so the instance cannot finish out from under it. Re-arm every block while the tail is audible; the hold lapses on its own once you stop.

Declaration
public void HoldTail(long tailFrames)
Type Name
System.Int64 tailFrames

Requests a voice for this player, starting at startFrame within the block (sample-accurate). When the pool is full the declared steal policy applies. Returns an invalid handle if refused (Reject policy) or the node is not a voice-player. Per-voice scratch (DarkEffekt.Audity.AudityExecContext.VoiceState(DarkEffekt.Audity.AudityVoiceHandle)) is zeroed on spawn.

Declaration
public AudityVoiceHandle SpawnVoice(in AudityNodeDesc node, int startFrame)

DarkEffekt.Audity.AudityVoiceHandle

Type Name
DarkEffekt.Audity.AudityNodeDesc node
System.Int32 startFrame

Retires a voice, freeing its pool slot. Emit any onFinished trigger yourself (via DarkEffekt.Audity.AudityExecContext.EmitTrigger(DarkEffekt.Audity.AudityNodeDesc%40%2cSystem.Int32%2cSystem.Int32)) before calling this.

Declaration
public void FinishVoice(AudityVoiceHandle voice)
Type Name
DarkEffekt.Audity.AudityVoiceHandle voice

Enumerates this player’s currently-playing voices (foreach-able, no allocation).

Declaration
public AudityVoiceEnumerator LiveVoices(in AudityNodeDesc node)

DarkEffekt.Audity.AudityVoiceEnumerator

Type Name
DarkEffekt.Audity.AudityNodeDesc node

Per-voice scratch (DarkEffekt.Audity.WaveVoice.VoiceUserFloats floats, zeroed on spawn) - the voice’s phase, envelope, pitch, etc. Persists while the voice lives.

Declaration
public Span<float> VoiceState(AudityVoiceHandle voice)

System.Span<System.Single>

Type Name
DarkEffekt.Audity.AudityVoiceHandle voice

The block-frame offset at which this voice starts rendering this block (its spawn offset on the first block; 0 thereafter).

Declaration
public int VoiceStartFrame(AudityVoiceHandle voice)

System.Int32

Type Name
DarkEffekt.Audity.AudityVoiceHandle voice