Skip to content

Commit 1721282

Browse files
committed
Add failing test case where NodeCollection would panic
This issue arises when a graph involves nodes connecting to audio params. E.g. constant src -> playback rate -> buffer src. The playbackrate param is dropped alongside the buffer src if it has ended, but this leaves an edge from the constant src in place. To solve this we probably need a bit more refactoring, stay tuned
1 parent 50f6a9f commit 1721282

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

src/render/graph.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,69 @@ mod tests {
829829
assert!(node_id_consumer.pop().is_none());
830830
}
831831

832+
#[test]
833+
fn test_audio_param_with_signal_lifecycle() {
834+
let (node_id_producer, mut node_id_consumer) = llq::Queue::new().split();
835+
let mut graph = Graph::new(node_id_producer);
836+
837+
let node = Box::new(TestNode { tail_time: false });
838+
839+
// Destination Node is always node id 0, and should never drop
840+
add_node(&mut graph, 0, node.clone());
841+
842+
// AudioListener Node is always node id 1, and should never drop
843+
add_node(&mut graph, 1, node.clone());
844+
845+
// Add a regular node at id 3, it has tail time false so after rendering it should be
846+
// dropped and the AudioNodeId(3) should be reclaimed
847+
add_node(&mut graph, 2, node.clone());
848+
// Mark the node as 'detached from the control thread', so it is allowed to drop
849+
graph
850+
.nodes
851+
.get_unchecked_mut(AudioNodeId(2))
852+
.control_handle_dropped = true;
853+
854+
// Connect the regular node to the AudioDestinationNode
855+
add_edge(&mut graph, 2, 0);
856+
857+
// Add an AudioParam at id 4, it should be dropped alongside the regular node
858+
let param = Box::new(TestNode { tail_time: true }); // audio params have tail time true
859+
add_node(&mut graph, 3, param);
860+
// Mark the node as 'detached from the control thread', so it is allowed to drop
861+
graph
862+
.nodes
863+
.get_unchecked_mut(AudioNodeId(3))
864+
.control_handle_dropped = true;
865+
866+
// Connect the audioparam to the regular node
867+
add_audioparam(&mut graph, 3, 2);
868+
869+
// Add a source node to feed into the AudioParam
870+
let signal = Box::new(TestNode { tail_time: true });
871+
add_node(&mut graph, 4, signal);
872+
add_edge(&mut graph, 4, 3);
873+
874+
// Render a single quantum
875+
let scope = AudioWorkletGlobalScope {
876+
current_frame: 0,
877+
current_time: 0.,
878+
sample_rate: 48000.,
879+
node_id: std::cell::Cell::new(AudioNodeId(0)),
880+
event_sender: None,
881+
};
882+
graph.render(&scope);
883+
884+
// First the regular node should be dropped, then the audioparam
885+
assert_eq!(node_id_consumer.pop().unwrap().0, 2);
886+
assert_eq!(node_id_consumer.pop().unwrap().0, 3);
887+
888+
// No other dropped nodes
889+
assert!(node_id_consumer.pop().is_none());
890+
891+
// Render again
892+
graph.render(&scope);
893+
}
894+
832895
#[test]
833896
fn test_release_orphaned_source_nodes() {
834897
let (node_id_producer, mut node_id_consumer) = llq::Queue::new().split();

0 commit comments

Comments
 (0)