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 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}