Created
September 11, 2023 00:24
-
-
Save smj-edison/df76b02a9217789ff1de8af14f26ea3c to your computer and use it in GitHub Desktop.
Audio processing with GhostCell
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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