Skip to content

Commit

Permalink
Update to use nano arena
Browse files Browse the repository at this point in the history
  • Loading branch information
bennetthardwick committed May 7, 2020
1 parent fed9faa commit 43b217e
Show file tree
Hide file tree
Showing 7 changed files with 480 additions and 554 deletions.
6 changes: 1 addition & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ keywords = [ "audio", "dsp", "graph" ]
[dependencies]
sample = "0.10.0"
bufferpool = "0.1.6"
nano_arena = "0.5.0"
nano_arena = "0.5.1"

[dev-dependencies]
uuid = { version = "0.8", features = ["v4"] }
Expand All @@ -30,7 +30,3 @@ alloc_counter = "0.0.4"

[badges]
travis-ci = { repository = "https://github.com/bennetthardwick/audio-graph" }

[[example]]
name = "counting-node-bench"
path = "benches/counting-node.rs"
75 changes: 34 additions & 41 deletions benches/dsp-chain-alternative.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ extern crate test;
#[macro_use]
extern crate lazy_static;

use audiograph::NodeId;
use dsp::Node;
use std::cell::RefCell;
use std::rc::Rc;
use test::Bencher;
use volatile_unique_id::*;

use audiograph;
use dsp;
Expand Down Expand Up @@ -76,7 +74,7 @@ fn bench_audiograph_count_to_max(b: &mut Bencher) {

#[derive(Debug)]
struct OutputRoute {
buffer: Rc<RefCell<Vec<f32>>>,
buffer: Vec<f32>,
offset: usize,
}

Expand All @@ -88,7 +86,7 @@ fn bench_audiograph_count_to_max(b: &mut Bencher) {
_frames: usize,
_context: &mut (),
) {
let mut buffer = self.buffer.borrow_mut();
let buffer = &mut self.buffer;
for (input, output) in input[0]
.as_ref()
.iter()
Expand Down Expand Up @@ -121,54 +119,49 @@ fn bench_audiograph_count_to_max(b: &mut Bencher) {
}
}

#[derive(Debug, Eq, PartialEq, Clone, Hash)]
struct Id(volatile_unique_id::Id);

impl audiograph::NodeId<Generator> for Id {
fn generate_node_id(generator: &mut Generator) -> Self {
Id(generator.generate())
}
}
let test: Vec<f32> = TEST_DATA.iter().cloned().collect();

let mut generator = GeneratorBuilder::new().build();

b.iter(|| {
let buffer: Vec<f32> = vec![0.; BUFFER_SIZE];
let buffer = Rc::new(RefCell::new(buffer));

let output_id = Id::generate_node_id(&mut generator);

let buffer_size = 1024;
let count = BUFFER_SIZE / buffer_size;
let mut graph = audiograph::RouteGraphBuilder::new()
.with_buffer_size(buffer_size)
.build();

let output = graph.add_node_with_idx(move |id| {
audiograph::Node::with_id(
id,
1,
Routes::Output(OutputRoute {
buffer: vec![0.; BUFFER_SIZE],
offset: 0,
}),
vec![],
)
});

graph.add_node_with_idx(|id| {
audiograph::Node::with_id(
id,
1,
Routes::Counting(CountingRoute { current: 0 }),
vec![audiograph::Connection::new(output.clone(), 1.)],
)
});

graph.topographic_sort();

let mut graph = audiograph::RouteGraph::with_nodes(
vec![
audiograph::Node::new(
1,
Routes::Counting(CountingRoute { current: 0 }),
vec![audiograph::Connection::new(output_id.clone(), 1.)],
&mut generator
),
audiograph::Node::with_id(
output_id,
1,
Routes::Output(OutputRoute {
buffer: Rc::clone(&buffer),
offset: 0,
}),
vec![],
),
],
buffer_size as usize,
);
let count = BUFFER_SIZE / buffer_size;

let mut c = ();

for _ in 0..count {
graph.process(buffer_size as usize, &mut c);
}

assert_eq!(*buffer.borrow(), test);
if let Routes::Output(OutputRoute { buffer, .. }) = graph.remove_node(output).route() {
assert_eq!(*buffer, test);
} else {
panic!("Expected output route!");
}
});
}
81 changes: 35 additions & 46 deletions benches/counting-node.rs → examples/counting-node.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
#[macro_use]
extern crate lazy_static;

use audiograph::NodeId;
use std::cell::RefCell;
use std::rc::Rc;
use volatile_unique_id::*;

use audiograph;

