Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
anticipation_eligibility.hpp
Go to the documentation of this file.
1#pragma once
2
4
5#include <cstdint>
6#include <span>
7#include <vector>
8
9namespace pulp::host {
10
11struct GraphNode;
12struct Connection;
13
14// Why a node may NOT be rendered ahead of the audio deadline. Anticipation
15// pre-computes a latent subgraph's
16// output into a buffer during earlier blocks' slack so a CPU spike is absorbed
17// off the critical block — but only for work whose result for a FUTURE block can
18// be computed from inputs already available, with no dependence on live or
19// host-clock state. A node is eligible only if it (and its entire feedforward
20// dependency cone) is free of every exclusion below.
21enum class AnticipationExclusion : std::uint8_t {
22 None = 0, // anticipation-eligible
23 LiveAudioInput, // is, or transitively reads, a live system AudioInput
24 LiveMidiInput, // is, or transitively reads, a live system MidiInput
25 // (a MIDI-instrument feed — the notes aren't known ahead)
26 Feedback, // participates in, or sits downstream of, a feedback edge
27 // (its own past output gates it; can't run arbitrarily ahead)
28 Sidechain, // has, or transitively reads, a sidechain input (live signal)
29 TransportSensitive, // is, or transitively reads, a node that consumes the
30 // host transport (GraphNode::transport_sensitive). Such
31 // a node must run live to observe the real playhead, so
32 // it (and its downstream cone) cannot be rendered ahead.
33 ExactParameterInput, // owns block-specific exact-generation host automation
34};
35
37 // Per node, indexed exactly like the input `nodes` span: None = passed the
38 // static topology exclusions, otherwise the reason it (or something it depends
39 // on) cannot be anticipated. A node inherits the exclusion of any feedforward
40 // source it depends on.
41 std::vector<AnticipationExclusion> node_exclusion;
42 bool ok = false;
43
44 // `passes_static_exclusions(i)` means node i cleared every exclusion: the
45 // topology hard exclusions (live input / feedback / sidechain) AND
46 // transport sensitivity (a node that opted into the host transport via
47 // GraphNode::transport_sensitive, seeded as TransportSensitive and propagated
48 // over its downstream cone). A true result is therefore sufficient for the
49 // anticipation partition to treat node i as ahead-renderable interior.
50 bool passes_static_exclusions(std::size_t node_index) const {
51 return node_index < node_exclusion.size() &&
53 }
55 for (auto e : node_exclusion) {
56 if (e == AnticipationExclusion::None) return true;
57 }
58 return false;
59 }
60};
61
62// Classify each node's anticipation eligibility from the graph topology plus the
63// per-node transport-sensitivity capability: seed the hard-excluded roots (live
64// AudioInput / MidiInput nodes, the endpoints of every feedback edge, any node
65// with a sidechain inbound edge, and any node with GraphNode::transport_sensitive
66// set), then propagate each exclusion forward along feedforward (non-feedback)
67// edges to a fixpoint, so a node downstream of anything excluded is excluded too.
68// The first reason assigned to a node wins (its own seed reason over an inherited
69// one); "excluded for some reason" is the load-bearing bit, the specific reason
70// is diagnostic. Deterministic and allocation-bounded; no prepared/live graph
71// required. Returns ok=false only on a malformed input (a connection naming a
72// node id absent from `nodes`).
73//
74// Transport sensitivity is the per-node opt-out for host-clock-dependent nodes:
75// `transport_sensitive` is resolved once at compile (from
76// PluginSlot::wants_transport() or a transport-aware custom callback), so seeding
77// TransportSensitive here keeps such a node — and its downstream cone — out of
78// the ahead-rendered interior, letting it run live and observe the real playhead.
80 std::span<const GraphNode> nodes, std::span<const Connection> connections,
81 std::span<const NodeId> exact_parameter_input_nodes = {});
82
83} // namespace pulp::host
Bounded event contracts shared by host ingress and graph-authored nodes.
Definition anticipation_eligibility.hpp:9
AnticipationExclusion
Definition anticipation_eligibility.hpp:21
@ TransportSensitive
Definition anticipation_eligibility.hpp:29
@ LiveMidiInput
Definition anticipation_eligibility.hpp:24
@ LiveAudioInput
Definition anticipation_eligibility.hpp:23
@ None
Definition anticipation_eligibility.hpp:22
@ Feedback
Definition anticipation_eligibility.hpp:26
@ Sidechain
Definition anticipation_eligibility.hpp:28
@ ExactParameterInput
Definition anticipation_eligibility.hpp:33
AnticipationEligibility analyze_anticipation_eligibility(std::span< const GraphNode > nodes, std::span< const Connection > connections, std::span< const NodeId > exact_parameter_input_nodes={})
Definition anticipation_eligibility.hpp:36
bool ok
Definition anticipation_eligibility.hpp:42
std::vector< AnticipationExclusion > node_exclusion
Definition anticipation_eligibility.hpp:41
bool any_passes_static_exclusions() const
Definition anticipation_eligibility.hpp:54
bool passes_static_exclusions(std::size_t node_index) const
Definition anticipation_eligibility.hpp:50
Definition signal_graph_connection.hpp:18
Definition signal_graph_node.hpp:126