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:
BasicDspGraph: lightweight graph without rewiring supportRewireDspGraph: graph with channel rewiring capabilities
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>
impl<T: Sample, Edge: GraphEdge> DspGraph<T, Edge>
Sourcepub fn new(
num_channels: usize,
frame_size: FrameSize,
max_num_edges: Option<usize>,
) -> Self
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. IfNone, defaults to 64.
Sourcepub fn add_processor<P: Processor<T> + Send + 'static>(
&mut self,
processor: P,
output_buffer: MultiChannelBuffer<T>,
) -> Result<NodeIndex, AudioGraphError>
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.
Sourcepub fn connect(
&mut self,
from: GraphNode,
to: GraphNode,
channel_selection: Option<ChannelSelection>,
) -> Result<EdgeIndex, AudioGraphError>
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.
Sourcepub fn remove_connection(
&mut self,
edge: EdgeIndex,
) -> Result<(), AudioGraphError>
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.
Sourcepub fn enable_connection(
&mut self,
edge: EdgeIndex,
) -> Result<(), AudioGraphError>
pub fn enable_connection( &mut self, edge: EdgeIndex, ) -> Result<(), AudioGraphError>
Enables an existing connection in the graph
Sourcepub fn disable_connection(
&mut self,
edge: EdgeIndex,
) -> Result<(), AudioGraphError>
pub fn disable_connection( &mut self, edge: EdgeIndex, ) -> Result<(), AudioGraphError>
Disables an existing connection in the graph
Sourcepub fn process(
&mut self,
input: &dyn AudioBuffer<T>,
output: &mut dyn AudioBuffer<T>,
num_frames: FrameSize,
)
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>
impl<T: Sample> DspGraph<T, RewireProcessorChannel>
Sourcepub fn rewire(
&mut self,
edge_index: EdgeIndex,
rewire_mapping: &[(usize, usize)],
) -> Result<(), AudioGraphError>
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();Sourcepub fn remove_rewire(
&mut self,
edge_index: EdgeIndex,
) -> Result<(), AudioGraphError>
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
Sourcepub fn connect_rewired(
&mut self,
from: GraphNode,
to: GraphNode,
wiring: &[(usize, usize)],
) -> Result<EdgeIndex, AudioGraphError>
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>
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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
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
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
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
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.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
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.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
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.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
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.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
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.