const BUFFER_SIZE: usize = 1024 * 1024;
Expand Down Expand Up @@ -47,7 +42,7 @@ fn main() {

#[derive(Debug)]
struct OutputRoute {
buffer: Rc<RefCell<Vec<f32>>>,
buffer: Vec<f32>,
offset: usize,
}

Expand All @@ -59,7 +54,7 @@ fn main() {
_frames: usize,
_context: &mut C,
) {
let mut buffer = self.buffer.borrow_mut();
let buffer = &mut self.buffer;
for (input, output) in input[0]
.as_ref()
.iter()
Expand Down Expand Up @@ -92,57 +87,51 @@ fn main() {
}
}

#[derive(Debug, Eq, PartialEq, Clone, Hash)]
struct Id(volatile_unique_id::Id);

impl audiograph::NodeId<Generator> for Id {
fn generate_node_id(generator: &mut Generator) -> Self {
Id(generator.generate())
}
}

let test: Vec<f32> = TEST_DATA.iter().cloned().collect();

let iters = 10000;

let mut generator = GeneratorBuilder::new().build();
let iters = 1000;

for _ in 0..iters {
let buffer: Vec<f32> = vec![0.; BUFFER_SIZE];
let buffer = Rc::new(RefCell::new(buffer));

let output_id = Id::generate_node_id(&mut generator);

let buffer_size = 1024;
let count = BUFFER_SIZE / buffer_size;
let mut graph = audiograph::RouteGraphBuilder::new()
.with_buffer_size(buffer_size)
.build();

let output = graph.add_node_with_idx(move |id| {
audiograph::Node::with_id(
id,
1,
Routes::Output(OutputRoute {
buffer: vec![0.; BUFFER_SIZE],
offset: 0,
}),
vec![],
)
});

graph.add_node_with_idx(|id| {
audiograph::Node::with_id(
id,
1,
Routes::Counting(CountingRoute { current: 0 }),
vec![audiograph::Connection::new(output.clone(), 1.)],
)
});

graph.topographic_sort();

let mut graph = audiograph::RouteGraph::with_nodes(
vec![
audiograph::Node::new(
1,
Routes::Counting(CountingRoute { current: 0 }),
vec![audiograph::Connection::new(output_id.clone(), 1.)],
&mut generator,
),
audiograph::Node::with_id(
output_id,
1,
Routes::Output(OutputRoute {
buffer: Rc::clone(&buffer),
offset: 0,
}),
vec![],
),
],
buffer_size as usize,
);
let count = BUFFER_SIZE / buffer_size;

let mut c = ();

for _ in 0..count {
graph.process(buffer_size as usize, &mut c);
}

assert_eq!(*buffer.borrow(), test);
if let Routes::Output(OutputRoute { buffer, .. }) = graph.remove_node(output).route() {
assert_eq!(*buffer, test);
} else {
panic!("Expected output route!");
}
}
}
52 changes: 17 additions & 35 deletions examples/pass-through.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use audiograph::*;
use std::io::Read;
use volatile_unique_id::*;

// Define some strings to be used throughout the application
const APP_NAME: &str = "pass-through-audiograph";
Expand Down Expand Up @@ -109,18 +108,6 @@ impl Route<Sample, Context> for OutputRoute {
}
}

// RouteGraph also requires that each node have a unique id.
// What Id you use is completely up to you, in this example I use
// a library called uuid.
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
struct Id(volatile_unique_id::Id);

impl NodeId<Generator> for Id {
fn generate_node_id(generator: &mut Generator) -> Self {
Id(generator.generate())
}
}

// There's many ways to represent routes inside the graph. To minimise
// the amount of heap allocations, I've opted to use an enum instead of
// Box<dyn Route<Sample>>. This also helps if I want to convert the route
Expand Down Expand Up @@ -153,32 +140,27 @@ fn main() {

let channels = 2;

let mut generator = GeneratorBuilder::new().build();

// Create a channel to send data from Jack into the route.
let output_id = Id::generate_node_id(&mut generator);
let buffer_size = client.buffer_size();
let mut graph = RouteGraphBuilder::new()
.with_buffer_size(buffer_size as usize)
.build();

// Create the Node to host the route. Nodes have a little bit of extra information
// that is used with the routing of the graph, such as the number of channels it has
// and the other nodes that it's connected to.
let output_node: Node<Id, Sample, Routes, _, _> =
Node::with_id(output_id.clone(), channels, Routes::Output(OutputRoute), vec![]);

let input_id = Id::generate_node_id(&mut generator);
let input_node = Node::with_id(
input_id,
channels,
Routes::Input(InputRoute),
// Connect to the output route with an amplitude of 1
vec![Connection::new(output_id, 1.)],
);

// The initial buffer size for the graph. With Jack this can change all the time
// after the graph has been created - but this example doesn't support that.
let buffer_size = client.buffer_size();

// Create a graph of just the input and output nodes.
let mut graph = RouteGraph::with_nodes(vec![input_node, output_node], buffer_size as usize);
let output = graph
.add_node_with_idx(|id| Node::with_id(id, channels, Routes::Output(OutputRoute), vec![]));

graph.add_node_with_idx(|id| {
Node::with_id(
id,
channels,
Routes::Input(InputRoute),
vec![Connection::new(output.clone(), 1.)],
)
});

graph.topographic_sort();

// Get the specifications for input and output Jack ports
let out_spec = jack::AudioOut::default();
Expand Down
Loading

0 comments on commit 43b217e

Please sign in to comment.