use std::sync::{Arc, RwLock};
use crate::utils::buffer::{clear_buffer, TempBuffer};
use fundsp::{
audionode::AudioNode,
buffer::{BufferMut, BufferRef},
combinator::An,
typenum::{U0, U1},
Frame,
};
#[derive(Clone)]
pub struct SharedBuffer {
buffer: Arc<RwLock<TempBuffer>>,
}
impl SharedBuffer {
pub fn new(capacity: usize) -> Self {
let buffer = Arc::new(RwLock::new(TempBuffer::new(capacity)));
Self { buffer }
}
pub fn read(&self, values: &mut [f32]) {
let buffer = self
.buffer
.read()
.expect("Failed to access shared fundsp buffer for reading");
assert!(
values.len() <= buffer.len(),
"Tried to read {} prefilled values, but only got {} values",
values.len(),
buffer.len()
);
buffer.copy_to(values);
}
pub fn write(&mut self, values: &[f32]) {
let mut buffer = self
.buffer
.write()
.expect("Failed to access shared fundsp buffer for writing");
assert!(
values.len() <= buffer.capacity(),
"Cannot write more than {} values",
buffer.capacity()
);
buffer.set_range(0, values.len());
buffer.copy_from(values);
}
pub fn clear(&mut self) {
let mut buffer = self
.buffer
.write()
.expect("Failed to access shared fundsp buffer for writing");
buffer.reset_range();
clear_buffer(buffer.get_mut());
}
}
#[derive(Clone)]
pub struct VarBuffer {
buffer: SharedBuffer,
}
impl VarBuffer {
pub fn new(buffer: &SharedBuffer) -> Self {
Self {
buffer: buffer.clone(),
}
}
}
impl AudioNode for VarBuffer {
const ID: u64 = 0x766172627566; type Inputs = U0;
type Outputs = U1;
#[inline]
fn tick(&mut self, _input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
unreachable!("Can't use tick in VarBuffer")
}
fn process(&mut self, size: usize, _input: &BufferRef, output: &mut BufferMut) {
let output = output.channel_f32_mut(0);
self.buffer.read(&mut output[0..size]);
}
}
pub fn var_buffer(buffer: &SharedBuffer) -> An<VarBuffer> {
An(VarBuffer::new(buffer))
}