The way we make it work is by separating the user facing objects (implementing the AudioNode
trait) and the actual graph structure (which contains objects implementing the AudioProcessor
trait)
The AudioNode::connect
method simply sends an asynchronous control message to the audio render thread. It does not modify the graph in place.
The audio render thread receives these messages and applies them to the graph. The graph looks like this (simplified):
struct AudioGraph {
nodes: HashMap<u64, RefCell<Box<dyn AudioProcessor>>>,
edges: HashSet<(u64, u64)>,
}
Don't model your graph with Rc
s and RefCell
s, you will enter a world of pain.
Use an established graph library, or roll your own so you can mix in your application requirements