Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
signal_graph_prepared_topology_edit.hpp
Go to the documentation of this file.
1#pragma once
2
5
6#include <optional>
7
8namespace pulp::host {
9
10namespace detail {
11struct QuiescedPluginLifecycle;
12struct QuiescedCustomLifecycle;
13struct QuiescedProcessorLifecycle;
14} // namespace detail
15
20class ExactParameterNodeClaimPasskey {
21 ExactParameterNodeClaimPasskey() = default;
23};
24
25// Isolated, fail-closed authoring transaction for topology-producing clients.
26// This exposes only nodes that SignalGraph owns and can prepare off-side.
28 public:
53
57
60 bool unregister_custom_node_type(std::string_view type_id, int version);
62 std::size_t custom_node_type_count() const;
63
64 NodeId add_input_node(int channels, const std::string& name = "Input");
66 const std::string& name) {
67 if (prepare_attempted_ || committed_)
68 return {std::nullopt, SpectralError::Busy};
69 return candidate_->add_spectral_analysis(identity, name);
70 }
73 const std::string& name) {
74 if (prepare_attempted_ || committed_)
75 return {std::nullopt, SpectralError::Busy};
76 return candidate_->add_spectral_stage(identity, std::move(stage), name);
77 }
79 const std::string& name) {
80 if (prepare_attempted_ || committed_)
81 return {std::nullopt, SpectralError::Busy};
82 return candidate_->add_spectral_synthesis(identity, name);
83 }
85 if (prepare_attempted_ || committed_)
86 return {GraphResult::Code::UnknownPort, 0, 0, "edit is immutable", {}};
87 return candidate_->connect(source, destination);
88 }
89 GraphResult connect(const PortHandle& source, const PortHandle& destination) {
90 if (prepare_attempted_ || committed_)
91 return {GraphResult::Code::UnknownPort, 0, 0, "edit is immutable", {}};
92 return candidate_->connect(source, destination);
93 }
94 NodeId add_output_node(int channels, const std::string& name = "Output");
95 NodeId add_gain_node(const std::string& name = "Gain");
96 NodeId add_midi_input_node(const std::string& name = "MIDI In");
97 NodeId add_midi_output_node(const std::string& name = "MIDI Out");
99 NodeId add_owned_builtin_plugin_node(std::unique_ptr<PluginSlot> slot, int num_inputs,
100 int num_outputs, const std::string& name);
101 NodeId add_processor_node(std::shared_ptr<format::ProcessorNodeInstance> processor,
102 const std::string& name = {});
103 NodeId add_processor_node(std::unique_ptr<format::Processor> processor,
104 const std::string& name = {});
105 NodeId add_custom_node(std::string_view type_id, const std::string& name = {});
106 NodeId add_custom_node(std::string_view type_id, int version,
107 const std::string& name = {});
108 NodeId add_unresolved_custom_node(std::string_view type_id, int version,
109 int num_inputs, int num_outputs,
110 const std::string& name);
112 bool connect(NodeId source, PortIndex source_port, NodeId dest, PortIndex dest_port);
113 bool connect_automation(NodeId source, PortIndex source_port, NodeId dest,
114 uint32_t dest_param_id, float range_lo, float range_hi,
115 float smoothing_ms = 0.0f, AutomationMix mix = AutomationMix::Replace);
116 bool connect_audio_rate_modulation(NodeId source, PortIndex source_port, NodeId dest,
117 uint32_t dest_param_id, float range_lo, float range_hi,
118 float smoothing_ms = 0.0f,
120 bool connect_feedback(NodeId source, PortIndex source_port, NodeId dest,
121 PortIndex dest_port);
122 bool connect_midi(NodeId source, NodeId dest);
123 bool disconnect(NodeId source, PortIndex source_port, NodeId dest, PortIndex dest_port);
124 bool disconnect_modulation(NodeId source, PortIndex source_port, NodeId dest,
125 uint32_t dest_param_id, bool audio_rate);
126 bool set_node_gain(NodeId id, float linear_gain);
127
131 SampleKernelConfig config);
134 SampleKernelConfig config);
136 PortIndex source_port, NodeId destination,
137 PortIndex destination_port);
139 std::optional<SampleRegionDescriptor> sample_region(SampleRegionId id) const;
140 std::vector<SampleRegionDescriptor> sample_regions() const;
144 return sample_region_parameter_binding_;
145 }
146
147 void set_canonical_executor_routing_enabled(bool enabled) noexcept;
148 void set_parallel_routing_enabled(bool enabled) noexcept;
149 void set_anticipation_enabled(bool enabled) noexcept;
150
151 const GraphNode* node(NodeId id) const;
152 const std::vector<GraphNode>& nodes() const;
153 const std::vector<Connection>& connections() const;
154 bool routed_execution_ready(int block_size) const noexcept;
155
156 Result prepare(double sample_rate, int max_block_size);
158 Result prepare_quiesced(double sample_rate, int max_block_size);
161 if (owner_->spectral_mode_.load(std::memory_order_acquire)) {
162 owner_->spectral_error_.store(SpectralError::SpectralPinnedExecutionUnsupported,
163 std::memory_order_relaxed);
164 return {};
165 }
166 return ExecutionSnapshot(*owner_, committed_snapshot_);
167 }
168 Result last_result() const noexcept { return last_result_; }
169
170 // Claims a set of plugin nodes as exact-generation parameter-event sinks
171 // owned by `owner`. Gated by a passkey only the timeline binding can mint.
173 const std::shared_ptr<detail::ExactParameterIngressOwner>& owner,
174 std::span<const NodeId> nodes, ExactParameterNodeClaimPasskey);
175
176 private:
177 friend class SignalGraph;
179 explicit PreparedTopologyEdit(SignalGraph& owner);
180 bool base_is_current_locked_() const;
181 bool is_new_node_(NodeId id) const;
182 std::optional<Result> baseline_removal_rejection_locked_() const;
183 bool rollback_quiesced_lifecycles_locked_() noexcept;
184 void release_new_custom_instances_() noexcept;
185 SampleRegionResult replace_sample_region_(SampleRegionDefinition definition, bool declaration);
186 SampleRegionResult reject_sample_region_(SampleRegionId id, SampleRegionRefusalReason reason,
187 std::string message, NodeId node = 0);
188 std::optional<Result> sample_region_preparation_result_(double sample_rate, int max_block_size);
189
190 template <typename Fn> NodeId add_node_(Fn&& fn) {
191 if (mutation_failed_ || committed_ || prepare_attempted_) {
192 mutation_failed_ = true;
193 return 0;
194 }
195 const NodeId id = fn();
196 if (id == 0)
197 mutation_failed_ = true;
198 return id;
199 }
200 template <typename Fn> bool mutate_(Fn&& fn) {
201 if (mutation_failed_ || committed_ || prepare_attempted_) {
202 mutation_failed_ = true;
203 return false;
204 }
205 const bool ok = fn();
206 if (!ok)
207 mutation_failed_ = true;
208 return ok;
209 }
210
211 SignalGraph* owner_ = nullptr;
212 std::unique_ptr<SignalGraph> candidate_;
213 std::shared_ptr<SignalGraph::CompiledGraph> prepared_snapshot_;
214 std::shared_ptr<SignalGraph::CompiledGraph> committed_snapshot_;
215 std::unordered_set<NodeId> baseline_node_ids_;
216 std::unordered_set<std::string> baseline_registry_keys_;
217 std::unordered_set<std::string> replaced_registry_keys_;
218 std::vector<NodeId> prepared_new_custom_ids_;
219 std::vector<detail::QuiescedPluginLifecycle> quiesced_plugins_;
220 std::vector<detail::QuiescedCustomLifecycle> quiesced_customs_;
221 std::vector<detail::QuiescedProcessorLifecycle> quiesced_processors_;
222 std::uint64_t base_authoring_generation_ = 0;
223 std::shared_ptr<SignalGraph::CompiledGraph> base_live_;
224 bool base_canonical_routing_ = false;
225 bool base_parallel_routing_ = false;
226 bool base_anticipation_ = false;
227 bool mutation_failed_ = false;
228 bool prepare_attempted_ = false;
229 bool quiesced_lifecycles_dirty_ = false;
230 bool committed_ = false;
231 const SampleRegionParameterBinding* sample_region_parameter_binding_ = nullptr;
232 Result last_result_ = Result::NotPrepared;
233};
234
235} // namespace pulp::host
Closed catalog value.
Definition spectral_frame.hpp:174
Profile-one indexed channels: symmetric float Hann, local-window phase, forward scale one,...
Definition spectral_frame.hpp:126
Passkey authorizing exact-parameter-event node claims on a prepared edit.
Definition signal_graph_prepared_topology_edit.hpp:20
friend class TimelineGraphPlaybackBinding
Definition signal_graph_prepared_topology_edit.hpp:22
Definition sample_region_parameters.hpp:80
Definition sample_region_parameters.hpp:28
Strong, typed handle to one exact compiled SignalGraph generation.
Definition signal_graph_execution_snapshot.hpp:23
Definition signal_graph_prepared_topology_edit.hpp:27
SampleRegionResult remove_sample_region(SampleRegionId id)
bool register_custom_node_type(CustomNodeType type)
SpectralResult< SpectralStagePorts > add_spectral_stage(SpectralIdentity identity, QualifiedSpectralStage stage, const std::string &name)
Definition signal_graph_prepared_topology_edit.hpp:71
bool connect_midi(NodeId source, NodeId dest)
bool connect(NodeId source, PortIndex source_port, NodeId dest, PortIndex dest_port)
PreparedTopologyEdit & operator=(const PreparedTopologyEdit &)=delete
Result
Definition signal_graph_prepared_topology_edit.hpp:29
@ CustomStateRestoreFailed
Definition signal_graph_prepared_topology_edit.hpp:42
@ PreflightFailed
Definition signal_graph_prepared_topology_edit.hpp:34
@ CustomRegistryConflict
Definition signal_graph_prepared_topology_edit.hpp:40
@ QuiescedRollbackFailed
Definition signal_graph_prepared_topology_edit.hpp:46
@ CompileFailed
Definition signal_graph_prepared_topology_edit.hpp:43
@ ExternalPluginReprepareRequired
Definition signal_graph_prepared_topology_edit.hpp:36
@ BaselinePluginRemovalRequiresRelease
Definition signal_graph_prepared_topology_edit.hpp:37
@ NotPrepared
Definition signal_graph_prepared_topology_edit.hpp:47
@ ExistingCustomReprepareRequired
Definition signal_graph_prepared_topology_edit.hpp:38
@ Staged
Definition signal_graph_prepared_topology_edit.hpp:51
@ AlreadyCommitted
Definition signal_graph_prepared_topology_edit.hpp:48
@ MidiOutputSnapshotLocalRequired
Definition signal_graph_prepared_topology_edit.hpp:35
@ Prepared
Definition signal_graph_prepared_topology_edit.hpp:30
@ ParallelWorkerStartFailed
Definition signal_graph_prepared_topology_edit.hpp:45
@ RegionRuntimeUnavailable
Definition signal_graph_prepared_topology_edit.hpp:49
@ StaleBase
Definition signal_graph_prepared_topology_edit.hpp:33
@ InvalidMutation
Definition signal_graph_prepared_topology_edit.hpp:32
@ ParameterContractMismatch
Definition signal_graph_prepared_topology_edit.hpp:50
@ CustomInstanceCreateFailed
Definition signal_graph_prepared_topology_edit.hpp:41
@ BaselineCustomRemovalRequiresRelease
Definition signal_graph_prepared_topology_edit.hpp:39
@ RuntimeAdoptionFailed
Definition signal_graph_prepared_topology_edit.hpp:44
@ Committed
Definition signal_graph_prepared_topology_edit.hpp:31
void set_canonical_executor_routing_enabled(bool enabled) noexcept
SpectralResult< SpectralAnalysisPorts > add_spectral_analysis(SpectralIdentity identity, const std::string &name)
Definition signal_graph_prepared_topology_edit.hpp:65
SampleRegionResult remove_sample_region_member(SampleRegionId id, NodeId member)
bool unregister_custom_node_type(std::string_view type_id, int version)
GraphResult connect(SpectralOutputPort source, SpectralInputPort destination)
Definition signal_graph_prepared_topology_edit.hpp:84
ExecutionSnapshot committed_execution_snapshot() const noexcept
Definition signal_graph_prepared_topology_edit.hpp:160
SampleRegionProof prove_sample_region(SampleRegionId id) const
SampleRegionResult connect_in_sample_region(SampleRegionId id, NodeId source, PortIndex source_port, NodeId destination, PortIndex destination_port)
bool disconnect(NodeId source, PortIndex source_port, NodeId dest, PortIndex dest_port)
NodeId add_midi_input_node(const std::string &name="MIDI In")
bool connect_feedback(NodeId source, PortIndex source_port, NodeId dest, PortIndex dest_port)
void set_parallel_routing_enabled(bool enabled) noexcept
NodeId add_processor_node(std::unique_ptr< format::Processor > processor, const std::string &name={})
NodeId add_unresolved_custom_node(std::string_view type_id, int version, int num_inputs, int num_outputs, const std::string &name)
SampleRegionResult bind_sample_region_parameters(const SampleRegionParameterBinding &binding)
const GraphNode * node(NodeId id) const
bool connect_automation(NodeId source, PortIndex source_port, NodeId dest, uint32_t dest_param_id, float range_lo, float range_hi, float smoothing_ms=0.0f, AutomationMix mix=AutomationMix::Replace)
Result prepare(double sample_rate, int max_block_size)
SampleRegionParameterContract sample_region_parameter_contract() const
NodeId add_gain_node(const std::string &name="Gain")
std::vector< SampleRegionDescriptor > sample_regions() const
SpectralResult< SpectralSynthesisPorts > add_spectral_synthesis(SpectralIdentity identity, const std::string &name)
Definition signal_graph_prepared_topology_edit.hpp:78
NodeId add_output_node(int channels, const std::string &name="Output")
NodeId add_owned_builtin_plugin_node(std::unique_ptr< PluginSlot > slot, int num_inputs, int num_outputs, const std::string &name)
Transfers a pathless Pulp-owned slot into this disposable candidate.
NodeId add_processor_node(std::shared_ptr< format::ProcessorNodeInstance > processor, const std::string &name={})
SampleRegionResult set_sample_kernel_config(SampleRegionId id, NodeId member, SampleKernelConfig config)
bool set_node_gain(NodeId id, float linear_gain)
SampleRegionResult declare_sample_region(SampleRegionDefinition definition)
Result last_result() const noexcept
Definition signal_graph_prepared_topology_edit.hpp:168
const std::vector< GraphNode > & nodes() const
NodeId add_midi_output_node(const std::string &name="MIDI Out")
const std::vector< Connection > & connections() const
SampleRegionResult add_sample_region_member(SampleRegionId id, NodeId member, SampleKernelConfig config)
bool disconnect_modulation(NodeId source, PortIndex source_port, NodeId dest, uint32_t dest_param_id, bool audio_rate)
GraphResult connect(const PortHandle &source, const PortHandle &destination)
Definition signal_graph_prepared_topology_edit.hpp:89
friend class SignalGraph
Definition signal_graph_prepared_topology_edit.hpp:177
bool routed_execution_ready(int block_size) const noexcept
void set_anticipation_enabled(bool enabled) noexcept
const SampleRegionParameterBinding * sample_region_parameter_binding() const noexcept
Definition signal_graph_prepared_topology_edit.hpp:143
NodeId add_input_node(int channels, const std::string &name="Input")
PreparedTopologyEdit(const PreparedTopologyEdit &)=delete
Result prepare_quiesced(double sample_rate, int max_block_size)
Requires process, MIDI injection, and anticipation to be stopped.
std::optional< SampleRegionDescriptor > sample_region(SampleRegionId id) const
friend bool register_builtin_sample_region_types(PreparedTopologyEdit &edit)
NodeId add_custom_node(std::string_view type_id, int version, const std::string &name={})
bool set_exact_parameter_event_nodes(const std::shared_ptr< detail::ExactParameterIngressOwner > &owner, std::span< const NodeId > nodes, ExactParameterNodeClaimPasskey)
bool connect_audio_rate_modulation(NodeId source, PortIndex source_port, NodeId dest, uint32_t dest_param_id, float range_lo, float range_hi, float smoothing_ms=0.0f, AutomationMix mix=AutomationMix::Replace)
NodeId add_custom_node(std::string_view type_id, const std::string &name={})
bool register_custom_node_type(CustomNodeType type, SampleKernelDescriptor sample_kernel)
friend class ExecutionSnapshot
Definition signal_graph_runtime.hpp:934
std::uint32_t NodeId
Definition graph_types.hpp:7
std::uint32_t PortIndex
Definition graph_types.hpp:8
Definition baked_codec.hpp:158
Bounded event contracts shared by host ingress and graph-authored nodes.
Definition anticipation_eligibility.hpp:9
AutomationMix
Definition signal_graph_connection.hpp:13
@ Replace
Definition signal_graph_connection.hpp:14
SampleRegionRefusalReason
Definition sample_region_proof.hpp:102
graph::SpectralResult< T > SpectralResult
Definition spectral_graph.hpp:11
std::uint32_t SampleRegionId
Definition sample_region_proof.hpp:13
STL namespace.
Definition custom_node_type.hpp:90
Definition signal_graph_node.hpp:126
Definition signal_graph_node.hpp:46
@ UnknownPort
Definition signal_graph_node.hpp:50
Definition signal_graph_node.hpp:36
Definition custom_node_type.hpp:332
Definition custom_node_type.hpp:386
Definition sample_region_authoring.hpp:24
Definition sample_region_proof.hpp:134
Definition sample_region_authoring.hpp:37
Definition spectral_graph.hpp:13
Definition spectral_graph.hpp:16