pub struct Port<T, const BUF_SIZE: usize>where
T: Transcendental,{
pub id: PortId,
pub name: String,
pub direction: PortDirection,
pub action: Option<Box<dyn Algorithm<T>>>,
pub pending_command: Option<T>,
pub buffer: Buffer<T, BUF_SIZE>,
pub feedback_buffer: Option<Buffer<T, BUF_SIZE>>,
pub downstream: Vec<(usize, usize)>,
pub upstream_buffer: Option<*const Buffer<T, BUF_SIZE>>,
pub feedback_downstream: Vec<(usize, usize)>,
}Expand description
A port on a node.
Each port has an owned Buffer<T, BUF_SIZE> for its data and an optional
Action that defines per-port processing. Output ports typically have
an action; input ports may have one for preprocessing.
Ports can optionally participate in feedback edges:
- On an output port in a feedback edge,
feedback_bufferstores the previous block’s output, snapshotted after DSP viasnapshot_feedback(). - On an input port in a feedback edge,
feedback_bufferholds the delayed feedback value that gets mixed intobufferbypre_process(). downstreamlists audio connections from this output port to input ports of other nodes, populated at build time by the graph builder.upstream_bufferon input ports: direct pointer to the upstream output port’s buffer for zero-copy routing.Nonefor fan-in/feedback ports.
§Safety
upstream_buffer is safe because the graph topology is immutable and
processing is strictly single-threaded in topological order. The
upstream output buffer is guaranteed to outlive the downstream input
port that references it.
Fields§
§id: PortIdPort identifier
name: StringPort name
direction: PortDirectionPort direction (input/output)
action: Option<Box<dyn Algorithm<T>>>Per-port processing algorithm (None for simple input ports)
pending_command: Option<T>Pending command value from the control path
buffer: Buffer<T, BUF_SIZE>Owned audio buffer (for output ports and input ports without upstream)
feedback_buffer: Option<Buffer<T, BUF_SIZE>>Delayed feedback state (None if not on a feedback edge)
downstream: Vec<(usize, usize)>Downstream audio connections: (target_node_index, target_port_index)
upstream_buffer: Option<*const Buffer<T, BUF_SIZE>>Direct pointer to upstream output buffer for zero-copy routing.
Some for input ports with exactly one upstream (1:1 connection).
None for output ports, fan-in, feedback, or unconnected input ports.
§Safety
Valid for the engine’s lifetime: the graph topology is static and processing is single-threaded in topological order.
feedback_downstream: Vec<(usize, usize)>Feedback edge targets from this output port
Implementations§
Source§impl<T, const BUF_SIZE: usize> Port<T, BUF_SIZE>where
T: Transcendental,
impl<T, const BUF_SIZE: usize> Port<T, BUF_SIZE>where
T: Transcendental,
Sourcepub fn output(node_id: NodeId, index: u16, name: &str) -> Port<T, BUF_SIZE>
pub fn output(node_id: NodeId, index: u16, name: &str) -> Port<T, BUF_SIZE>
Create a new signal output port
Sourcepub fn output_with_action(
node_id: NodeId,
index: u16,
name: &str,
action: Box<dyn Algorithm<T>>,
) -> Port<T, BUF_SIZE>
pub fn output_with_action( node_id: NodeId, index: u16, name: &str, action: Box<dyn Algorithm<T>>, ) -> Port<T, BUF_SIZE>
Create a new signal output port with an algorithm
Sourcepub fn input(node_id: NodeId, index: u16, name: &str) -> Port<T, BUF_SIZE>
pub fn input(node_id: NodeId, index: u16, name: &str) -> Port<T, BUF_SIZE>
Create a new signal input port
Sourcepub fn control_output(
node_id: NodeId,
index: u16,
name: &str,
) -> Port<T, BUF_SIZE>
pub fn control_output( node_id: NodeId, index: u16, name: &str, ) -> Port<T, BUF_SIZE>
Create a new control output port
Sourcepub fn control_output_with_action(
node_id: NodeId,
index: u16,
name: &str,
action: Box<dyn Algorithm<T>>,
) -> Port<T, BUF_SIZE>
pub fn control_output_with_action( node_id: NodeId, index: u16, name: &str, action: Box<dyn Algorithm<T>>, ) -> Port<T, BUF_SIZE>
Create a new control output port with an algorithm
Sourcepub fn control_input(
node_id: NodeId,
index: u16,
name: &str,
) -> Port<T, BUF_SIZE>
pub fn control_input( node_id: NodeId, index: u16, name: &str, ) -> Port<T, BUF_SIZE>
Create a new control input port
Sourcepub fn buffer_mut(&mut self) -> &mut Buffer<T, BUF_SIZE>
pub fn buffer_mut(&mut self) -> &mut Buffer<T, BUF_SIZE>
Get a mutable reference to the buffer
Sourcepub fn audio_buffer(&self) -> &Buffer<T, BUF_SIZE>
pub fn audio_buffer(&self) -> &Buffer<T, BUF_SIZE>
Get the effective audio buffer for an input port.
Returns a reference to the upstream output buffer when this port has a direct 1:1 connection (zero-copy), or the port’s own buffer for fan-in/feedback/unconnected ports (copy-based).
§Safety
The upstream pointer is valid because the graph topology is static and processing is single-threaded in topological order. The upstream output buffer is owned by another port in the same graph and lives for the entire processing session.
Sourcepub unsafe fn upstream_ref(
ptr: *const Buffer<T, BUF_SIZE>,
) -> &'static Buffer<T, BUF_SIZE>
pub unsafe fn upstream_ref( ptr: *const Buffer<T, BUF_SIZE>, ) -> &'static Buffer<T, BUF_SIZE>
Directly dereference an upstream buffer pointer to a &Buffer.
Used by the engine to avoid borrowing self (and thus the node)
when building audio input references for zero-copy processing.
§Safety
ptr must be a valid, aligned pointer to a Buffer<T, BUF_SIZE>
that lives for the entire processing session.
Sourcepub fn pre_process(&mut self, _tick: &ClockTick)
pub fn pre_process(&mut self, _tick: &ClockTick)
Pre-process this port before node DSP.
For input ports on a feedback edge, mixes the delayed feedback
(from feedback_buffer) into the current buffer.
No-op when feedback_buffer is None.
tick is the current clock tick, available for future
sample-accurate or time-varying port-level processing.
Sourcepub fn snapshot_feedback(&mut self)
pub fn snapshot_feedback(&mut self)
Snapshot the buffer into feedback_buffer after node DSP.
For output ports on a feedback edge, saves the current buffer
so it can be used as delayed feedback in the next block.
No-op when feedback_buffer is None.
Sourcepub fn propagate(
&self,
_tick: &ClockTick,
nodes: &mut [NodeVariant<T, BUF_SIZE>],
)
pub fn propagate( &self, _tick: &ClockTick, nodes: &mut [NodeVariant<T, BUF_SIZE>], )
Propagate this port’s buffer to all downstream input ports.
Iterates over downstream and copies buffer into each target
input port’s buffer. The caller must ensure no aliasing between
this port’s node and any target node (guaranteed by DAG topology).
tick is the current clock tick, available for future
sample-accurate or time-varying port-level propagation.
Sourcepub fn run_action(
&mut self,
input: Option<&[T; BUF_SIZE]>,
ctx: &ActionContext<'_>,
) -> Result<(), ProcessError>
pub fn run_action( &mut self, input: Option<&[T; BUF_SIZE]>, ctx: &ActionContext<'_>, ) -> Result<(), ProcessError>
Run the port’s algorithm.
Delivers any pending command via Algorithm::apply_command(), then
calls Algorithm::process() with the input and output slices.
When no algorithm is attached, the pending command value (if any)
is written directly into the buffer; otherwise input is passed
through or zero-filled.