caw_core/
stereo.rs

1use crate::{Buf, SigCtx, SigSampleIntoBufT, SigT};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum Channel {
5    Left,
6    Right,
7}
8
9impl Channel {
10    // Apply a 90 degree offset to the right channel so a stereo sine wave would draw a circle with
11    // stereo oscillographics.
12    pub fn circle_phase_offset_01(&self) -> f32 {
13        match self {
14            Self::Left => 0.0,
15            Self::Right => 0.25,
16        }
17    }
18
19    pub fn is_left(&self) -> bool {
20        *self == Self::Left
21    }
22
23    pub fn is_right(&self) -> bool {
24        *self == Self::Right
25    }
26}
27
28#[derive(Debug, Clone, Copy, Default)]
29pub struct Stereo<L, R> {
30    pub left: L,
31    pub right: R,
32}
33
34pub type StereoPair<T> = Stereo<T, T>;
35
36impl<L, R> Stereo<L, R> {
37    pub fn new(left: L, right: R) -> Self {
38        Self { left, right }
39    }
40
41    pub fn map_ref<'a, OL, FL, OR, FR>(
42        &'a self,
43        fl: FL,
44        fr: FR,
45    ) -> Stereo<OL, OR>
46    where
47        FL: FnOnce(&'a L) -> OL,
48        FR: FnOnce(&'a R) -> OR,
49    {
50        Stereo {
51            left: fl(&self.left),
52            right: fr(&self.right),
53        }
54    }
55
56    pub fn as_mut(&mut self) -> Stereo<&mut L, &mut R> {
57        Stereo::new(&mut self.left, &mut self.right)
58    }
59}
60
61impl<L, R> Stereo<L, R>
62where
63    L: SigT,
64    R: SigT,
65{
66    pub fn sample<'a>(
67        &'a mut self,
68        ctx: &'a SigCtx,
69    ) -> Stereo<impl 'a + Buf<L::Item>, impl 'a + Buf<R::Item>> {
70        Stereo {
71            left: self.left.sample(ctx),
72            right: self.right.sample(ctx),
73        }
74    }
75}
76
77impl<L, R> Stereo<L, R>
78where
79    L: SigSampleIntoBufT,
80    R: SigSampleIntoBufT,
81{
82    pub fn sample_into_buf<'a>(
83        &'a mut self,
84        ctx: &'a SigCtx,
85        buf: Stereo<&mut Vec<L::Item>, &mut Vec<R::Item>>,
86    ) {
87        self.left.sample_into_buf(ctx, buf.left);
88        self.right.sample_into_buf(ctx, buf.right);
89    }
90}
91
92impl<S> Stereo<S, S> {
93    pub fn new_fn<F>(mut f: F) -> Self
94    where
95        F: FnMut() -> S,
96    {
97        Self {
98            left: f(),
99            right: f(),
100        }
101    }
102
103    pub fn new_fn_channel<F>(mut f: F) -> Self
104    where
105        F: FnMut(Channel) -> S,
106    {
107        Self {
108            left: f(Channel::Left),
109            right: f(Channel::Right),
110        }
111    }
112
113    pub fn get(&self, channel: Channel) -> &S {
114        match channel {
115            Channel::Left => &self.left,
116            Channel::Right => &self.right,
117        }
118    }
119
120    pub fn get_mut(&mut self, channel: Channel) -> &mut S {
121        match channel {
122            Channel::Left => &mut self.left,
123            Channel::Right => &mut self.right,
124        }
125    }
126}