1#[cfg(feature = "fixed")]
4pub use fixed::types::{I1F7 as q7, I1F15 as q15, I1F31 as q31, I16F16};
5
6#[cfg(feature = "fixed")]
7pub type Q8F7 = fixed::FixedI16<fixed::types::extra::U7>;
9
10#[cfg(feature = "fixed")]
11pub type Q2F14 = fixed::FixedI16<fixed::types::extra::U14>;
13
14#[cfg(not(feature = "fixed"))]
15pub use fallback::*;
16
17#[cfg(not(feature = "fixed"))]
18mod fallback {
19 pub trait FixedNum: Copy {
20 fn to_raw_fixed(self, frac: u32, min_val: i64, max_val: i64, saturate: bool) -> i64;
21 fn from_raw_fixed(raw: i64, frac: u32) -> Self;
22 }
23
24 impl FixedNum for f32 {
25 #[inline(always)]
26 fn to_raw_fixed(self, frac: u32, min_val: i64, max_val: i64, saturate: bool) -> i64 {
27 (self as f64).to_raw_fixed(frac, min_val, max_val, saturate)
28 }
29 #[inline(always)]
30 fn from_raw_fixed(raw: i64, frac: u32) -> Self {
31 f64::from_raw_fixed(raw, frac) as f32
32 }
33 }
34
35 impl FixedNum for f64 {
36 #[inline(always)]
37 fn to_raw_fixed(self, frac: u32, min_val: i64, max_val: i64, saturate: bool) -> i64 {
38 if self.is_nan() {
39 return 0;
40 }
41 let scale = (1u64 << frac) as f64;
42 let scaled = self * scale;
43 if saturate {
44 if scaled >= max_val as f64 {
45 return max_val;
46 }
47 if scaled <= min_val as f64 {
48 return min_val;
49 }
50 }
51 let sign = if scaled < 0.0 { -1i64 } else { 1i64 };
52 let abs_val = if scaled < 0.0 { -scaled } else { scaled };
53 let abs_int = abs_val as i64;
54 let frac_part = abs_val - (abs_int as f64);
55 let rounded_abs = if frac_part > 0.5 {
56 abs_int + 1
57 } else if frac_part < 0.5 {
58 abs_int
59 } else {
60 if (abs_int & 1) != 0 {
61 abs_int + 1
62 } else {
63 abs_int
64 }
65 };
66 let res = sign.wrapping_mul(rounded_abs);
67 if saturate {
68 res.clamp(min_val, max_val)
69 } else {
70 res
71 }
72 }
73
74 #[inline(always)]
75 fn from_raw_fixed(raw: i64, frac: u32) -> Self {
76 (raw as f64) / ((1u64 << frac) as f64)
77 }
78 }
79
80 macro_rules! impl_fixed_num_int {
81 ($($t:ty),*) => {
82 $(
83 impl FixedNum for $t {
84 #[inline(always)]
85 fn to_raw_fixed(self, frac: u32, min_val: i64, max_val: i64, saturate: bool) -> i64 {
86 let shifted = (self as i64).wrapping_shl(frac);
87 if saturate {
88 shifted.clamp(min_val, max_val)
89 } else {
90 shifted
91 }
92 }
93 #[inline(always)]
94 fn from_raw_fixed(raw: i64, frac: u32) -> Self {
95 (raw >> frac) as $t
96 }
97 }
98 )*
99 };
100 }
101 impl_fixed_num_int!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize);
102
103 macro_rules! define_fallback_type {
104 ($name:ident, $raw:ident, $wide:ident, $frac:expr) => {
105 #[allow(non_camel_case_types)]
106 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
107 #[repr(transparent)]
108 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
109 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
110 #[cfg_attr(feature = "serde", serde(transparent))]
111 pub struct $name(pub $raw);
112
113 impl $name {
114 pub const ZERO: Self = Self(0);
115 pub const MAX: Self = Self($raw::MAX);
116 pub const MIN: Self = Self($raw::MIN);
117
118 #[inline(always)]
119 pub const fn from_bits(bits: $raw) -> Self {
120 Self(bits)
121 }
122
123 #[inline(always)]
124 pub const fn to_bits(self) -> $raw {
125 self.0
126 }
127
128 #[inline(always)]
129 pub fn from_num<T: FixedNum>(v: T) -> Self {
130 Self(
131 T::to_raw_fixed(v, $frac, $raw::MIN as i64, $raw::MAX as i64, false)
132 as $raw,
133 )
134 }
135
136 #[inline(always)]
137 pub fn saturating_from_num<T: FixedNum>(v: T) -> Self {
138 Self(
139 T::to_raw_fixed(v, $frac, $raw::MIN as i64, $raw::MAX as i64, true) as $raw,
140 )
141 }
142
143 #[inline(always)]
144 pub fn to_num<T: FixedNum>(self) -> T {
145 T::from_raw_fixed(self.0 as i64, $frac)
146 }
147
148 #[inline(always)]
149 pub const fn saturating_add(self, rhs: Self) -> Self {
150 Self(self.0.saturating_add(rhs.0))
151 }
152
153 #[inline(always)]
154 pub const fn saturating_sub(self, rhs: Self) -> Self {
155 Self(self.0.saturating_sub(rhs.0))
156 }
157
158 #[inline(always)]
159 pub fn saturating_mul(self, rhs: Self) -> Self {
160 let prod = ((self.0 as $wide) * (rhs.0 as $wide)) >> $frac;
161 Self(prod.clamp($raw::MIN as $wide, $raw::MAX as $wide) as $raw)
162 }
163
164 #[inline(always)]
165 pub const fn saturating_neg(self) -> Self {
166 Self(self.0.saturating_neg())
167 }
168
169 #[inline(always)]
170 pub const fn saturating_abs(self) -> Self {
171 Self(self.0.saturating_abs())
172 }
173
174 #[inline(always)]
175 pub const fn abs(self) -> Self {
176 Self(self.0.wrapping_abs())
177 }
178
179 #[inline(always)]
180 pub const fn wrapping_add(self, rhs: Self) -> Self {
181 Self(self.0.wrapping_add(rhs.0))
182 }
183
184 #[inline(always)]
185 pub const fn wrapping_sub(self, rhs: Self) -> Self {
186 Self(self.0.wrapping_sub(rhs.0))
187 }
188
189 #[inline(always)]
190 pub const fn wrapping_neg(self) -> Self {
191 Self(self.0.wrapping_neg())
192 }
193
194 #[inline(always)]
195 pub fn wrapping_mul(self, rhs: Self) -> Self {
196 let prod = (self.0 as $wide).wrapping_mul(rhs.0 as $wide);
197 Self((prod >> $frac) as $raw)
198 }
199
200 #[inline(always)]
201 pub const fn wrapping_mul_int(self, n: i32) -> Self {
202 Self(self.0.wrapping_mul(n as $raw))
203 }
204
205 #[inline(always)]
206 pub fn wrapping_div(self, rhs: Self) -> Self {
207 if rhs.0 == 0 {
208 return Self(0);
209 }
210 let a = (self.0 as $wide) << $frac;
211 let b = rhs.0 as $wide;
212 Self((a / b) as $raw)
213 }
214
215 #[inline(always)]
216 pub fn wrapping_div_int(self, n: i32) -> Self {
217 if n == 0 {
218 return Self(0);
219 }
220 Self(self.0.wrapping_div(n as $raw))
221 }
222
223 #[inline(always)]
224 pub fn recip(self) -> Self {
225 if self.0 == 0 {
226 return Self::MAX;
227 }
228 let one_shifted = 1i64 << (2 * $frac);
229 Self((one_shifted / (self.0 as i64)) as $raw)
230 }
231
232 #[inline(always)]
233 pub fn checked_div(self, rhs: Self) -> Option<Self> {
234 if rhs.0 == 0 {
235 return None;
236 }
237 let a = (self.0 as $wide) << $frac;
238 let b = rhs.0 as $wide;
239 let res = a / b;
240 if res > $raw::MAX as $wide || res < $raw::MIN as $wide {
241 None
242 } else {
243 Some(Self(res as $raw))
244 }
245 }
246 }
247
248 impl FixedNum for $name {
249 #[inline(always)]
250 fn to_raw_fixed(
251 self,
252 frac: u32,
253 min_val: i64,
254 max_val: i64,
255 saturate: bool,
256 ) -> i64 {
257 let shifted = if frac >= $frac {
258 (self.0 as i64) << (frac - $frac)
259 } else {
260 (self.0 as i64) >> ($frac - frac)
261 };
262 if saturate {
263 shifted.clamp(min_val, max_val)
264 } else {
265 shifted
266 }
267 }
268
269 #[inline(always)]
270 fn from_raw_fixed(raw: i64, frac: u32) -> Self {
271 let bits = if $frac >= frac {
272 (raw << ($frac - frac)) as $raw
273 } else {
274 (raw >> (frac - $frac)) as $raw
275 };
276 Self(bits)
277 }
278 }
279
280 impl core::ops::Add for $name {
281 type Output = Self;
282 #[inline(always)]
283 fn add(self, rhs: Self) -> Self {
284 Self(self.0.wrapping_add(rhs.0))
285 }
286 }
287
288 impl core::ops::AddAssign for $name {
289 #[inline(always)]
290 fn add_assign(&mut self, rhs: Self) {
291 self.0 = self.0.wrapping_add(rhs.0);
292 }
293 }
294
295 impl core::ops::Sub for $name {
296 type Output = Self;
297 #[inline(always)]
298 fn sub(self, rhs: Self) -> Self {
299 Self(self.0.wrapping_sub(rhs.0))
300 }
301 }
302
303 impl core::ops::SubAssign for $name {
304 #[inline(always)]
305 fn sub_assign(&mut self, rhs: Self) {
306 self.0 = self.0.wrapping_sub(rhs.0);
307 }
308 }
309
310 impl core::ops::Mul for $name {
311 type Output = Self;
312 #[inline(always)]
313 fn mul(self, rhs: Self) -> Self {
314 let prod = (self.0 as $wide) * (rhs.0 as $wide);
315 Self((prod >> $frac) as $raw)
316 }
317 }
318
319 impl core::ops::MulAssign for $name {
320 #[inline(always)]
321 fn mul_assign(&mut self, rhs: Self) {
322 *self = *self * rhs;
323 }
324 }
325
326 impl core::ops::Neg for $name {
327 type Output = Self;
328 #[inline(always)]
329 fn neg(self) -> Self {
330 Self(self.0.wrapping_neg())
331 }
332 }
333
334 impl core::fmt::Display for $name {
335 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
336 write!(f, "{}", self.0)
337 }
338 }
339
340 macro_rules! impl_cmp_int {
341 ($int:ident) => {
342 impl PartialEq<$int> for $name {
343 #[inline(always)]
344 fn eq(&self, other: &$int) -> bool {
345 let other_fixed = (*other as i64) << $frac;
346 (self.0 as i64) == other_fixed
347 }
348 }
349 impl PartialOrd<$int> for $name {
350 #[inline(always)]
351 fn partial_cmp(&self, other: &$int) -> Option<core::cmp::Ordering> {
352 let other_fixed = (*other as i64) << $frac;
353 (self.0 as i64).partial_cmp(&other_fixed)
354 }
355 }
356 impl PartialEq<$name> for $int {
357 #[inline(always)]
358 fn eq(&self, other: &$name) -> bool {
359 other.eq(self)
360 }
361 }
362 impl PartialOrd<$name> for $int {
363 #[inline(always)]
364 fn partial_cmp(&self, other: &$name) -> Option<core::cmp::Ordering> {
365 let self_fixed = (*self as i64) << $frac;
366 self_fixed.partial_cmp(&(other.0 as i64))
367 }
368 }
369 };
370 }
371 impl_cmp_int!(i8);
372 impl_cmp_int!(i16);
373 impl_cmp_int!(i32);
374 impl_cmp_int!(i64);
375 impl_cmp_int!(isize);
376 impl_cmp_int!(u8);
377 impl_cmp_int!(u16);
378 impl_cmp_int!(u32);
379 impl_cmp_int!(u64);
380 impl_cmp_int!(usize);
381 };
382 }
383
384 define_fallback_type!(q7, i8, i32, 7);
385 define_fallback_type!(q15, i16, i32, 15);
386 define_fallback_type!(q31, i32, i64, 31);
387 define_fallback_type!(Q8F7, i16, i32, 7);
388 define_fallback_type!(Q2F14, i16, i32, 14);
389 define_fallback_type!(I16F16, i32, i64, 16);
390}
391
392#[allow(non_camel_case_types)]
398pub type q63 = i64;
399#[allow(non_camel_case_types)]
400pub type f32_t = f32;
401#[allow(non_camel_case_types)]
402pub type f64_t = f64;
403
404#[derive(Debug, Clone, Copy, PartialEq, Eq)]
406#[repr(i8)]
407pub enum Status {
408 Success = 0,
410 ArgumentError = -1,
412 LengthError = -2,
414 SizeMismatch = -3,
416 NanInf = -4,
418 Singular = -5,
420 TestFailure = -6,
422 DecompositionFailure = -7,
424}
425
426#[derive(Debug, Clone, Copy, PartialEq, Default)]
428#[repr(C)]
429pub struct Complex<T> {
430 pub real: T,
431 pub imag: T,
432}
433
434impl<T> Complex<T> {
435 #[inline(always)]
436 pub const fn new(real: T, imag: T) -> Self {
437 Self { real, imag }
438 }
439}
440
441#[inline(always)]
443pub fn q15_mult(a: q15, b: q15) -> q15 {
444 a.saturating_mul(b)
445}
446
447#[inline(always)]
449pub fn q31_mult(a: q31, b: q31) -> q31 {
450 a.saturating_mul(b)
451}
452
453#[inline(always)]
455pub fn q7_mult(a: q7, b: q7) -> q7 {
456 a.saturating_mul(b)
457}
458
459#[inline(always)]
461fn saturating_div_q15(a: q15, b: q15) -> q15 {
462 if b == q15::ZERO {
463 if a >= q15::ZERO { q15::MAX } else { q15::MIN }
464 } else {
465 match a.checked_div(b) {
466 Some(v) => v,
467 None => {
468 if (a >= q15::ZERO) == (b >= q15::ZERO) {
469 q15::MAX
470 } else {
471 q15::MIN
472 }
473 }
474 }
475 }
476}
477
478#[inline(always)]
480fn saturating_div_q31(a: q31, b: q31) -> q31 {
481 if b == q31::ZERO {
482 if a >= q31::ZERO { q31::MAX } else { q31::MIN }
483 } else {
484 match a.checked_div(b) {
485 Some(v) => v,
486 None => {
487 if (a >= q31::ZERO) == (b >= q31::ZERO) {
488 q31::MAX
489 } else {
490 q31::MIN
491 }
492 }
493 }
494 }
495}
496
497pub trait DspSample:
506 Copy
507 + Default
508 + PartialEq
509 + PartialOrd
510 + core::ops::Add<Output = Self>
511 + core::ops::Sub<Output = Self>
512 + core::ops::Mul<Output = Self>
513 + core::ops::Neg<Output = Self>
514{
515 const ZERO: Self;
517 const ONE: Self;
519
520 fn sat_add(self, rhs: Self) -> Self;
522 fn sat_sub(self, rhs: Self) -> Self;
524 fn sat_mul(self, rhs: Self) -> Self;
526 fn sat_div(self, rhs: Self) -> Self;
528 fn abs_val(self) -> Self;
530 fn to_f32(self) -> f32;
532 fn from_f32(val: f32) -> Self;
534}
535
536impl DspSample for f32 {
537 const ZERO: Self = 0.0;
538 const ONE: Self = 1.0;
539
540 #[inline(always)]
541 fn sat_add(self, rhs: Self) -> Self {
542 self + rhs
543 }
544
545 #[inline(always)]
546 fn sat_sub(self, rhs: Self) -> Self {
547 self - rhs
548 }
549
550 #[inline(always)]
551 fn sat_mul(self, rhs: Self) -> Self {
552 self * rhs
553 }
554
555 #[inline(always)]
556 fn sat_div(self, rhs: Self) -> Self {
557 self / rhs
558 }
559
560 #[inline(always)]
561 fn abs_val(self) -> Self {
562 if self < 0.0 { -self } else { self }
563 }
564
565 #[inline(always)]
566 fn to_f32(self) -> f32 {
567 self
568 }
569
570 #[inline(always)]
571 fn from_f32(val: f32) -> Self {
572 val
573 }
574}
575
576impl DspSample for f64 {
577 const ZERO: Self = 0.0;
578 const ONE: Self = 1.0;
579
580 #[inline(always)]
581 fn sat_add(self, rhs: Self) -> Self {
582 self + rhs
583 }
584
585 #[inline(always)]
586 fn sat_sub(self, rhs: Self) -> Self {
587 self - rhs
588 }
589
590 #[inline(always)]
591 fn sat_mul(self, rhs: Self) -> Self {
592 self * rhs
593 }
594
595 #[inline(always)]
596 fn sat_div(self, rhs: Self) -> Self {
597 self / rhs
598 }
599
600 #[inline(always)]
601 fn abs_val(self) -> Self {
602 if self < 0.0 { -self } else { self }
603 }
604
605 #[inline(always)]
606 fn to_f32(self) -> f32 {
607 self as f32
608 }
609
610 #[inline(always)]
611 fn from_f32(val: f32) -> Self {
612 val as f64
613 }
614}
615
616impl DspSample for q15 {
617 const ZERO: Self = Self::ZERO;
618 const ONE: Self = Self::MAX;
619
620 #[inline(always)]
621 fn sat_add(self, rhs: Self) -> Self {
622 self.saturating_add(rhs)
623 }
624
625 #[inline(always)]
626 fn sat_sub(self, rhs: Self) -> Self {
627 self.saturating_sub(rhs)
628 }
629
630 #[inline(always)]
631 fn sat_mul(self, rhs: Self) -> Self {
632 self.saturating_mul(rhs)
633 }
634
635 #[inline(always)]
636 fn sat_div(self, rhs: Self) -> Self {
637 saturating_div_q15(self, rhs)
638 }
639
640 #[inline(always)]
641 fn abs_val(self) -> Self {
642 self.saturating_abs()
643 }
644
645 #[inline(always)]
646 fn to_f32(self) -> f32 {
647 self.to_num()
648 }
649
650 #[inline(always)]
651 fn from_f32(val: f32) -> Self {
652 Self::saturating_from_num(val)
653 }
654}
655
656impl DspSample for q31 {
657 const ZERO: Self = Self::ZERO;
658 const ONE: Self = Self::MAX;
659
660 #[inline(always)]
661 fn sat_add(self, rhs: Self) -> Self {
662 self.saturating_add(rhs)
663 }
664
665 #[inline(always)]
666 fn sat_sub(self, rhs: Self) -> Self {
667 self.saturating_sub(rhs)
668 }
669
670 #[inline(always)]
671 fn sat_mul(self, rhs: Self) -> Self {
672 self.saturating_mul(rhs)
673 }
674
675 #[inline(always)]
676 fn sat_div(self, rhs: Self) -> Self {
677 saturating_div_q31(self, rhs)
678 }
679
680 #[inline(always)]
681 fn abs_val(self) -> Self {
682 self.saturating_abs()
683 }
684
685 #[inline(always)]
686 fn to_f32(self) -> f32 {
687 self.to_num()
688 }
689
690 #[inline(always)]
691 fn from_f32(val: f32) -> Self {
692 Self::saturating_from_num(val)
693 }
694}
695
696impl<T: core::ops::Add<Output = T>> core::ops::Add for Complex<T> {
701 type Output = Self;
702 #[inline(always)]
703 fn add(self, rhs: Self) -> Self {
704 Self {
705 real: self.real + rhs.real,
706 imag: self.imag + rhs.imag,
707 }
708 }
709}
710
711impl<T: core::ops::Sub<Output = T>> core::ops::Sub for Complex<T> {
712 type Output = Self;
713 #[inline(always)]
714 fn sub(self, rhs: Self) -> Self {
715 Self {
716 real: self.real - rhs.real,
717 imag: self.imag - rhs.imag,
718 }
719 }
720}
721
722impl<T: core::ops::Neg<Output = T>> core::ops::Neg for Complex<T> {
723 type Output = Self;
724 #[inline(always)]
725 fn neg(self) -> Self {
726 Self {
727 real: -self.real,
728 imag: -self.imag,
729 }
730 }
731}
732
733impl<T: Copy + core::ops::Add<Output = T> + core::ops::Sub<Output = T> + core::ops::Mul<Output = T>>
734 core::ops::Mul for Complex<T>
735{
736 type Output = Self;
737 #[inline(always)]
738 fn mul(self, rhs: Self) -> Self {
739 Self {
740 real: self.real * rhs.real - self.imag * rhs.imag,
741 imag: self.real * rhs.imag + self.imag * rhs.real,
742 }
743 }
744}
745
746impl<T: Copy + core::ops::Mul<Output = T>> core::ops::Mul<T> for Complex<T> {
747 type Output = Self;
748 #[inline(always)]
749 fn mul(self, scalar: T) -> Self {
750 Self {
751 real: self.real * scalar,
752 imag: self.imag * scalar,
753 }
754 }
755}