euphony_node/
sink.rs

1use euphony_units::coordinates::Polar;
2
3use crate::{BoxProcessor, Buffers, Inputs, Node, Output};
4
5pub trait Sink: 'static + Send + Sized {
6    #[inline]
7    fn spawn(self) -> BoxProcessor {
8        Wrapper::spawn(self)
9    }
10
11    fn write<S: Iterator<Item = (f64, Polar<f64>)>>(&mut self, samples: S);
12}
13
14#[repr(u8)]
15#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
16pub enum SampleType {
17    Pcm = 0,
18    /// The azimuth (or azimuthal angle) is the signed angle measured from
19    /// the azimuth reference direction to the orthogonal projection of the
20    /// line segment OP on the reference plane.
21    Azimuth = 1,
22    /// The inclination (or polar angle) is the angle between the zenith
23    /// direction and the line segment OP.
24    Inclination = 2,
25    /// The radius or radial distance is the Euclidean distance from the
26    /// origin O to P.
27    Radius = 3,
28}
29
30#[derive(Clone, Debug, Default)]
31struct Wrapper<Inner: Sink> {
32    inner: Inner,
33}
34
35impl<Inner: Sink> Wrapper<Inner> {
36    fn spawn(inner: Inner) -> BoxProcessor {
37        crate::spawn(Self { inner })
38    }
39}
40
41impl<Inner: Sink> Node<4, 0> for Wrapper<Inner> {
42    const DEFAULTS: [f64; 4] = [0.0, 0.0, 0.0, 0.0];
43
44    #[inline]
45    fn process(&mut self, inputs: Inputs<4>, _buffer: Buffers<0>, samples: &mut [f64]) {
46        let pcm = inputs.get(0);
47        let pcm = pcm.iter().take(samples.len());
48        let azimuth = inputs.get(1);
49        let azimuth = azimuth.iter().take(samples.len());
50        let inclination = inputs.get(2);
51        let inclination = inclination.iter().take(samples.len());
52        let radius = inputs.get(3);
53        let radius = radius.iter().take(samples.len());
54
55        let coord = azimuth
56            .zip(inclination)
57            .zip(radius)
58            .map(|((azimuth, inclination), radius)| Polar {
59                azimuth,
60                inclination,
61                radius,
62            });
63
64        let samples = pcm.zip(coord);
65
66        self.inner.write(samples)
67    }
68
69    #[inline]
70    fn process_full(&mut self, inputs: Inputs<4>, _buffer: Buffers<0>, _samples: &mut Output) {
71        let pcm = inputs.get(0);
72        let pcm = pcm.iter();
73        let azimuth = inputs.get(1);
74        let azimuth = azimuth.iter();
75        let inclination = inputs.get(2);
76        let inclination = inclination.iter();
77        let radius = inputs.get(3);
78        let radius = radius.iter();
79
80        let coord = azimuth
81            .zip(inclination)
82            .zip(radius)
83            .map(|((azimuth, inclination), radius)| Polar {
84                azimuth,
85                inclination,
86                radius,
87            });
88
89        let samples = pcm.zip(coord);
90
91        self.inner.write(samples)
92    }
93}