euphony_mix/
distance.rs

1use crate::{bformat, frame::Frame, sample::Sample, Mixer, Writer};
2
3#[derive(Debug)]
4pub struct Distance<const CHANNELS: usize, W: Writer> {
5    writer: W,
6    config: [bformat::Weights; CHANNELS],
7}
8
9impl<const CHANNELS: usize, W: Writer> Distance<CHANNELS, W> {
10    #[inline]
11    pub fn new(writer: W, config: [bformat::Weights; CHANNELS]) -> Self {
12        debug_assert_eq!(CHANNELS, W::Frame::CHANNELS);
13        Self { writer, config }
14    }
15
16    #[inline]
17    pub fn finish(self) -> W {
18        self.writer
19    }
20}
21
22impl<const CHANNELS: usize, W: Writer> Mixer for Distance<CHANNELS, W> {
23    type Error = W::Error;
24
25    #[inline]
26    fn skip(&mut self, frames: usize) -> Result<(), Self::Error> {
27        self.writer.skip(frames)
28    }
29
30    #[inline]
31    fn mix(&mut self, samples: &[crate::SpatialSample]) -> Result<(), Self::Error> {
32        debug_assert_eq!(CHANNELS, W::Frame::CHANNELS);
33
34        let mut frame = [0.0f64; CHANNELS];
35
36        for s in samples.iter() {
37            for (to, config) in frame.iter_mut().zip(self.config.iter()) {
38                *to = config.dot(s);
39            }
40        }
41
42        let frame = W::Frame::from_fn(|idx| unsafe { frame.get_unchecked(idx).to_sample() });
43        self.writer.write(frame)?;
44
45        Ok(())
46    }
47}