Skip to main content

DspGraph

Struct DspGraph 

Source
pub struct DspGraph<T: Sample, Edge: GraphEdge> { /* private fields */ }
Expand description

Directed graph structure for audio processing

Consists of processor nodes and typed edges that describe the signal flow. When constructing a DspGraph, a capacity needs to be provided to preallocate internal data structures. This ensures realtime safety when adding nodes and edges at runtime.

Two graph variants are provided by the library, differentiated by their edge types:

Most users should use the type aliases rather than DspGraph directly:

Nodes and edges can be added using DspGraph::add_processor and DspGraph::connect. Connections can also be dynamically enabled, disabled or updated.

The graph owns the processing nodes as well as their corresponding output buffers. Conversely, the input and output buffers that the graph operates on must be managed outside of the graph structure. To run the audio processing graph, use the DspGraph::process method, which takes the input and output buffers as arguments.

Implementations§

Source§

impl<T: Sample, Edge: GraphEdge> DspGraph<T, Edge>

Source

pub fn new( num_channels: usize, frame_size: FrameSize, max_num_edges: Option<usize>, ) -> Self

Creates a new DspGraph with preallocated capacity for internal data structures

  • num_channels: Maximum number of channels a node will process. Needs to be known upfront for summing operations.
  • frame_size: Maximum number of frames for block-wise processing.
  • max_num_edges: Graph capacity used for preallocation. This value also bounds the maximum number of nodes that can be added. If None, defaults to 64.
Source

pub fn add_processor<P: Processor<T> + Send + 'static>( &mut self, processor: P, output_buffer: MultiChannelBuffer<T>, ) -> Result<NodeIndex, AudioGraphError>

Adds a processor node to the graph along with its associated output buffer

Returns the NodeIndex of the newly added processor node (or an error if something went wrong). The node index can be used to reference the node when adding an edge to it using DspGraph::connect.

Source

pub fn connect( &mut self, from: GraphNode, to: GraphNode, channel_selection: Option<ChannelSelection>, ) -> Result<EdgeIndex, AudioGraphError>

Connects two nodes in the graph with an edge

The direction of the edge is so that the to node will access the output buffer of the from node as its input buffer during processing. These nodes can be either processor nodes added via DspGraph::add_processor, or the input or output nodes of the entire graph (see GraphNode).

Optionally, a ChannelSelection can be provided to specify which channels of the from node’s output buffer should be processed by the to node. If no selection is provided, all channels are connected by default.

Returns the EdgeIndex of the newly created edge (or an error if something went wrong). The edge index can be used to reference the edge for further operations such as enabling/disabling the connection.

Source

pub fn remove_connection( &mut self, edge: EdgeIndex, ) -> Result<(), AudioGraphError>

Removes an existing connection from the graph

NOT realtime safe for the RewireDspGraph variant

Alternative: Use DspGraph::disable_connection to temporarily disable a connection.

Source

pub fn enable_connection( &mut self, edge: EdgeIndex, ) -> Result<(), AudioGraphError>

Enables an existing connection in the graph

Source

pub fn disable_connection( &mut self, edge: EdgeIndex, ) -> Result<(), AudioGraphError>

Disables an existing connection in the graph

Source

pub fn process( &mut self, input: &dyn AudioBuffer<T>, output: &mut dyn AudioBuffer<T>, num_frames: FrameSize, )

Processes audio data through the graph

Source§

impl<T: Sample> DspGraph<T, RewireProcessorChannel>

Source

pub fn rewire( &mut self, edge_index: EdgeIndex, rewire_mapping: &[(usize, usize)], ) -> Result<(), AudioGraphError>

Rewires an existing connection in the graph to use a different channel mapping between the edge’s source and destination nodes.

NOT realtime safe

The rewire_mapping parameter is a slice of tuples where each tuple defines a channel mapping in the form (source_channel, destination_channel).

Note: Mapping multiple source channels to the same destination channel returns an error.

§Example
use audiograph::{FrameSize, GraphNode, MultiChannelBuffer, NoOp, RewireDspGraph};

let frame_size = FrameSize(1024);

let mut dsp_graph = RewireDspGraph::<f32>::new(4, frame_size, None);

let node1 = dsp_graph
    .add_processor(
        NoOp {},
        MultiChannelBuffer::new(4, frame_size), // 4 output channels
    )
    .unwrap();

let node2 = dsp_graph
    .add_processor(
        NoOp {},
        MultiChannelBuffer::new(4, frame_size), // 4 output channels
    )
    .unwrap();

// Connect nodes with default channel selection (i.e., all channels in order)
dsp_graph
    .connect(GraphNode::Input, node1.into(), None)
    .unwrap();

let edge = dsp_graph.connect(node1.into(), node2.into(), None).unwrap();

dsp_graph
    .connect(node2.into(), GraphNode::Output, None)
    .unwrap();

// Rewire the edge to swap channels 0 and 1, while keeping channels 2 and 3 the same
dsp_graph
    .rewire(edge, &[(0, 1), (1, 0), (2, 2), (3, 3)])
    .unwrap();
Source

pub fn remove_rewire( &mut self, edge_index: EdgeIndex, ) -> Result<(), AudioGraphError>

Removes rewiring from an existing connection, reverting to the default channel selection (i.e. all channels connected)

NOT realtime-safe

Source

pub fn connect_rewired( &mut self, from: GraphNode, to: GraphNode, wiring: &[(usize, usize)], ) -> Result<EdgeIndex, AudioGraphError>

Connects two nodes and creates a rewired mapping in one step

NOT realtime-safe

See RewireDspGraph::connect and RewireDspGraph::rewire for details.

Auto Trait Implementations§

§

impl<T, Edge> Freeze for DspGraph<T, Edge>

§

impl<T, Edge> !RefUnwindSafe for DspGraph<T, Edge>

§

impl<T, Edge> Send for DspGraph<T, Edge>
where Edge: Send, T: Send,

§

impl<T, Edge> !Sync for DspGraph<T, Edge>

§

impl<T, Edge> Unpin for DspGraph<T, Edge>
where Edge: Unpin,

§

impl<T, Edge> UnsafeUnpin for DspGraph<T, Edge>

§

impl<T, Edge> !UnwindSafe for DspGraph<T, Edge>

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> 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> Conv for T

Source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<T> FmtForward for T

Source§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
Source§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
Source§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
Source§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
Source§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
Source§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
Source§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
Source§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
Source§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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> Pipe for T
where T: ?Sized,

Source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
Source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
Source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
Source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
Source§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
Source§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
Source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
Source§

impl<T> Tap for T

Source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
Source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
Source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
Source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
Source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
Source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
Source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
Source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
Source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
Source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T> TryConv for T

Source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
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.