pub struct Graph { /* private fields */ }Expand description
Audio processing directed acyclic graph.
Nodes are processors, edges route audio between ports. Evaluation follows topological order with pre-allocated buffers.
Graph itself implements Processor, enabling recursive nesting:
a Graph can be inserted as a node in a parent Graph.
Implementations§
Source§impl Graph
impl Graph
Sourcepub fn new(block_size: usize) -> Self
pub fn new(block_size: usize) -> Self
Empty graph with initial block allocation size.
§Examples
use trem::graph::Graph;
use trem::dsp::{Oscillator, Adsr, Gain, Waveform};
let mut g = Graph::new(512);
let osc = g.add_node(Box::new(Oscillator::new(Waveform::Saw)));
let env = g.add_node(Box::new(Adsr::new(0.01, 0.1, 0.5, 0.2)));
let gain = g.add_node(Box::new(Gain::new(0.5)));
g.connect(osc, 0, env, 0);
g.connect(env, 0, gain, 0);
assert_eq!(g.node_count(), 3);Sourcepub fn labeled(block_size: usize, label: &'static str) -> Self
pub fn labeled(block_size: usize, label: &'static str) -> Self
Construct with a label (used as ProcessorInfo::name when this Graph acts as a Processor).
Sourcepub fn set_input(&mut self, node: NodeId, num_inputs: u16)
pub fn set_input(&mut self, node: NodeId, num_inputs: u16)
Designate a GraphInput node as the entry point for parent audio.
When this Graph is processed as a Processor, parent inputs are copied
into this node’s output buffers before run().
Sourcepub fn set_output(&mut self, node: NodeId, num_outputs: u16)
pub fn set_output(&mut self, node: NodeId, num_outputs: u16)
Designate a node whose outputs become this Graph’s outputs.
Sourcepub fn add_group(&mut self, group: ParamGroup) -> u32
pub fn add_group(&mut self, group: ParamGroup) -> u32
Declare a parameter group. Returns the assigned group ID.
Sourcepub fn expose_param(
&mut self,
node: NodeId,
param_id: u32,
label: &'static str,
) -> u32
pub fn expose_param( &mut self, node: NodeId, param_id: u32, label: &'static str, ) -> u32
Expose an internal node’s parameter under a new label. Returns the external parameter ID.
Sourcepub fn expose_param_in_group(
&mut self,
node: NodeId,
param_id: u32,
label: &'static str,
group: u32,
) -> u32
pub fn expose_param_in_group( &mut self, node: NodeId, param_id: u32, label: &'static str, group: u32, ) -> u32
Expose an internal node’s parameter under a new label, assigned to a group.
Sourcepub fn add_node(&mut self, processor: Box<dyn Processor>) -> NodeId
pub fn add_node(&mut self, processor: Box<dyn Processor>) -> NodeId
Add a processor node, returns its NodeId.
Sourcepub fn connect(
&mut self,
src_node: NodeId,
src_port: PortIdx,
dst_node: NodeId,
dst_port: PortIdx,
)
pub fn connect( &mut self, src_node: NodeId, src_port: PortIdx, dst_node: NodeId, dst_port: PortIdx, )
Connect src_node:src_port → dst_node:dst_port.
Sourcepub fn node_count(&self) -> usize
pub fn node_count(&self) -> usize
Number of live (non-removed) processor slots.
Sourcepub fn run(&mut self, frames: usize, sample_rate: f64, events: &[TimedEvent])
pub fn run(&mut self, frames: usize, sample_rate: f64, events: &[TimedEvent])
Runs the graph in topological order for frames samples, mixing edges
into inputs and passing events to each node. This is the standalone
entry point used by the audio driver. When this Graph is used as a
Processor inside another Graph, Processor::process delegates here.
Sourcepub fn output_buffer(&self, node: NodeId, port: PortIdx) -> &[f32]
pub fn output_buffer(&self, node: NodeId, port: PortIdx) -> &[f32]
Slice of the last Graph::process output for node/port (length ≥ last frames; only first frames are valid).
Sourcepub fn graph_at_path(&self, path: &[NodeId]) -> Option<&Graph>
pub fn graph_at_path(&self, path: &[NodeId]) -> Option<&Graph>
Resolve a nested graph: path is successive container node ids from the root (e.g. [lead_id]
for the inner graph of the Lead node). Empty path = this graph.
Sourcepub fn output_buffer_at_path(
&self,
path: &[NodeId],
node: NodeId,
port: PortIdx,
) -> Option<&[f32]>
pub fn output_buffer_at_path( &self, path: &[NodeId], node: NodeId, port: PortIdx, ) -> Option<&[f32]>
Like Self::output_buffer, but for a node inside Self::graph_at_path(path).
Sourcepub fn node_sig_at_path(&self, path: &[NodeId], node: NodeId) -> Option<Sig>
pub fn node_sig_at_path(&self, path: &[NodeId], node: NodeId) -> Option<Sig>
Port signature of a node reached via path (for preview / UI).
Sourcepub fn mix_input_port_at_path(
&self,
path: &[NodeId],
node: NodeId,
dst_port: PortIdx,
frames: usize,
out: &mut [f32],
)
pub fn mix_input_port_at_path( &self, path: &[NodeId], node: NodeId, dst_port: PortIdx, frames: usize, out: &mut [f32], )
Sum all edges feeding node:dst_port into out[..frames] (matches one input bus of the node).
out should be at least frames long; only the first frames samples are written.
Sourcepub fn reset(&mut self)
pub fn reset(&mut self)
Calls Processor::reset on every node (e.g. clear oscillator phase, envelopes).
Sourcepub fn topology(&self) -> (Vec<(NodeId, &'static str)>, Vec<Edge>)
pub fn topology(&self) -> (Vec<(NodeId, &'static str)>, Vec<Edge>)
Snapshot of graph topology for display purposes.
Sourcepub fn node_params(&self, node: NodeId) -> Vec<ParamDescriptor>
pub fn node_params(&self, node: NodeId) -> Vec<ParamDescriptor>
Delegates to Processor::params; unknown or empty slots return an empty vec.
Sourcepub fn node_param_groups(&self, node: NodeId) -> Vec<ParamGroup>
pub fn node_param_groups(&self, node: NodeId) -> Vec<ParamGroup>
Delegates to Processor::param_groups; unknown or empty slots return an empty vec.
Sourcepub fn node_param_value(&self, node: NodeId, param_id: u32) -> f64
pub fn node_param_value(&self, node: NodeId, param_id: u32) -> f64
Reads Processor::get_param; missing nodes return 0.0.
Sourcepub fn set_node_param(&mut self, node: NodeId, param_id: u32, value: f64)
pub fn set_node_param(&mut self, node: NodeId, param_id: u32, value: f64)
Writes Processor::set_param if the node exists; otherwise no-op.
Sourcepub fn node_description(&self, node: NodeId) -> &str
pub fn node_description(&self, node: NodeId) -> &str
Returns the description string from a node’s ProcessorInfo.
Sourcepub fn snapshot_all_params(
&self,
node_ids: &[NodeId],
) -> Vec<(Vec<ParamDescriptor>, Vec<f64>, Vec<ParamGroup>)>
pub fn snapshot_all_params( &self, node_ids: &[NodeId], ) -> Vec<(Vec<ParamDescriptor>, Vec<f64>, Vec<ParamGroup>)>
Snapshot all parameter descriptors, groups, and current values for every node.
Returns one entry per node-index in graph_nodes order.
Sourcepub fn node_has_children(&self, node: NodeId) -> bool
pub fn node_has_children(&self, node: NodeId) -> bool
Check whether a node wraps an inner graph (i.e. it is a nested Graph-as-Processor).
Sourcepub fn snapshot(&self) -> GraphSnapshot
pub fn snapshot(&self) -> GraphSnapshot
Take a full snapshot of this graph level for UI rendering.
Sourcepub fn snapshot_at_path(&self, path: &[u32]) -> Option<GraphSnapshot>
pub fn snapshot_at_path(&self, path: &[u32]) -> Option<GraphSnapshot>
Follow a path of node IDs into nested graphs and snapshot the target level.
Sourcepub fn nested_ui_snapshots(&self) -> HashMap<Vec<NodeId>, GraphSnapshot>
pub fn nested_ui_snapshots(&self) -> HashMap<Vec<NodeId>, GraphSnapshot>
Snapshots of every nested graph level reachable from the root, keyed by navigation path.
Keys are non-empty paths: [outer_id], [outer_id, inner_id], … matching how the TUI
builds NodePath when drilling into nested processors (see SetParam.path).
Sourcepub fn set_param_at_path(&mut self, path: &[u32], param_id: u32, value: f64)
pub fn set_param_at_path(&mut self, path: &[u32], param_id: u32, value: f64)
Set a parameter on a node reached via a path through nested graphs.
path identifies the target graph level, param_id identifies the parameter.
Sourcepub fn chain(
label: &'static str,
block_size: usize,
procs: Vec<Box<dyn Processor>>,
) -> Result<Self, SigMismatch>
pub fn chain( label: &'static str, block_size: usize, procs: Vec<Box<dyn Processor>>, ) -> Result<Self, SigMismatch>
Sequential composition: wire processors a -> b -> c -> ....
Each processor’s outputs must match the next’s inputs (validated via Sig::chain).
The resulting Graph has the first processor’s inputs and the last’s outputs.
Sourcepub fn parallel(
label: &'static str,
block_size: usize,
procs: Vec<Box<dyn Processor>>,
) -> Self
pub fn parallel( label: &'static str, block_size: usize, procs: Vec<Box<dyn Processor>>, ) -> Self
Parallel composition: processors run independently, I/O counts sum.
When used as a Processor, parent inputs are split across children in order
and outputs are concatenated.
Sourcepub fn pipeline(label: &'static str, block_size: usize) -> PipelineBuilder
pub fn pipeline(label: &'static str, block_size: usize) -> PipelineBuilder
Fluent pipeline builder for ergonomic chain construction.