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}