use crate::{Frame, Sample, Seek, Signal};
pub struct Downmix<T: ?Sized>(T);
impl<T> Downmix<T> {
pub fn new(signal: T) -> Self {
Self(signal)
}
}
impl<T: Signal + ?Sized> Signal for Downmix<T>
where
T::Frame: Frame,
{
type Frame = Sample;
fn sample(&mut self, interval: f32, out: &mut [Sample]) {
const CHUNK_SIZE: usize = 256;
let mut buf = [Frame::ZERO; CHUNK_SIZE];
for chunk in out.chunks_mut(CHUNK_SIZE) {
self.0.sample(interval, &mut buf);
for (i, o) in buf.iter_mut().zip(chunk) {
*o = i.channels().iter().copied().sum();
}
}
}
fn is_finished(&self) -> bool {
self.0.is_finished()
}
}
impl<T: Seek + Signal + ?Sized> Seek for Downmix<T>
where
T::Frame: Frame,
{
fn seek(&mut self, seconds: f32) {
self.0.seek(seconds);
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Constant;
#[test]
fn smoke() {
let mut signal = Downmix::new(Constant::new([1.0, 2.0]));
let mut out = [0.0; 384];
signal.sample(1.0, &mut out);
assert_eq!(out, [3.0; 384]);
}
}