1#[allow(non_camel_case_types)]
4pub type q7 = i8;
5#[allow(non_camel_case_types)]
6pub type q15 = i16;
7#[allow(non_camel_case_types)]
8pub type q31 = i32;
9#[allow(non_camel_case_types)]
10pub type q63 = i64;
11#[allow(non_camel_case_types)]
12pub type f32_t = f32;
13#[allow(non_camel_case_types)]
14pub type f64_t = f64;
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18#[repr(i8)]
19pub enum Status {
20 Success = 0,
22 ArgumentError = -1,
24 LengthError = -2,
26 SizeMismatch = -3,
28 NanInf = -4,
30 Singular = -5,
32 TestFailure = -6,
34 DecompositionFailure = -7,
36}
37
38#[derive(Debug, Clone, Copy, PartialEq, Default)]
40#[repr(C)]
41pub struct Complex<T> {
42 pub real: T,
43 pub imag: T,
44}
45
46impl<T> Complex<T> {
47 #[inline(always)]
48 pub const fn new(real: T, imag: T) -> Self {
49 Self { real, imag }
50 }
51}
52
53#[inline(always)]
55pub fn q15_mult(a: q15, b: q15) -> q15 {
56 let mul = (a as i32 * b as i32) >> 15;
57 mul.clamp(i16::MIN as i32, i16::MAX as i32) as i16
58}
59
60#[inline(always)]
62pub fn q31_mult(a: q31, b: q31) -> q31 {
63 let mul = (a as i64 * b as i64) >> 31;
64 mul.clamp(i32::MIN as i64, i32::MAX as i64) as i32
65}
66
67#[inline(always)]
69pub fn q7_mult(a: q7, b: q7) -> q7 {
70 let mul = (a as i32 * b as i32) >> 7;
71 mul.clamp(i8::MIN as i32, i8::MAX as i32) as i8
72}
73
74#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
83#[repr(transparent)]
84pub struct Q15(pub i16);
85
86impl Q15 {
87 pub const ZERO: Self = Self(0);
89 pub const ONE: Self = Self(i16::MAX);
91 pub const MIN: Self = Self(i16::MIN);
93 pub const MAX: Self = Self(i16::MAX);
95 pub const DELTA: Self = Self(1);
97
98 #[inline(always)]
100 pub const fn from_bits(bits: i16) -> Self {
101 Self(bits)
102 }
103
104 #[inline(always)]
106 pub const fn to_bits(self) -> i16 {
107 self.0
108 }
109
110 #[inline(always)]
112 pub fn from_f32(v: f32) -> Self {
113 let scaled = v * 32768.0 + if v >= 0.0 { 0.5 } else { -0.5 };
114 Self(scaled.clamp(-32768.0, 32767.0) as i16)
115 }
116
117 #[inline(always)]
119 pub fn to_f32(self) -> f32 {
120 self.0 as f32 / 32768.0
121 }
122
123 #[inline(always)]
125 pub const fn saturating_add(self, rhs: Self) -> Self {
126 Self(self.0.saturating_add(rhs.0))
127 }
128
129 #[inline(always)]
131 pub const fn saturating_sub(self, rhs: Self) -> Self {
132 Self(self.0.saturating_sub(rhs.0))
133 }
134
135 #[inline(always)]
137 pub fn saturating_mul(self, rhs: Self) -> Self {
138 Self(q15_mult(self.0, rhs.0))
139 }
140
141 #[inline(always)]
143 pub fn saturating_div(self, rhs: Self) -> Self {
144 if rhs.0 == 0 {
145 if self.0 >= 0 { Self::MAX } else { Self::MIN }
146 } else {
147 let num = (self.0 as i32) << 15;
148 let res = num / (rhs.0 as i32);
149 Self(res.clamp(i16::MIN as i32, i16::MAX as i32) as i16)
150 }
151 }
152
153 #[inline(always)]
155 pub const fn abs(self) -> Self {
156 if self.0 == i16::MIN {
157 Self::MAX
158 } else {
159 Self(self.0.abs())
160 }
161 }
162
163 #[inline(always)]
165 pub fn clamp(self, min: Self, max: Self) -> Self {
166 Self(self.0.clamp(min.0, max.0))
167 }
168}
169
170impl core::ops::Add for Q15 {
171 type Output = Self;
172 #[inline(always)]
173 fn add(self, rhs: Self) -> Self {
174 self.saturating_add(rhs)
175 }
176}
177
178impl core::ops::Sub for Q15 {
179 type Output = Self;
180 #[inline(always)]
181 fn sub(self, rhs: Self) -> Self {
182 self.saturating_sub(rhs)
183 }
184}
185
186impl core::ops::Mul for Q15 {
187 type Output = Self;
188 #[inline(always)]
189 fn mul(self, rhs: Self) -> Self {
190 self.saturating_mul(rhs)
191 }
192}
193
194impl core::ops::Div for Q15 {
195 type Output = Self;
196 #[inline(always)]
197 fn div(self, rhs: Self) -> Self {
198 self.saturating_div(rhs)
199 }
200}
201
202impl core::ops::Neg for Q15 {
203 type Output = Self;
204 #[inline(always)]
205 fn neg(self) -> Self {
206 if self.0 == i16::MIN {
207 Self::MAX
208 } else {
209 Self(-self.0)
210 }
211 }
212}
213
214impl core::ops::AddAssign for Q15 {
215 #[inline(always)]
216 fn add_assign(&mut self, rhs: Self) {
217 *self = *self + rhs;
218 }
219}
220
221impl core::ops::SubAssign for Q15 {
222 #[inline(always)]
223 fn sub_assign(&mut self, rhs: Self) {
224 *self = *self - rhs;
225 }
226}
227
228impl core::ops::MulAssign for Q15 {
229 #[inline(always)]
230 fn mul_assign(&mut self, rhs: Self) {
231 *self = *self * rhs;
232 }
233}
234
235impl core::ops::DivAssign for Q15 {
236 #[inline(always)]
237 fn div_assign(&mut self, rhs: Self) {
238 *self = *self / rhs;
239 }
240}
241
242impl From<i16> for Q15 {
243 #[inline(always)]
244 fn from(v: i16) -> Self {
245 Self(v)
246 }
247}
248
249impl From<Q15> for i16 {
250 #[inline(always)]
251 fn from(v: Q15) -> Self {
252 v.0
253 }
254}
255
256impl From<f32> for Q15 {
257 #[inline(always)]
258 fn from(v: f32) -> Self {
259 Self::from_f32(v)
260 }
261}
262
263impl From<Q15> for f32 {
264 #[inline(always)]
265 fn from(v: Q15) -> Self {
266 v.to_f32()
267 }
268}
269
270#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
275#[repr(transparent)]
276pub struct Q31(pub i32);
277
278impl Q31 {
279 pub const ZERO: Self = Self(0);
281 pub const ONE: Self = Self(i32::MAX);
283 pub const MIN: Self = Self(i32::MIN);
285 pub const MAX: Self = Self(i32::MAX);
287 pub const DELTA: Self = Self(1);
289
290 #[inline(always)]
292 pub const fn from_bits(bits: i32) -> Self {
293 Self(bits)
294 }
295
296 #[inline(always)]
298 pub const fn to_bits(self) -> i32 {
299 self.0
300 }
301
302 #[inline(always)]
304 pub fn from_f32(v: f32) -> Self {
305 let scaled = v as f64 * 2147483648.0 + if v >= 0.0 { 0.5 } else { -0.5 };
306 Self(scaled.clamp(-2147483648.0, 2147483647.0) as i32)
307 }
308
309 #[inline(always)]
311 pub fn to_f32(self) -> f32 {
312 (self.0 as f64 / 2147483648.0) as f32
313 }
314
315 #[inline(always)]
317 pub fn from_f64(v: f64) -> Self {
318 let scaled = v * 2147483648.0 + if v >= 0.0 { 0.5 } else { -0.5 };
319 Self(scaled.clamp(-2147483648.0, 2147483647.0) as i32)
320 }
321
322 #[inline(always)]
324 pub fn to_f64(self) -> f64 {
325 self.0 as f64 / 2147483648.0
326 }
327
328 #[inline(always)]
330 pub const fn saturating_add(self, rhs: Self) -> Self {
331 Self(self.0.saturating_add(rhs.0))
332 }
333
334 #[inline(always)]
336 pub const fn saturating_sub(self, rhs: Self) -> Self {
337 Self(self.0.saturating_sub(rhs.0))
338 }
339
340 #[inline(always)]
342 pub fn saturating_mul(self, rhs: Self) -> Self {
343 Self(q31_mult(self.0, rhs.0))
344 }
345
346 #[inline(always)]
348 pub fn saturating_div(self, rhs: Self) -> Self {
349 if rhs.0 == 0 {
350 if self.0 >= 0 { Self::MAX } else { Self::MIN }
351 } else {
352 let num = (self.0 as i64) << 31;
353 let res = num / (rhs.0 as i64);
354 Self(res.clamp(i32::MIN as i64, i32::MAX as i64) as i32)
355 }
356 }
357
358 #[inline(always)]
360 pub const fn abs(self) -> Self {
361 if self.0 == i32::MIN {
362 Self::MAX
363 } else {
364 Self(self.0.abs())
365 }
366 }
367
368 #[inline(always)]
370 pub fn clamp(self, min: Self, max: Self) -> Self {
371 Self(self.0.clamp(min.0, max.0))
372 }
373}
374
375impl core::ops::Add for Q31 {
376 type Output = Self;
377 #[inline(always)]
378 fn add(self, rhs: Self) -> Self {
379 self.saturating_add(rhs)
380 }
381}
382
383impl core::ops::Sub for Q31 {
384 type Output = Self;
385 #[inline(always)]
386 fn sub(self, rhs: Self) -> Self {
387 self.saturating_sub(rhs)
388 }
389}
390
391impl core::ops::Mul for Q31 {
392 type Output = Self;
393 #[inline(always)]
394 fn mul(self, rhs: Self) -> Self {
395 self.saturating_mul(rhs)
396 }
397}
398
399impl core::ops::Div for Q31 {
400 type Output = Self;
401 #[inline(always)]
402 fn div(self, rhs: Self) -> Self {
403 self.saturating_div(rhs)
404 }
405}
406
407impl core::ops::Neg for Q31 {
408 type Output = Self;
409 #[inline(always)]
410 fn neg(self) -> Self {
411 if self.0 == i32::MIN {
412 Self::MAX
413 } else {
414 Self(-self.0)
415 }
416 }
417}
418
419impl core::ops::AddAssign for Q31 {
420 #[inline(always)]
421 fn add_assign(&mut self, rhs: Self) {
422 *self = *self + rhs;
423 }
424}
425
426impl core::ops::SubAssign for Q31 {
427 #[inline(always)]
428 fn sub_assign(&mut self, rhs: Self) {
429 *self = *self - rhs;
430 }
431}
432
433impl core::ops::MulAssign for Q31 {
434 #[inline(always)]
435 fn mul_assign(&mut self, rhs: Self) {
436 *self = *self * rhs;
437 }
438}
439
440impl core::ops::DivAssign for Q31 {
441 #[inline(always)]
442 fn div_assign(&mut self, rhs: Self) {
443 *self = *self / rhs;
444 }
445}
446
447impl From<i32> for Q31 {
448 #[inline(always)]
449 fn from(v: i32) -> Self {
450 Self(v)
451 }
452}
453
454impl From<Q31> for i32 {
455 #[inline(always)]
456 fn from(v: Q31) -> Self {
457 v.0
458 }
459}
460
461impl From<f32> for Q31 {
462 #[inline(always)]
463 fn from(v: f32) -> Self {
464 Self::from_f32(v)
465 }
466}
467
468impl From<Q31> for f32 {
469 #[inline(always)]
470 fn from(v: Q31) -> Self {
471 v.to_f32()
472 }
473}
474
475pub trait DspSample:
484 Copy
485 + Default
486 + PartialEq
487 + PartialOrd
488 + core::ops::Add<Output = Self>
489 + core::ops::Sub<Output = Self>
490 + core::ops::Mul<Output = Self>
491 + core::ops::Neg<Output = Self>
492{
493 const ZERO: Self;
495 const ONE: Self;
497
498 fn sat_add(self, rhs: Self) -> Self;
500 fn sat_sub(self, rhs: Self) -> Self;
502 fn sat_mul(self, rhs: Self) -> Self;
504 fn sat_div(self, rhs: Self) -> Self;
506 fn abs_val(self) -> Self;
508 fn to_f32(self) -> f32;
510 fn from_f32(val: f32) -> Self;
512}
513
514impl DspSample for f32 {
515 const ZERO: Self = 0.0;
516 const ONE: Self = 1.0;
517
518 #[inline(always)]
519 fn sat_add(self, rhs: Self) -> Self {
520 self + rhs
521 }
522
523 #[inline(always)]
524 fn sat_sub(self, rhs: Self) -> Self {
525 self - rhs
526 }
527
528 #[inline(always)]
529 fn sat_mul(self, rhs: Self) -> Self {
530 self * rhs
531 }
532
533 #[inline(always)]
534 fn sat_div(self, rhs: Self) -> Self {
535 self / rhs
536 }
537
538 #[inline(always)]
539 fn abs_val(self) -> Self {
540 if self < 0.0 { -self } else { self }
541 }
542
543 #[inline(always)]
544 fn to_f32(self) -> f32 {
545 self
546 }
547
548 #[inline(always)]
549 fn from_f32(val: f32) -> Self {
550 val
551 }
552}
553
554impl DspSample for f64 {
555 const ZERO: Self = 0.0;
556 const ONE: Self = 1.0;
557
558 #[inline(always)]
559 fn sat_add(self, rhs: Self) -> Self {
560 self + rhs
561 }
562
563 #[inline(always)]
564 fn sat_sub(self, rhs: Self) -> Self {
565 self - rhs
566 }
567
568 #[inline(always)]
569 fn sat_mul(self, rhs: Self) -> Self {
570 self * rhs
571 }
572
573 #[inline(always)]
574 fn sat_div(self, rhs: Self) -> Self {
575 self / rhs
576 }
577
578 #[inline(always)]
579 fn abs_val(self) -> Self {
580 if self < 0.0 { -self } else { self }
581 }
582
583 #[inline(always)]
584 fn to_f32(self) -> f32 {
585 self as f32
586 }
587
588 #[inline(always)]
589 fn from_f32(val: f32) -> Self {
590 val as f64
591 }
592}
593
594impl DspSample for Q15 {
595 const ZERO: Self = Self::ZERO;
596 const ONE: Self = Self::ONE;
597
598 #[inline(always)]
599 fn sat_add(self, rhs: Self) -> Self {
600 self.saturating_add(rhs)
601 }
602
603 #[inline(always)]
604 fn sat_sub(self, rhs: Self) -> Self {
605 self.saturating_sub(rhs)
606 }
607
608 #[inline(always)]
609 fn sat_mul(self, rhs: Self) -> Self {
610 self.saturating_mul(rhs)
611 }
612
613 #[inline(always)]
614 fn sat_div(self, rhs: Self) -> Self {
615 self.saturating_div(rhs)
616 }
617
618 #[inline(always)]
619 fn abs_val(self) -> Self {
620 self.abs()
621 }
622
623 #[inline(always)]
624 fn to_f32(self) -> f32 {
625 self.to_f32()
626 }
627
628 #[inline(always)]
629 fn from_f32(val: f32) -> Self {
630 Self::from_f32(val)
631 }
632}
633
634impl DspSample for Q31 {
635 const ZERO: Self = Self::ZERO;
636 const ONE: Self = Self::ONE;
637
638 #[inline(always)]
639 fn sat_add(self, rhs: Self) -> Self {
640 self.saturating_add(rhs)
641 }
642
643 #[inline(always)]
644 fn sat_sub(self, rhs: Self) -> Self {
645 self.saturating_sub(rhs)
646 }
647
648 #[inline(always)]
649 fn sat_mul(self, rhs: Self) -> Self {
650 self.saturating_mul(rhs)
651 }
652
653 #[inline(always)]
654 fn sat_div(self, rhs: Self) -> Self {
655 self.saturating_div(rhs)
656 }
657
658 #[inline(always)]
659 fn abs_val(self) -> Self {
660 self.abs()
661 }
662
663 #[inline(always)]
664 fn to_f32(self) -> f32 {
665 self.to_f32()
666 }
667
668 #[inline(always)]
669 fn from_f32(val: f32) -> Self {
670 Self::from_f32(val)
671 }
672}
673
674impl<T: core::ops::Add<Output = T>> core::ops::Add for Complex<T> {
679 type Output = Self;
680 #[inline(always)]
681 fn add(self, rhs: Self) -> Self {
682 Self {
683 real: self.real + rhs.real,
684 imag: self.imag + rhs.imag,
685 }
686 }
687}
688
689impl<T: core::ops::Sub<Output = T>> core::ops::Sub for Complex<T> {
690 type Output = Self;
691 #[inline(always)]
692 fn sub(self, rhs: Self) -> Self {
693 Self {
694 real: self.real - rhs.real,
695 imag: self.imag - rhs.imag,
696 }
697 }
698}
699
700impl<T: core::ops::Neg<Output = T>> core::ops::Neg for Complex<T> {
701 type Output = Self;
702 #[inline(always)]
703 fn neg(self) -> Self {
704 Self {
705 real: -self.real,
706 imag: -self.imag,
707 }
708 }
709}
710
711impl<T: Copy + core::ops::Add<Output = T> + core::ops::Sub<Output = T> + core::ops::Mul<Output = T>>
712 core::ops::Mul for Complex<T>
713{
714 type Output = Self;
715 #[inline(always)]
716 fn mul(self, rhs: Self) -> Self {
717 Self {
718 real: self.real * rhs.real - self.imag * rhs.imag,
719 imag: self.real * rhs.imag + self.imag * rhs.real,
720 }
721 }
722}
723
724impl<T: Copy + core::ops::Mul<Output = T>> core::ops::Mul<T> for Complex<T> {
725 type Output = Self;
726 #[inline(always)]
727 fn mul(self, scalar: T) -> Self {
728 Self {
729 real: self.real * scalar,
730 imag: self.imag * scalar,
731 }
732 }
733}