Skip to content

Instantly share code, notes, and snippets.

@smj-edison
Created September 11, 2023 00:24
Show Gist options
  • Save smj-edison/df76b02a9217789ff1de8af14f26ea3c to your computer and use it in GitHub Desktop.
Save smj-edison/df76b02a9217789ff1de8af14f26ea3c to your computer and use it in GitHub Desktop.
Audio processing with GhostCell
use std::{sync::mpsc, thread};
use ghost_cell::{GhostBorrow, GhostCell, GhostToken};
fn main() {
let buffer_size = 2;
let (to_engine, from_main) = mpsc::channel::<Vec<f32>>();
let (to_main, from_engine) = mpsc::channel::<Vec<f32>>();
// audio thread
thread::spawn(move || {
let mut gain = GainNode { gain: 0.5 };
let mut streams = vec![0.0_f32; buffer_size * 2];
GhostToken::new(|mut token| {
let streams = GhostCell::from_mut(&mut streams[..]).as_slice_of_cells();
let channels = vec![
&streams[0..buffer_size],
&streams[buffer_size..(2 * buffer_size)],
];
let stream_io = vec![&channels[0..1], &channels[1..2]];
while let Ok(from_main) = from_main.recv() {
for (incoming, local) in from_main.iter().zip(streams.iter()) {
*local.borrow_mut(&mut token) = *incoming;
}
gain.process(
Ins {
streams: &stream_io[0..1],
},
Outs {
streams: &stream_io[1..2],
},
&mut token,
);
to_main.send(streams.borrow(&token).to_vec()).unwrap();
}
});
});
// example incoming audio
to_engine.send(vec![1.0, 1.0]).unwrap();
to_engine.send(vec![2.0, 2.0]).unwrap();
to_engine.send(vec![3.0, 3.0]).unwrap();
to_engine.send(vec![4.0, 4.0]).unwrap();
while let Ok(from_engine) = from_engine.recv() {
println!("from engine: {:?}", from_engine);
}
}
pub struct Ins<'a, 'brand> {
pub streams: &'a [&'a [&'a [GhostCell<'brand, f32>]]],
}
pub struct Outs<'a, 'brand> {
pub streams: &'a [&'a [&'a [GhostCell<'brand, f32>]]],
}
struct GainNode {
gain: f32,
}
impl GainNode {
fn process<'a, 'brand>(
&mut self,
ins: Ins<'a, 'brand>,
outs: Outs<'a, 'brand>,
token: &'a mut GhostToken<'brand>,
) {
for (channel_in, channel_out) in ins.streams[0].iter().zip(outs.streams[0].iter()) {
for (sample_in, sample_out) in channel_in.iter().zip(channel_out.iter()) {
*sample_out.borrow_mut(token) = *sample_in.borrow(token) * self.gain;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment