Skip to main content

Port

Struct Port 

Source
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_buffer stores the previous block’s output, snapshotted after DSP via snapshot_feedback().
  • On an input port in a feedback edge, feedback_buffer holds the delayed feedback value that gets mixed into buffer by pre_process().
  • downstream lists audio connections from this output port to input ports of other nodes, populated at build time by the graph builder.
  • upstream_buffer on input ports: direct pointer to the upstream output port’s buffer for zero-copy routing. None for 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: PortId

Port identifier

§name: String

Port name

§direction: PortDirection

Port 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,

Source

pub fn output(node_id: NodeId, index: u16, name: &str) -> Port<T, BUF_SIZE>

Create a new signal output port

Source

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

Source

pub fn input(node_id: NodeId, index: u16, name: &str) -> Port<T, BUF_SIZE>

Create a new signal input port

Source

pub fn control_output( node_id: NodeId, index: u16, name: &str, ) -> Port<T, BUF_SIZE>

Create a new control output port

Source

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

Source

pub fn control_input( node_id: NodeId, index: u16, name: &str, ) -> Port<T, BUF_SIZE>

Create a new control input port

Source

pub fn id(&self) -> PortId

Get the port ID

Source

pub fn name(&self) -> &str

Get the port name

Source

pub fn is_input(&self) -> bool

Check if port is an input

Source

pub fn is_output(&self) -> bool

Check if port is an output

Source

pub fn buffer(&self) -> &Buffer<T, BUF_SIZE>

Get a reference to the buffer

Source

pub fn buffer_mut(&mut self) -> &mut Buffer<T, BUF_SIZE>

Get a mutable reference to the buffer

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn set_value(&mut self, value: T)

Set a command value for this port.

The value is stored as a pending command and delivered to the algorithm (or written directly to the buffer) on the next run_action() call.

Trait Implementations§

Source§

impl<T, const BUF_SIZE: usize> ActivePort<T, BUF_SIZE> for Port<T, BUF_SIZE>
where T: Transcendental,

Source§

fn pull(&mut self) -> Option<[T; BUF_SIZE]>

Pull data from the port (for input ports).
Source§

fn push(&mut self, data: [T; BUF_SIZE]) -> Result<(), PortError>

Push data into the port (for output ports).
Source§

fn is_connected(&self) -> bool

Check if the port is connected.
Source§

fn on_tick(&mut self, _tick: &ClockTick)

Called on each clock tick (optional).
Source§

impl<T, const BUF_SIZE: usize> Debug for Port<T, BUF_SIZE>
where T: Transcendental,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl<T, const BUF_SIZE: usize> Send for Port<T, BUF_SIZE>
where T: Transcendental + Send,

Source§

impl<T, const BUF_SIZE: usize> Sync for Port<T, BUF_SIZE>
where T: Transcendental + Sync,

Auto Trait Implementations§

§

impl<T, const BUF_SIZE: usize> Freeze for Port<T, BUF_SIZE>
where T: Freeze,

§

impl<T, const BUF_SIZE: usize> !RefUnwindSafe for Port<T, BUF_SIZE>

§

impl<T, const BUF_SIZE: usize> Unpin for Port<T, BUF_SIZE>
where T: Unpin,

§

impl<T, const BUF_SIZE: usize> UnsafeUnpin for Port<T, BUF_SIZE>
where T: UnsafeUnpin,

§

impl<T, const BUF_SIZE: usize> !UnwindSafe for Port<T, BUF_SIZE>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> AsAny for T
where T: 'static,

Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert to &dyn std::any::Any
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert to &mut dyn std::any::Any
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.