1use crate::{Mul, SignalAt, SignalNext};
12
13#[doc = crate::_tags!(num signal)]
14#[doc = crate::_doc_meta!{
16 location("num/signal", struct SignalClamp),
17}]
18#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
19pub struct SignalClamp<S, T> {
20 pub signal: S,
22 pub min: T,
24 pub max: T,
26}
27#[rustfmt::skip]
28impl<S, T> SignalClamp<S, T> {
29 pub const fn new(signal: S, min: T, max: T) -> Self {
31 Self { signal, min, max }
32 }
33 fn clamp_value(&self, v: T) -> T where T: Copy + PartialOrd {
34 if v < self.min { self.min } else if v > self.max { self.max } else { v }
35 }
36}
37impl<S, T> SignalNext for SignalClamp<S, T>
38where
39 S: SignalNext<Sample = T>,
40 T: Copy + PartialOrd,
41{
42 type Sample = T;
43 fn next(&mut self) -> T {
44 let v = self.signal.next();
45 self.clamp_value(v)
46 }
47}
48impl<X, S, T> SignalAt<X> for SignalClamp<S, T>
49where
50 S: SignalAt<X, Sample = T>,
51 T: Copy + PartialOrd,
52{
53 type Sample = T;
54 fn at(&self, x: X) -> T {
55 self.clamp_value(self.signal.at(x))
56 }
57}
58
59#[doc = crate::_tags!(num signal)]
60#[doc = crate::_doc_meta!{
62 location("num/signal", struct SignalMap),
63}]
64#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
65pub struct SignalMap<S, F> {
66 pub signal: S,
68 pub f: F,
70}
71impl<S, F> SignalMap<S, F> {
72 pub const fn new(signal: S, f: F) -> Self {
74 Self { signal, f }
75 }
76}
77impl<S, F, O> SignalNext for SignalMap<S, F>
78where
79 S: SignalNext,
80 F: FnMut(S::Sample) -> O,
81{
82 type Sample = O;
83 fn next(&mut self) -> O {
84 (self.f)(self.signal.next())
85 }
86}
87impl<X, S, F, O> SignalAt<X> for SignalMap<S, F>
88where
89 S: SignalAt<X>,
90 F: Fn(S::Sample) -> O,
91{
92 type Sample = O;
93 fn at(&self, x: X) -> O {
94 (self.f)(self.signal.at(x))
95 }
96}
97
98#[doc = crate::_tags!(num signal)]
99#[doc = crate::_doc_meta!{
101 location("num/signal", struct SignalScale),
102}]
103#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
104pub struct SignalScale<S, K> {
105 pub signal: S,
107 pub factor: K,
109}
110impl<S, K> SignalScale<S, K> {
111 pub const fn new(signal: S, factor: K) -> Self {
113 Self { signal, factor }
114 }
115}
116impl<S, K> SignalNext for SignalScale<S, K>
117where
118 S: SignalNext,
119 S::Sample: Mul<K, Output = S::Sample>,
120 K: Copy,
121{
122 type Sample = S::Sample;
123 fn next(&mut self) -> Self::Sample {
124 self.signal.next() * self.factor
125 }
126}
127impl<X, S, K> SignalAt<X> for SignalScale<S, K>
128where
129 S: SignalAt<X>,
130 S::Sample: Mul<K, Output = S::Sample>,
131 K: Copy,
132{
133 type Sample = S::Sample;
134 fn at(&self, x: X) -> Self::Sample {
135 self.signal.at(x) * self.factor
136 }
137}
138
139#[doc = crate::_tags!(num signal)]
140#[doc = crate::_doc_meta!{
142 location("num/signal", struct SignalZip),
143}]
144#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
145pub struct SignalZip<A, B, F> {
146 pub a: A,
148 pub b: B,
150 pub f: F,
152}
153impl<A, B, F> SignalZip<A, B, F> {
154 pub const fn new(a: A, b: B, f: F) -> Self {
156 Self { a, b, f }
157 }
158}
159impl<A, B, F, O> SignalNext for SignalZip<A, B, F>
160where
161 A: SignalNext,
162 B: SignalNext,
163 F: FnMut(A::Sample, B::Sample) -> O,
164{
165 type Sample = O;
166 fn next(&mut self) -> O {
167 (self.f)(self.a.next(), self.b.next())
168 }
169}
170impl<X, A, B, F, O> SignalAt<X> for SignalZip<A, B, F>
171where
172 X: Copy,
173 A: SignalAt<X>,
174 B: SignalAt<X>,
175 F: Fn(A::Sample, B::Sample) -> O,
176{
177 type Sample = O;
178
179 fn at(&self, x: X) -> O {
180 (self.f)(self.a.at(x), self.b.at(x))
181 }
182}