Struct dsp::Graph
[−]
[src]
pub struct Graph<F, N> { // some fields omitted }
A directed, acyclic DSP graph.
Designed for easily and safely setting up high performance audio signal generating, processing and mixing. Useful for both simple and highly complex signal graphs.
There are a variety of use cases for Graph
:
- Designing effects.
- Creating an audio mixer.
- Making a sampler.
- Writing a DSP backend for a DAW.
- Any kind of modular audio synthesis or processing.
Graph
is a wrapper around daggy's
Dag
type - an abstraction for
working with directed acyclic graph's where high performance node adding and accessing is
required.
An input -> output connection in this Graph
is represented as a parent -> child connection
within the internal Dag
. The following terms are all equivalent:
- input -> output
- src -> dest
- parent -> child
Audio can be requested from any node in the Graph using the
audio_requested_from
method.
When audio_requested
is called on the
Graph, audio will be requested from the node specified by the index at maybe_master
. If
maybe_master
is None
, audio will be requested from the first, input-only node found - that
is, the first node that is found with only input connections and no outputs.
NodeIndex is a type that acts as a reference to a node, while EdgeIndex is a type that acts as a reference to an edge (which in this case describes a src -> dest Connection between two nodes). It should be noted that these are only stable across certain operations. Removing indices may shift other indices of the same type! Adding nodes or edges to the Graph keeps all indices stable, but removing a node or edge will force the last node/edge to shift its index to take its place.
Graph also offers methods for accessing its underlying Dag or PetGraph.
Methods
impl<F, N> Graph<F, N> where F: Frame, N: Node<F>
[src]
fn new() -> Self
Constructor for a new dsp Graph.
with_capacity
is recommended if you have a
rough idea of the number of nodes, connections and frames per buffer upon the Graph's
instantiation.
fn with_capacity(nodes: usize, connections: usize, frames_per_buffer: usize) -> Self
Constructor for a new dsp Graph with some minimum capacity.
- nodes is the capacity for the underlying Dag's node
Vec
. - connections is the capacity for the underlying Dag's edge
Vec
. - frames_per_buffer is the capacity for the Graph's
dry_buffer
, which is used for mixing the dry and wet signals whenNode::audio_requested
is called.
fn dag(&self) -> &Dag<F, N>
A reference to the underlying Dag.
fn into_dag(self) -> Dag<F, N>
Takes ownership of the Graph and returns the underlying Dag.
fn pet_graph(&self) -> &PetGraph<F, N>
A reference to the internal Dag's underlying PetGraph.
fn into_pet_graph(self) -> PetGraph<F, N>
Takes ownership of the Graph and returns the internal Dag's underlying PetGraph.
fn node_count(&self) -> usize
The total number of nodes in the Graph.
fn connection_count(&self) -> usize
The total number of connections in the Graph.
fn master_index(&self) -> Option<NodeIndex>
Return the Graph's master index if there is one.
Graph's Node implementation will request audio from the node at maybe_master
when the Node::audio_requested
method is called.
fn set_master(&mut self, maybe_index: Option<NodeIndex>)
Set the master node for the Graph.
Graph will check to see if a node exists for the given index before assigning.
Graph's Node implementation will request audio from the node at maybe_master
when the Node::audio_requested
method is called.
fn add_node(&mut self, node: N) -> NodeIndex
Add a node to the dsp graph.
This computes in O(1) time.
fn node(&self, node: NodeIndex) -> Option<&N>
A reference to the node at the given index (or None
if it doesn't exist).
fn node_mut(&mut self, node: NodeIndex) -> Option<&mut N>
A mutable reference to the node at the given index (or None
if it doesn't exist).
fn raw_nodes(&self) -> RawNodes<N>
Read only access to the internal node array.
fn nodes_mut(&mut self) -> NodesMut<N>
An iterator yielding mutable access to all nodes.
The order in which nodes are yielded matches the order of their indices.
fn connection(&self, edge: EdgeIndex) -> Option<&Connection<F>>
A reference to the connection at the given index (or None
if it doesn't exist).
fn raw_edges(&self) -> RawEdges<F>
Read only access to the internal edge array.
fn index_twice_mut(&mut self, a: NodeIndex, b: NodeIndex) -> (&mut N, &mut N)
Index the Graph by two NodeIndex
s at once.
Panics if the indices are equal or if they are out of bounds.
fn remove_node(&mut self, idx: NodeIndex) -> Option<N>
Remove a node from the dsp graph.
Resets the master to None if the index matches the current master index.
Note: This method may shift (and in turn invalidate) previously returned node indices!
Graph will re-prepare its visit order if some node was removed.
fn add_connection(&mut self, src: NodeIndex, dest: NodeIndex) -> Result<EdgeIndex, WouldCycle>
Adds an edge from src
to dest
. That is, src
is now an input to dest
.
Returns an error instead if the input would create a cycle in the graph.
Graph will re-prepare its visit order if some connection was successfully added.
If you're using add_node
followed by this method, consider using
add_input
or
add_output
instead for greater performance.
This is because when adding a new node and edge simultaneously, we don't have to check
whether adding the edge would create a cycle.
Panics if there is no node for either src
or dest
.
Panics if the Graph is at the maximum number of edges for its index.
fn add_connections<I>(&mut self, connections: I) -> Result<EdgeIndices, WouldCycle> where I: IntoIterator<Item=(NodeIndex, NodeIndex)>
The same as add_connection
but adds
multiple connections to the Graph. Rather than checking for introduced cycles and
re-preparing the visit order after adding each edge, we only do so after all edges are
added. Thus, this is a far more efficient alternative to repeatedly calling the
add_connection
method.
Returns an error instead if any of the connections would create a cycle in the graph.
Graph will re-prepare its visit order if the connections were successfully added.
If you're using add_node
followed by this method, consider using
add_input
or
add_output
instead for greater performance.
This is because when adding a new node and edge simultaneously, we don't have to check
whether adding the edge would create a cycle.
Panics if there is no node for either src
or dest
.
Panics if the Graph is at the maximum number of edges for its index.
fn find_connection(&self, src: NodeIndex, dest: NodeIndex) -> Option<EdgeIndex>
Find and return the index to the edge that describes the connection where src
is an input
to dest
.
Computes in O(e') time, where e' is the number of edges connected to the nodes a
and b
.
fn remove_edge(&mut self, edge: EdgeIndex) -> bool
Remove the connection described by the edge at the given index.
Returns true if an edge was removed, returns false if there was no edge at the given index.
Re-prepares the visit order if some edge was removed.
fn remove_connection(&mut self, a: NodeIndex, b: NodeIndex) -> bool
Find and remove any connection between a and b if there is one, whether it is a -> b or b -> a. We know that their may only be one edge as our API does not allow for creating a cyclic graph.
Returns true if an edge was removed, returns false if there was no edge at the given index.
Graph will re-prepare its visit order if some edge was removed.
Note: If you have an index to the edge you want to remove,
remove_edge
is a more performant option.
fn add_input(&mut self, src: N, dest: NodeIndex) -> (EdgeIndex, NodeIndex)
Add a new node weight to the graph as an input to the wait at the given dest
node index.
src -> new edge -> dest
Returns an index to both the new src
node and the edge that represents the new connection
between it and the node at dest
.
Computes in O(n) time where n is the number of nodes. This is because must update the visit order after adding the new connection.
Panics if there is no node for the given dest
index.
Panics if the Graph is at the maximum number of edges for its index.
fn add_output(&mut self, src: NodeIndex, dest: N) -> (EdgeIndex, NodeIndex)
Add a new node weight to the graph as an output to the wait at the given src
node index.
src -> new edge -> dest
Returns an index to both the new dest
node and the edge that represents the new connection
between it and the node at src
.
Computes in O(n) time where n is the number of nodes. This is because must update the visit order after adding the new connection.
Panics if there is no node for the given dest
index.
Panics if the Graph is at the maximum number of edges for its index.
fn inputs(&self, idx: NodeIndex) -> Inputs<F, N>
A "walker" object that may be used to step through the inputs of the given node.
Unlike the Inputs
type, WalkInputs
does not borrow the Graph
.
Can be converted to an iterator using .iter()
.
fn outputs(&self, idx: NodeIndex) -> Outputs<F, N>
A "walker" object that may be used to step through the outputs of the given node.
Unlike the Outputs
type, WalkOutputs
does not borrow the Graph.
Can be converted to an iterator using .iter()
.
fn visit_order(&self) -> VisitOrder
A "walker" type that may be used to step through all node indices in the order in which they will be visited when audio is requested from the Graph.
fn visit_order_rev(&self) -> VisitOrderReverse
A "walker" type that may be used to step through all node indices in the order in which they will be visited when audio is requested from the Graph.
Unlike the VisitOrder type, VisitOrder does not borrow the Graph.
fn remove_all_input_connections(&mut self, idx: NodeIndex) -> usize
Remove all incoming connections to the node at the given index.
Return the number of connections removed.
fn remove_all_output_connections(&mut self, idx: NodeIndex) -> usize
Remove all outgoing connections from the node at the given index.
Return the number of connections removed.
fn clear_disconnected(&mut self) -> usize
Clear all dsp nodes that have no inputs or outputs.
Returns the number of nodes removed.
Note: this may shift (and in turn invalidate) previously returned node and edge indices!
fn clear(&mut self)
Clear all dsp nodes.
fn prepare_buffers(&mut self, buffer_size: usize)
Prepare the buffers for all nodes within the Graph.
fn audio_requested_from(&mut self, out_node: NodeIndex, output: &mut [F], sample_hz: f64)
Request audio from the node at the given index.
Panics if there is no node for the given index.
Trait Implementations
impl<F, N> Index<NodeIndex> for Graph<F, N>
[src]
type Output = N
The returned type after indexing
fn index<'a>(&'a self, index: NodeIndex) -> &'a N
The method for the indexing (Foo[Bar]
) operation
impl<F, N> IndexMut<NodeIndex> for Graph<F, N>
[src]
fn index_mut(&mut self, index: NodeIndex) -> &mut N
The method for the indexing (Foo[Bar]
) operation
impl<F, N> Index<EdgeIndex> for Graph<F, N>
[src]
type Output = Connection<F>
The returned type after indexing
fn index<'a>(&'a self, index: EdgeIndex) -> &'a Connection<F>
The method for the indexing (Foo[Bar]
) operation
impl<F, N> Node<F> for Graph<F, N> where F: Frame, N: Node<F>
[src]
fn audio_requested(&mut self, output: &mut [F], sample_hz: f64)
Request audio from the Node given some sample_hz
(aka sample rate in hertz). If the Node has no inputs, the buffer
will be zeroed. If the Node has some inputs, the buffer
will consist of the inputs summed together. Read more
fn dry(&self) -> F::Sample::Float
Following the call to the Node
's audio_requested
method, the Graph
will sum together some of the original (dry) signal with some of the processed (wet) signal. Read more
fn wet(&self) -> F::Sample::Float
Following the call to the Node
's audio_requested
method, the Graph
will sum together some of the original (dry) signal with some of the processed (wet) signal. Read more
Derived Implementations
impl<F: Debug, N: Debug> Debug for Graph<F, N>
[src]
impl<F: Clone, N: Clone> Clone for Graph<F, N>
[src]
fn clone(&self) -> Graph<F, N>
Returns a copy of the value. Read more
fn clone_from(&mut self, source: &Self)
1.0.0
Performs copy-assignment from source
. Read more