# 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 when`Node::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