use aether_core::{node::DspNode, param::ParamBlock, BUFFER_SIZE, MAX_INPUTS};
pub struct Mixer;
impl DspNode for Mixer {
fn process(
&mut self,
inputs: &[Option<&[f32; BUFFER_SIZE]>; MAX_INPUTS],
output: &mut [f32; BUFFER_SIZE],
params: &mut ParamBlock,
_sample_rate: f32,
) {
output.fill(0.0);
for (slot, maybe_input) in inputs.iter().enumerate() {
if let Some(buf) = maybe_input {
let gain = if slot < params.count {
params.get(slot).current
} else {
1.0
};
mix_channel(output, buf, gain);
}
}
params.tick_all();
}
fn type_name(&self) -> &'static str {
"Mixer"
}
}
#[inline(always)]
fn mix_channel(output: &mut [f32; BUFFER_SIZE], input: &[f32; BUFFER_SIZE], gain: f32) {
const CHUNK: usize = 4;
let chunks = BUFFER_SIZE / CHUNK;
if (gain - 1.0).abs() < f32::EPSILON {
for c in 0..chunks {
let i = c * CHUNK;
output[i] += input[i];
output[i + 1] += input[i + 1];
output[i + 2] += input[i + 2];
output[i + 3] += input[i + 3];
}
for i in (chunks * CHUNK)..BUFFER_SIZE {
output[i] += input[i];
}
} else {
for c in 0..chunks {
let i = c * CHUNK;
output[i] = gain.mul_add(input[i], output[i]);
output[i + 1] = gain.mul_add(input[i + 1], output[i + 1]);
output[i + 2] = gain.mul_add(input[i + 2], output[i + 2]);
output[i + 3] = gain.mul_add(input[i + 3], output[i + 3]);
}
for i in (chunks * CHUNK)..BUFFER_SIZE {
output[i] = gain.mul_add(input[i], output[i]);
}
}
}