1pub use self::i11::I11;
4pub use self::u11::U11;
5pub use self::i20::I20;
6pub use self::u20::U20;
7pub use self::i24::I24;
8pub use self::u24::U24;
9pub use self::i48::I48;
10pub use self::u48::U48;
11
12
13macro_rules! impl_from {
14 ($T:ident: $Rep:ident from {$U:ident : $URep:ty}) => {
15 impl From<$U> for $T {
16 #[inline]
17 fn from(other: $U) -> Self {
18 $T(other.inner() as $Rep)
19 }
20 }
21 };
22 ($T:ident: $Rep:ident from $U:ident) => {
23 impl From<$U> for $T {
24 #[inline]
25 fn from(other: $U) -> Self {
26 $T(other as $Rep)
27 }
28 }
29 };
30}
31
32macro_rules! impl_froms {
33 ($T:ident: $Rep:ident, {$U:ident : $URep:ty}, $($rest:tt)*) => {
34 impl_from!($T: $Rep from {$U: $URep});
35 impl_froms!($T: $Rep, $($rest)*);
36 };
37 ($T:ident: $Rep:ident, {$U:ident : $URep:ty}) => {
38 impl_from!($T: $Rep from {$U: $URep});
39 };
40 ($T:ident: $Rep:ident, $U:ident, $($rest:tt)*) => {
41 impl_from!($T: $Rep from $U);
42 impl_froms!($T: $Rep, $($rest)*);
43 };
44 ($T:ident: $Rep:ident, $U:ident) => {
45 impl_from!($T: $Rep from $U);
46 };
47 ($T:ident: $Rep:ident,) => {};
48}
49
50macro_rules! impl_neg {
51 ($T:ident) => {
52 impl ::core::ops::Neg for $T {
53 type Output = $T;
54 #[inline]
55 fn neg(self) -> $T {
56 $T(-self.0)
57 }
58 }
59 };
60}
61
62macro_rules! new_sample_type {
63 ($T:ident: $Rep:ident, eq: $EQ:expr, min: $MIN:expr, max: $MAX:expr, total: $TOTAL:expr, from: $($rest:tt)*) => {
64 pub const MIN: $T = $T($MIN);
65 pub const MAX: $T = $T($MAX);
66 pub const EQUILIBRIUM: $T = $T($EQ);
67 const MIN_REP: $Rep = $MIN;
68 const MAX_REP: $Rep = $MAX;
69 const TOTAL: $Rep = $TOTAL;
70
71 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Default)]
72 pub struct $T($Rep);
73
74 impl From<$Rep> for $T {
75 #[inline]
76 fn from(val: $Rep) -> Self {
77 $T(val).wrap_overflow()
78 }
79 }
80
81 impl $T {
82 #[inline]
86 pub fn new(val: $Rep) -> Option<Self> {
87 if val > MAX_REP || val < MIN_REP {
88 None
89 } else {
90 Some($T(val))
91 }
92 }
93
94 pub fn new_unchecked(s: $Rep) -> Self {
102 $T(s)
103 }
104
105 #[inline]
107 pub fn inner(self) -> $Rep {
108 self.0
109 }
110
111 #[inline]
113 fn wrap_overflow_once(self) -> Self {
114 if self.0 > MAX_REP { $T(self.0 - TOTAL) }
115 else if self.0 < MIN_REP { $T(self.0 + TOTAL) }
116 else { self }
117 }
118
119 #[inline]
121 fn wrap_overflow(mut self) -> Self {
122 while self.0 > MAX_REP {
123 self.0 -= TOTAL;
124 }
125 while self.0 < MIN_REP {
126 self.0 += TOTAL;
127 }
128 self
129 }
130 }
131
132 impl ::core::ops::Add<$T> for $T {
133 type Output = $T;
134 #[inline]
135 fn add(self, other: Self) -> Self {
136 if cfg!(debug_assertions) {
137 $T::new(self.0 + other.0).expect("arithmetic operation overflowed")
138 } else {
139 $T(self.0 + other.0).wrap_overflow_once()
140 }
141 }
142 }
143
144 impl ::core::ops::Sub<$T> for $T {
145 type Output = $T;
146 #[inline]
147 fn sub(self, other: Self) -> Self {
148 if cfg!(debug_assertions) {
149 $T::new(self.0 - other.0).expect("arithmetic operation overflowed")
150 } else {
151 $T(self.0 - other.0).wrap_overflow_once()
152 }
153 }
154 }
155
156 impl ::core::ops::Mul<$T> for $T {
157 type Output = $T;
158 #[inline]
159 fn mul(self, other: Self) -> Self {
160 if cfg!(debug_assertions) {
161 $T::new(self.0 * other.0).expect("arithmetic operation overflowed")
162 } else {
163 $T::from(self.0 * other.0)
164 }
165 }
166 }
167
168 impl ::core::ops::Div<$T> for $T {
169 type Output = $T;
170 #[inline]
171 fn div(self, other: Self) -> Self {
172 $T(self.0 / other.0)
173 }
174 }
175
176 impl ::core::ops::Not for $T {
177 type Output = $T;
178 #[inline]
179 fn not(self) -> $T {
180 $T(!self.0)
181 }
182 }
183
184 impl ::core::ops::Rem<$T> for $T {
185 type Output = $T;
186 #[inline]
187 fn rem(self, other: Self) -> Self {
188 $T(self.0 % other.0)
189 }
190 }
191
192 impl ::core::ops::Shl<$T> for $T {
193 type Output = $T;
194 #[inline]
195 fn shl(self, other: Self) -> Self {
196 $T(self.0 << other.0)
198 }
199 }
200
201 impl ::core::ops::Shr<$T> for $T {
202 type Output = $T;
203 #[inline]
204 fn shr(self, other: Self) -> Self {
205 $T(self.0 >> other.0)
207 }
208 }
209
210 impl ::core::ops::BitAnd<$T> for $T {
211 type Output = $T;
212 #[inline]
213 fn bitand(self, other: Self) -> Self {
214 $T(self.0 & other.0)
215 }
216 }
217
218 impl ::core::ops::BitOr<$T> for $T {
219 type Output = $T;
220 #[inline]
221 fn bitor(self, other: Self) -> Self {
222 $T(self.0 | other.0)
223 }
224 }
225
226 impl ::core::ops::BitXor<$T> for $T {
227 type Output = $T;
228 #[inline]
229 fn bitxor(self, other: Self) -> Self {
230 $T(self.0 ^ other.0)
231 }
232 }
233
234 impl_froms!($T: $Rep, $($rest)*);
235 };
236}
237
238pub mod i11 {
239 new_sample_type!(I11: i16, eq: 0, min: -1024, max: 1023, total: 2048,
240 from: i8, u8);
241 impl_neg!(I11);
242}
243
244pub mod u11 {
245 new_sample_type!(U11: i16, eq: 1024, min: 0, max: 2047, total: 2048,
246 from: u8);
247 impl_neg!(U11);
248}
249
250pub mod i20 {
251 use super::{I11, U11};
252 new_sample_type!(I20: i32, eq: 0, min: -524_288, max: 524_287, total: 1_048_576,
253 from: i8, {I11:i16}, i16, u8, {U11:i16}, u16);
254}
255
256pub mod u20 {
257 new_sample_type!(U20: i32, eq: 524_288, min: 0, max: 1_048_575, total: 1_048_576,
258 from: u8, u16);
259}
260
261pub mod i24 {
262 use super::{I20, U20};
263 new_sample_type!(I24: i32, eq: 0, min: -8_388_608, max: 8_388_607, total: 16_777_216,
264 from: i8, i16, {I20:i32}, u8, u16, {U20:i32});
265 impl_neg!(I24);
266}
267
268pub mod u24 {
269 use super::U20;
270 new_sample_type!(U24: i32, eq: 8_388_608, min: 0, max: 16_777_215, total: 16_777_216,
271 from: u8, u16, {U20:i32});
272}
273
274pub mod i48 {
275 use super::{I20, I24, U20, U24};
276 new_sample_type!(I48: i64, eq: 0, min: -140_737_488_355_328, max: 140_737_488_355_327, total: 281_474_976_710_656,
277 from: i8, i16, {I20:i32}, {I24:i32}, i32, u8, u16, {U20:i32}, {U24:i32}, u32);
278 impl_neg!(I48);
279}
280
281pub mod u48 {
282 use super::{U20, U24};
283 new_sample_type!(U48: i64, eq: 140_737_488_355_328, min: 0, max: 281_474_976_710_655, total: 281_474_976_710_656,
284 from: u8, u16, {U20:i32}, {U24:i32}, u32);
285}