1pub use fixed::types::{I1F7 as q7, I1F15 as q15, I1F31 as q31};
4
5pub type Q8F7 = fixed::FixedI16<fixed::types::extra::U7>;
10
11#[allow(non_camel_case_types)]
17pub type q63 = i64;
18#[allow(non_camel_case_types)]
19pub type f32_t = f32;
20#[allow(non_camel_case_types)]
21pub type f64_t = f64;
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25#[repr(i8)]
26pub enum Status {
27 Success = 0,
29 ArgumentError = -1,
31 LengthError = -2,
33 SizeMismatch = -3,
35 NanInf = -4,
37 Singular = -5,
39 TestFailure = -6,
41 DecompositionFailure = -7,
43}
44
45#[derive(Debug, Clone, Copy, PartialEq, Default)]
47#[repr(C)]
48pub struct Complex<T> {
49 pub real: T,
50 pub imag: T,
51}
52
53impl<T> Complex<T> {
54 #[inline(always)]
55 pub const fn new(real: T, imag: T) -> Self {
56 Self { real, imag }
57 }
58}
59
60#[inline(always)]
62pub fn q15_mult(a: q15, b: q15) -> q15 {
63 a.saturating_mul(b)
64}
65
66#[inline(always)]
68pub fn q31_mult(a: q31, b: q31) -> q31 {
69 a.saturating_mul(b)
70}
71
72#[inline(always)]
74pub fn q7_mult(a: q7, b: q7) -> q7 {
75 a.saturating_mul(b)
76}
77
78#[inline(always)]
81fn saturating_div_q<F>(a: F, b: F) -> F
82where
83 F: fixed::traits::Fixed + PartialOrd,
84{
85 match a.checked_div(b) {
86 Some(v) => v,
87 None if b == F::ZERO => {
88 if a >= F::ZERO {
89 F::MAX
90 } else {
91 F::MIN
92 }
93 }
94 None => {
95 if (a >= F::ZERO) == (b >= F::ZERO) {
96 F::MAX
97 } else {
98 F::MIN
99 }
100 }
101 }
102}
103
104pub trait DspSample:
113 Copy
114 + Default
115 + PartialEq
116 + PartialOrd
117 + core::ops::Add<Output = Self>
118 + core::ops::Sub<Output = Self>
119 + core::ops::Mul<Output = Self>
120 + core::ops::Neg<Output = Self>
121{
122 const ZERO: Self;
124 const ONE: Self;
126
127 fn sat_add(self, rhs: Self) -> Self;
129 fn sat_sub(self, rhs: Self) -> Self;
131 fn sat_mul(self, rhs: Self) -> Self;
133 fn sat_div(self, rhs: Self) -> Self;
135 fn abs_val(self) -> Self;
137 fn to_f32(self) -> f32;
139 fn from_f32(val: f32) -> Self;
141}
142
143impl DspSample for f32 {
144 const ZERO: Self = 0.0;
145 const ONE: Self = 1.0;
146
147 #[inline(always)]
148 fn sat_add(self, rhs: Self) -> Self {
149 self + rhs
150 }
151
152 #[inline(always)]
153 fn sat_sub(self, rhs: Self) -> Self {
154 self - rhs
155 }
156
157 #[inline(always)]
158 fn sat_mul(self, rhs: Self) -> Self {
159 self * rhs
160 }
161
162 #[inline(always)]
163 fn sat_div(self, rhs: Self) -> Self {
164 self / rhs
165 }
166
167 #[inline(always)]
168 fn abs_val(self) -> Self {
169 if self < 0.0 { -self } else { self }
170 }
171
172 #[inline(always)]
173 fn to_f32(self) -> f32 {
174 self
175 }
176
177 #[inline(always)]
178 fn from_f32(val: f32) -> Self {
179 val
180 }
181}
182
183impl DspSample for f64 {
184 const ZERO: Self = 0.0;
185 const ONE: Self = 1.0;
186
187 #[inline(always)]
188 fn sat_add(self, rhs: Self) -> Self {
189 self + rhs
190 }
191
192 #[inline(always)]
193 fn sat_sub(self, rhs: Self) -> Self {
194 self - rhs
195 }
196
197 #[inline(always)]
198 fn sat_mul(self, rhs: Self) -> Self {
199 self * rhs
200 }
201
202 #[inline(always)]
203 fn sat_div(self, rhs: Self) -> Self {
204 self / rhs
205 }
206
207 #[inline(always)]
208 fn abs_val(self) -> Self {
209 if self < 0.0 { -self } else { self }
210 }
211
212 #[inline(always)]
213 fn to_f32(self) -> f32 {
214 self as f32
215 }
216
217 #[inline(always)]
218 fn from_f32(val: f32) -> Self {
219 val as f64
220 }
221}
222
223impl DspSample for q15 {
224 const ZERO: Self = Self::ZERO;
225 const ONE: Self = Self::MAX;
226
227 #[inline(always)]
228 fn sat_add(self, rhs: Self) -> Self {
229 self.saturating_add(rhs)
230 }
231
232 #[inline(always)]
233 fn sat_sub(self, rhs: Self) -> Self {
234 self.saturating_sub(rhs)
235 }
236
237 #[inline(always)]
238 fn sat_mul(self, rhs: Self) -> Self {
239 self.saturating_mul(rhs)
240 }
241
242 #[inline(always)]
243 fn sat_div(self, rhs: Self) -> Self {
244 saturating_div_q(self, rhs)
245 }
246
247 #[inline(always)]
248 fn abs_val(self) -> Self {
249 self.saturating_abs()
250 }
251
252 #[inline(always)]
253 fn to_f32(self) -> f32 {
254 self.to_num()
255 }
256
257 #[inline(always)]
258 fn from_f32(val: f32) -> Self {
259 Self::saturating_from_num(val)
260 }
261}
262
263impl DspSample for q31 {
264 const ZERO: Self = Self::ZERO;
265 const ONE: Self = Self::MAX;
266
267 #[inline(always)]
268 fn sat_add(self, rhs: Self) -> Self {
269 self.saturating_add(rhs)
270 }
271
272 #[inline(always)]
273 fn sat_sub(self, rhs: Self) -> Self {
274 self.saturating_sub(rhs)
275 }
276
277 #[inline(always)]
278 fn sat_mul(self, rhs: Self) -> Self {
279 self.saturating_mul(rhs)
280 }
281
282 #[inline(always)]
283 fn sat_div(self, rhs: Self) -> Self {
284 saturating_div_q(self, rhs)
285 }
286
287 #[inline(always)]
288 fn abs_val(self) -> Self {
289 self.saturating_abs()
290 }
291
292 #[inline(always)]
293 fn to_f32(self) -> f32 {
294 self.to_num()
295 }
296
297 #[inline(always)]
298 fn from_f32(val: f32) -> Self {
299 Self::saturating_from_num(val)
300 }
301}
302
303impl<T: core::ops::Add<Output = T>> core::ops::Add for Complex<T> {
308 type Output = Self;
309 #[inline(always)]
310 fn add(self, rhs: Self) -> Self {
311 Self {
312 real: self.real + rhs.real,
313 imag: self.imag + rhs.imag,
314 }
315 }
316}
317
318impl<T: core::ops::Sub<Output = T>> core::ops::Sub for Complex<T> {
319 type Output = Self;
320 #[inline(always)]
321 fn sub(self, rhs: Self) -> Self {
322 Self {
323 real: self.real - rhs.real,
324 imag: self.imag - rhs.imag,
325 }
326 }
327}
328
329impl<T: core::ops::Neg<Output = T>> core::ops::Neg for Complex<T> {
330 type Output = Self;
331 #[inline(always)]
332 fn neg(self) -> Self {
333 Self {
334 real: -self.real,
335 imag: -self.imag,
336 }
337 }
338}
339
340impl<T: Copy + core::ops::Add<Output = T> + core::ops::Sub<Output = T> + core::ops::Mul<Output = T>>
341 core::ops::Mul for Complex<T>
342{
343 type Output = Self;
344 #[inline(always)]
345 fn mul(self, rhs: Self) -> Self {
346 Self {
347 real: self.real * rhs.real - self.imag * rhs.imag,
348 imag: self.real * rhs.imag + self.imag * rhs.real,
349 }
350 }
351}
352
353impl<T: Copy + core::ops::Mul<Output = T>> core::ops::Mul<T> for Complex<T> {
354 type Output = Self;
355 #[inline(always)]
356 fn mul(self, scalar: T) -> Self {
357 Self {
358 real: self.real * scalar,
359 imag: self.imag * scalar,
360 }
361 }
362}