1use crate::types::*;
4
5pub struct FirInstanceF32<'a> {
9 pub num_taps: u16,
10 pub coeffs: &'a [f32],
11 pub state: &'a mut [f32],
12}
13
14impl<'a> FirInstanceF32<'a> {
15 pub fn init(num_taps: u16, coeffs: &'a [f32], state: &'a mut [f32]) -> Self {
16 state.fill(0.0);
17 Self {
18 num_taps,
19 coeffs,
20 state,
21 }
22 }
23}
24
25pub fn fir_f32(instance: &mut FirInstanceF32, src: &[f32], dst: &mut [f32]) {
26 let num_taps = instance.num_taps as usize;
27 let block_size = src.len().min(dst.len());
28
29 for i in 0..block_size {
30 for k in (1..num_taps).rev() {
32 instance.state[k] = instance.state[k - 1];
33 }
34 instance.state[0] = src[i];
35
36 let mut acc = 0.0f32;
38 for k in 0..num_taps {
39 acc += instance.state[k] * instance.coeffs[k];
40 }
41 dst[i] = acc;
42 }
43}
44
45pub struct FirInstanceQ31<'a> {
47 pub num_taps: u16,
48 pub coeffs: &'a [q31],
49 pub state: &'a mut [q31],
50}
51
52impl<'a> FirInstanceQ31<'a> {
53 pub fn init(num_taps: u16, coeffs: &'a [q31], state: &'a mut [q31]) -> Self {
54 state.fill(0);
55 Self {
56 num_taps,
57 coeffs,
58 state,
59 }
60 }
61}
62
63pub fn fir_q31(instance: &mut FirInstanceQ31, src: &[q31], dst: &mut [q31]) {
64 let num_taps = instance.num_taps as usize;
65 let block_size = src.len().min(dst.len());
66
67 for i in 0..block_size {
68 for k in (1..num_taps).rev() {
69 instance.state[k] = instance.state[k - 1];
70 }
71 instance.state[0] = src[i];
72
73 let mut acc: i64 = 0;
74 for k in 0..num_taps {
75 acc += (instance.state[k] as i64 * instance.coeffs[k] as i64) >> 31;
76 }
77 dst[i] = acc.clamp(i32::MIN as i64, i32::MAX as i64) as q31;
78 }
79}
80
81pub struct FirInstanceQ15<'a> {
83 pub num_taps: u16,
84 pub coeffs: &'a [q15],
85 pub state: &'a mut [q15],
86}
87
88impl<'a> FirInstanceQ15<'a> {
89 pub fn init(num_taps: u16, coeffs: &'a [q15], state: &'a mut [q15]) -> Self {
90 state.fill(0);
91 Self {
92 num_taps,
93 coeffs,
94 state,
95 }
96 }
97}
98
99pub fn fir_q15(instance: &mut FirInstanceQ15, src: &[q15], dst: &mut [q15]) {
100 let num_taps = instance.num_taps as usize;
101 let block_size = src.len().min(dst.len());
102
103 for i in 0..block_size {
104 for k in (1..num_taps).rev() {
105 instance.state[k] = instance.state[k - 1];
106 }
107 instance.state[0] = src[i];
108
109 let mut acc: i32 = 0;
110 for k in 0..num_taps {
111 acc += (instance.state[k] as i32 * instance.coeffs[k] as i32) >> 15;
112 }
113 dst[i] = acc.clamp(i16::MIN as i32, i16::MAX as i32) as q15;
114 }
115}
116
117pub struct BiquadCascadeInstanceF32<'a> {
121 pub num_stages: u8,
122 pub coeffs: &'a [f32], pub state: &'a mut [f32], }
125
126impl<'a> BiquadCascadeInstanceF32<'a> {
127 pub fn init(num_stages: u8, coeffs: &'a [f32], state: &'a mut [f32]) -> Self {
128 state.fill(0.0);
129 Self {
130 num_stages,
131 coeffs,
132 state,
133 }
134 }
135}
136
137pub fn biquad_cascade_df1_f32(
138 instance: &mut BiquadCascadeInstanceF32,
139 src: &[f32],
140 dst: &mut [f32],
141) {
142 let num_stages = instance.num_stages as usize;
143 let block_size = src.len().min(dst.len());
144
145 let mut in_val;
146 let mut out_val;
147
148 for i in 0..block_size {
149 in_val = src[i];
150 for stage in 0..num_stages {
151 let b0 = instance.coeffs[stage * 5];
152 let b1 = instance.coeffs[stage * 5 + 1];
153 let b2 = instance.coeffs[stage * 5 + 2];
154 let a1 = instance.coeffs[stage * 5 + 3];
155 let a2 = instance.coeffs[stage * 5 + 4];
156
157 let x1 = instance.state[stage * 4];
158 let x2 = instance.state[stage * 4 + 1];
159 let y1 = instance.state[stage * 4 + 2];
160 let y2 = instance.state[stage * 4 + 3];
161
162 out_val = b0 * in_val + b1 * x1 + b2 * x2 + a1 * y1 + a2 * y2;
163
164 instance.state[stage * 4 + 1] = x1;
165 instance.state[stage * 4] = in_val;
166 instance.state[stage * 4 + 3] = y1;
167 instance.state[stage * 4 + 2] = out_val;
168
169 in_val = out_val;
170 }
171 dst[i] = in_val;
172 }
173}
174
175pub struct BiquadCascadeDf2tInstanceF32<'a> {
180 pub num_stages: u8,
181 pub coeffs: &'a [f32],
182 pub state: &'a mut [f32],
183}
184
185impl<'a> BiquadCascadeDf2tInstanceF32<'a> {
186 pub fn init(num_stages: u8, coeffs: &'a [f32], state: &'a mut [f32]) -> Self {
187 state.fill(0.0);
188 Self {
189 num_stages,
190 coeffs,
191 state,
192 }
193 }
194}
195
196pub fn biquad_cascade_df2t_f32(
197 instance: &mut BiquadCascadeDf2tInstanceF32,
198 src: &[f32],
199 dst: &mut [f32],
200) {
201 let num_stages = instance.num_stages as usize;
202 let block_size = src.len().min(dst.len());
203
204 for i in 0..block_size {
205 let mut in_val = src[i];
206 for stage in 0..num_stages {
207 let b0 = instance.coeffs[stage * 5];
208 let b1 = instance.coeffs[stage * 5 + 1];
209 let b2 = instance.coeffs[stage * 5 + 2];
210 let a1 = instance.coeffs[stage * 5 + 3];
211 let a2 = instance.coeffs[stage * 5 + 4];
212
213 let s1 = instance.state[stage * 2];
214 let s2 = instance.state[stage * 2 + 1];
215
216 let y = b0 * in_val + s1;
217 instance.state[stage * 2] = b1 * in_val + a1 * y + s2;
218 instance.state[stage * 2 + 1] = b2 * in_val + a2 * y;
219 in_val = y;
220 }
221 dst[i] = in_val;
222 }
223}
224
225pub struct BiquadCascadeInstanceQ15<'a> {
231 pub num_stages: u8,
232 pub post_shift: u8,
233 pub coeffs: &'a [q15],
234 pub state: &'a mut [q15],
235}
236
237impl<'a> BiquadCascadeInstanceQ15<'a> {
238 pub fn init(num_stages: u8, coeffs: &'a [q15], state: &'a mut [q15], post_shift: u8) -> Self {
239 state.fill(0);
240 Self {
241 num_stages,
242 post_shift,
243 coeffs,
244 state,
245 }
246 }
247}
248
249pub fn biquad_cascade_df1_q15(
250 instance: &mut BiquadCascadeInstanceQ15,
251 src: &[q15],
252 dst: &mut [q15],
253) {
254 let num_stages = instance.num_stages as usize;
255 let block_size = src.len().min(dst.len());
256 let shift = 15u32.saturating_sub(instance.post_shift as u32).min(31);
257
258 for i in 0..block_size {
259 let mut in_val = src[i] as i64;
260 for stage in 0..num_stages {
261 let b0 = instance.coeffs[stage * 5] as i64;
262 let b1 = instance.coeffs[stage * 5 + 1] as i64;
263 let b2 = instance.coeffs[stage * 5 + 2] as i64;
264 let a1 = instance.coeffs[stage * 5 + 3] as i64;
265 let a2 = instance.coeffs[stage * 5 + 4] as i64;
266
267 let x1 = instance.state[stage * 4] as i64;
268 let x2 = instance.state[stage * 4 + 1] as i64;
269 let y1 = instance.state[stage * 4 + 2] as i64;
270 let y2 = instance.state[stage * 4 + 3] as i64;
271
272 let acc = b0 * in_val + b1 * x1 + b2 * x2 + a1 * y1 + a2 * y2;
273 let out_val = (acc >> shift).clamp(i16::MIN as i64, i16::MAX as i64);
274
275 instance.state[stage * 4 + 1] = x1 as q15;
276 instance.state[stage * 4] = in_val as q15;
277 instance.state[stage * 4 + 3] = y1 as q15;
278 instance.state[stage * 4 + 2] = out_val as q15;
279
280 in_val = out_val;
281 }
282 dst[i] = in_val as q15;
283 }
284}
285
286pub struct BiquadCascadeInstanceQ31<'a> {
288 pub num_stages: u8,
289 pub post_shift: u8,
290 pub coeffs: &'a [q31],
291 pub state: &'a mut [q31],
292}
293
294impl<'a> BiquadCascadeInstanceQ31<'a> {
295 pub fn init(num_stages: u8, coeffs: &'a [q31], state: &'a mut [q31], post_shift: u8) -> Self {
296 state.fill(0);
297 Self {
298 num_stages,
299 post_shift,
300 coeffs,
301 state,
302 }
303 }
304}
305
306pub fn biquad_cascade_df1_q31(
307 instance: &mut BiquadCascadeInstanceQ31,
308 src: &[q31],
309 dst: &mut [q31],
310) {
311 let num_stages = instance.num_stages as usize;
312 let block_size = src.len().min(dst.len());
313 let shift = 31u32.saturating_sub(instance.post_shift as u32).min(63);
314
315 for i in 0..block_size {
316 let mut in_val = src[i] as i64;
317 for stage in 0..num_stages {
318 let b0 = instance.coeffs[stage * 5] as i64;
319 let b1 = instance.coeffs[stage * 5 + 1] as i64;
320 let b2 = instance.coeffs[stage * 5 + 2] as i64;
321 let a1 = instance.coeffs[stage * 5 + 3] as i64;
322 let a2 = instance.coeffs[stage * 5 + 4] as i64;
323
324 let x1 = instance.state[stage * 4] as i64;
325 let x2 = instance.state[stage * 4 + 1] as i64;
326 let y1 = instance.state[stage * 4 + 2] as i64;
327 let y2 = instance.state[stage * 4 + 3] as i64;
328
329 let acc = b0 * in_val + b1 * x1 + b2 * x2 + a1 * y1 + a2 * y2;
330 let out_val = (acc >> shift).clamp(i32::MIN as i64, i32::MAX as i64);
331
332 instance.state[stage * 4 + 1] = x1 as q31;
333 instance.state[stage * 4] = in_val as q31;
334 instance.state[stage * 4 + 3] = y1 as q31;
335 instance.state[stage * 4 + 2] = out_val as q31;
336
337 in_val = out_val;
338 }
339 dst[i] = in_val as q31;
340 }
341}
342
343pub struct BiquadCascadeDf2tInstanceQ15<'a> {
349 pub num_stages: u8,
350 pub post_shift: u8,
351 pub coeffs: &'a [q15],
352 pub state: &'a mut [q15],
353}
354
355impl<'a> BiquadCascadeDf2tInstanceQ15<'a> {
356 pub fn init(num_stages: u8, coeffs: &'a [q15], state: &'a mut [q15], post_shift: u8) -> Self {
357 state.fill(0);
358 Self {
359 num_stages,
360 post_shift,
361 coeffs,
362 state,
363 }
364 }
365}
366
367pub fn biquad_cascade_df2t_q15(
368 instance: &mut BiquadCascadeDf2tInstanceQ15,
369 src: &[q15],
370 dst: &mut [q15],
371) {
372 let num_stages = instance.num_stages as usize;
373 let block_size = src.len().min(dst.len());
374 let shift = 15u32.saturating_sub(instance.post_shift as u32).min(31);
375
376 for i in 0..block_size {
377 let mut in_val = src[i] as i64;
378 for stage in 0..num_stages {
379 let b0 = instance.coeffs[stage * 5] as i64;
380 let b1 = instance.coeffs[stage * 5 + 1] as i64;
381 let b2 = instance.coeffs[stage * 5 + 2] as i64;
382 let a1 = instance.coeffs[stage * 5 + 3] as i64;
383 let a2 = instance.coeffs[stage * 5 + 4] as i64;
384
385 let s1 = instance.state[stage * 2] as i64;
386 let s2 = instance.state[stage * 2 + 1] as i64;
387
388 let y = (b0 * in_val + (s1 << shift)).clamp(i64::MIN >> 1, i64::MAX >> 1) >> shift;
389 let out_val = y.clamp(i16::MIN as i64, i16::MAX as i64);
390 let s1_new = (b1 * in_val + a1 * out_val + (s2 << shift)) >> shift;
391 let s2_new = (b2 * in_val + a2 * out_val) >> shift;
392
393 instance.state[stage * 2] =
394 s1_new.clamp(i16::MIN as i64, i16::MAX as i64) as q15;
395 instance.state[stage * 2 + 1] =
396 s2_new.clamp(i16::MIN as i64, i16::MAX as i64) as q15;
397 in_val = out_val;
398 }
399 dst[i] = in_val as q15;
400 }
401}
402
403pub struct BiquadCascadeDf2tInstanceQ31<'a> {
405 pub num_stages: u8,
406 pub post_shift: u8,
407 pub coeffs: &'a [q31],
408 pub state: &'a mut [q31],
409}
410
411impl<'a> BiquadCascadeDf2tInstanceQ31<'a> {
412 pub fn init(num_stages: u8, coeffs: &'a [q31], state: &'a mut [q31], post_shift: u8) -> Self {
413 state.fill(0);
414 Self {
415 num_stages,
416 post_shift,
417 coeffs,
418 state,
419 }
420 }
421}
422
423pub fn biquad_cascade_df2t_q31(
424 instance: &mut BiquadCascadeDf2tInstanceQ31,
425 src: &[q31],
426 dst: &mut [q31],
427) {
428 let num_stages = instance.num_stages as usize;
429 let block_size = src.len().min(dst.len());
430 let shift = 31u32.saturating_sub(instance.post_shift as u32).min(63);
431
432 for i in 0..block_size {
433 let mut in_val = src[i] as i64;
434 for stage in 0..num_stages {
435 let b0 = instance.coeffs[stage * 5] as i64;
436 let b1 = instance.coeffs[stage * 5 + 1] as i64;
437 let b2 = instance.coeffs[stage * 5 + 2] as i64;
438 let a1 = instance.coeffs[stage * 5 + 3] as i64;
439 let a2 = instance.coeffs[stage * 5 + 4] as i64;
440
441 let s1 = instance.state[stage * 2] as i64;
442 let s2 = instance.state[stage * 2 + 1] as i64;
443
444 let y = (b0 * in_val + (s1 << shift)).clamp(i64::MIN >> 1, i64::MAX >> 1) >> shift;
445 let out_val = y.clamp(i32::MIN as i64, i32::MAX as i64);
446 let s1_new = (b1 * in_val + a1 * out_val + (s2 << shift)) >> shift;
447 let s2_new = (b2 * in_val + a2 * out_val) >> shift;
448
449 instance.state[stage * 2] =
450 s1_new.clamp(i32::MIN as i64, i32::MAX as i64) as q31;
451 instance.state[stage * 2 + 1] =
452 s2_new.clamp(i32::MIN as i64, i32::MAX as i64) as q31;
453 in_val = out_val;
454 }
455 dst[i] = in_val as q31;
456 }
457}
458
459pub struct LmsInstanceF32<'a> {
463 pub num_taps: u16,
464 pub coeffs: &'a mut [f32],
465 pub state: &'a mut [f32],
466 pub mu: f32,
467}
468
469impl<'a> LmsInstanceF32<'a> {
470 pub fn init(num_taps: u16, coeffs: &'a mut [f32], state: &'a mut [f32], mu: f32) -> Self {
471 state.fill(0.0);
472 coeffs.fill(0.0);
473 Self {
474 num_taps,
475 coeffs,
476 state,
477 mu,
478 }
479 }
480}
481
482pub fn lms_f32(
483 instance: &mut LmsInstanceF32,
484 src: &[f32],
485 ref_signal: &[f32],
486 out: &mut [f32],
487 err: &mut [f32],
488) {
489 let num_taps = instance.num_taps as usize;
490 let block_size = src
491 .len()
492 .min(ref_signal.len())
493 .min(out.len())
494 .min(err.len());
495
496 for i in 0..block_size {
497 for k in (1..num_taps).rev() {
498 instance.state[k] = instance.state[k - 1];
499 }
500 instance.state[0] = src[i];
501
502 let mut acc = 0.0f32;
503 for k in 0..num_taps {
504 acc += instance.state[k] * instance.coeffs[k];
505 }
506 out[i] = acc;
507 let e = ref_signal[i] - acc;
508 err[i] = e;
509
510 let alpha = 2.0 * instance.mu * e;
512 for k in 0..num_taps {
513 instance.coeffs[k] += alpha * instance.state[k];
514 }
515 }
516}
517
518pub fn lms_leaky_f32(
520 instance: &mut LmsInstanceF32,
521 src: &[f32],
522 ref_signal: &[f32],
523 out: &mut [f32],
524 err: &mut [f32],
525 leak: f32,
526) {
527 let num_taps = instance.num_taps as usize;
528 let block_size = src
529 .len()
530 .min(ref_signal.len())
531 .min(out.len())
532 .min(err.len());
533 let keep = 1.0 - leak;
534
535 for i in 0..block_size {
536 for k in (1..num_taps).rev() {
537 instance.state[k] = instance.state[k - 1];
538 }
539 instance.state[0] = src[i];
540
541 let mut acc = 0.0f32;
542 for k in 0..num_taps {
543 acc += instance.state[k] * instance.coeffs[k];
544 }
545 out[i] = acc;
546 let e = ref_signal[i] - acc;
547 err[i] = e;
548
549 let alpha = 2.0 * instance.mu * e;
550 for k in 0..num_taps {
551 instance.coeffs[k] = keep * instance.coeffs[k] + alpha * instance.state[k];
552 }
553 }
554}
555
556pub struct NlmsInstanceF32<'a> {
558 pub num_taps: u16,
559 pub coeffs: &'a mut [f32],
560 pub state: &'a mut [f32],
561 pub mu: f32,
562 pub eps: f32,
563}
564
565impl<'a> NlmsInstanceF32<'a> {
566 pub fn init(
567 num_taps: u16,
568 coeffs: &'a mut [f32],
569 state: &'a mut [f32],
570 mu: f32,
571 eps: f32,
572 ) -> Self {
573 state.fill(0.0);
574 coeffs.fill(0.0);
575 Self {
576 num_taps,
577 coeffs,
578 state,
579 mu,
580 eps,
581 }
582 }
583}
584
585pub fn nlms_f32(
587 instance: &mut NlmsInstanceF32,
588 src: &[f32],
589 ref_signal: &[f32],
590 out: &mut [f32],
591 err: &mut [f32],
592) {
593 let num_taps = instance.num_taps as usize;
594 let block_size = src
595 .len()
596 .min(ref_signal.len())
597 .min(out.len())
598 .min(err.len());
599
600 for i in 0..block_size {
601 for k in (1..num_taps).rev() {
602 instance.state[k] = instance.state[k - 1];
603 }
604 instance.state[0] = src[i];
605
606 let mut acc = 0.0f32;
607 let mut power = instance.eps;
608 for k in 0..num_taps {
609 acc += instance.state[k] * instance.coeffs[k];
610 power += instance.state[k] * instance.state[k];
611 }
612 out[i] = acc;
613 let e = ref_signal[i] - acc;
614 err[i] = e;
615
616 let alpha = instance.mu * e / power;
617 for k in 0..num_taps {
618 instance.coeffs[k] += alpha * instance.state[k];
619 }
620 }
621}
622
623pub struct LmsInstanceQ15<'a> {
625 pub num_taps: u16,
626 pub coeffs: &'a mut [q15],
627 pub state: &'a mut [q15],
628 pub mu: q15,
629}
630
631impl<'a> LmsInstanceQ15<'a> {
632 pub fn init(num_taps: u16, coeffs: &'a mut [q15], state: &'a mut [q15], mu: q15) -> Self {
633 state.fill(0);
634 coeffs.fill(0);
635 Self {
636 num_taps,
637 coeffs,
638 state,
639 mu,
640 }
641 }
642}
643
644fn lms_q15_inner(
645 instance: &mut LmsInstanceQ15,
646 src: &[q15],
647 ref_signal: &[q15],
648 out: &mut [q15],
649 err: &mut [q15],
650 leak: q15,
651) {
652 let num_taps = instance.num_taps as usize;
653 let block_size = src
654 .len()
655 .min(ref_signal.len())
656 .min(out.len())
657 .min(err.len());
658 let keep = 32767i32 - leak.max(0) as i32;
659
660 for i in 0..block_size {
661 for k in (1..num_taps).rev() {
662 instance.state[k] = instance.state[k - 1];
663 }
664 instance.state[0] = src[i];
665
666 let mut acc: i64 = 0;
667 for k in 0..num_taps {
668 acc += instance.state[k] as i64 * instance.coeffs[k] as i64;
669 }
670 let y = (acc >> 15).clamp(i16::MIN as i64, i16::MAX as i64);
671 out[i] = y as q15;
672 let e = (ref_signal[i] as i32 - y as i32).clamp(i16::MIN as i32, i16::MAX as i32);
673 err[i] = e as q15;
674
675 let alpha = (2i64 * instance.mu as i64 * e as i64) >> 15;
676 for k in 0..num_taps {
677 let leaked = (keep as i64 * instance.coeffs[k] as i64) >> 15;
678 let upd = leaked + ((alpha * instance.state[k] as i64) >> 15);
679 instance.coeffs[k] = upd.clamp(i16::MIN as i64, i16::MAX as i64) as q15;
680 }
681 }
682}
683
684pub fn lms_q15(
685 instance: &mut LmsInstanceQ15,
686 src: &[q15],
687 ref_signal: &[q15],
688 out: &mut [q15],
689 err: &mut [q15],
690) {
691 lms_q15_inner(instance, src, ref_signal, out, err, 0);
692}
693
694pub fn lms_leaky_q15(
696 instance: &mut LmsInstanceQ15,
697 src: &[q15],
698 ref_signal: &[q15],
699 out: &mut [q15],
700 err: &mut [q15],
701 leak: q15,
702) {
703 lms_q15_inner(instance, src, ref_signal, out, err, leak);
704}
705
706pub struct NlmsInstanceQ15<'a> {
708 pub num_taps: u16,
709 pub coeffs: &'a mut [q15],
710 pub state: &'a mut [q15],
711 pub mu: q15,
712 pub eps: q15,
713}
714
715impl<'a> NlmsInstanceQ15<'a> {
716 pub fn init(
717 num_taps: u16,
718 coeffs: &'a mut [q15],
719 state: &'a mut [q15],
720 mu: q15,
721 eps: q15,
722 ) -> Self {
723 state.fill(0);
724 coeffs.fill(0);
725 Self {
726 num_taps,
727 coeffs,
728 state,
729 mu,
730 eps,
731 }
732 }
733}
734
735pub fn nlms_q15(
736 instance: &mut NlmsInstanceQ15,
737 src: &[q15],
738 ref_signal: &[q15],
739 out: &mut [q15],
740 err: &mut [q15],
741) {
742 let num_taps = instance.num_taps as usize;
743 let block_size = src
744 .len()
745 .min(ref_signal.len())
746 .min(out.len())
747 .min(err.len());
748
749 for i in 0..block_size {
750 for k in (1..num_taps).rev() {
751 instance.state[k] = instance.state[k - 1];
752 }
753 instance.state[0] = src[i];
754
755 let mut acc: i64 = 0;
756 let mut power: i64 = instance.eps.max(1) as i64;
757 for k in 0..num_taps {
758 let x = instance.state[k] as i64;
759 acc += x * instance.coeffs[k] as i64;
760 power += (x * x) >> 15;
761 }
762 let y = (acc >> 15).clamp(i16::MIN as i64, i16::MAX as i64);
763 out[i] = y as q15;
764 let e = (ref_signal[i] as i32 - y as i32).clamp(i16::MIN as i32, i16::MAX as i32);
765 err[i] = e as q15;
766
767 let alpha = (instance.mu as i64 * e as i64) / power;
768 for k in 0..num_taps {
769 let upd =
770 instance.coeffs[k] as i64 + ((alpha * instance.state[k] as i64) >> 15);
771 instance.coeffs[k] = upd.clamp(i16::MIN as i64, i16::MAX as i64) as q15;
772 }
773 }
774}
775
776pub fn conv_f32(src_a: &[f32], src_b: &[f32], dst: &mut [f32]) {
779 let len_a = src_a.len();
780 let len_b = src_b.len();
781 let out_len = (len_a + len_b - 1).min(dst.len());
782
783 dst[..out_len].fill(0.0);
784 for i in 0..len_a {
785 for j in 0..len_b {
786 if i + j < out_len {
787 dst[i + j] += src_a[i] * src_b[j];
788 }
789 }
790 }
791}
792
793pub fn conv_q31(src_a: &[q31], src_b: &[q31], dst: &mut [q31]) {
794 let len_a = src_a.len();
795 let len_b = src_b.len();
796 let out_len = (len_a + len_b - 1).min(dst.len());
797
798 for n in 0..out_len {
799 let mut acc: i64 = 0;
800 let k_min = if n >= len_b - 1 { n - (len_b - 1) } else { 0 };
801 let k_max = n.min(len_a - 1);
802 for k in k_min..=k_max {
803 acc += (src_a[k] as i64 * src_b[n - k] as i64) >> 31;
804 }
805 dst[n] = acc.clamp(i32::MIN as i64, i32::MAX as i64) as q31;
806 }
807}
808
809pub fn conv_q15(src_a: &[q15], src_b: &[q15], dst: &mut [q15]) {
810 let len_a = src_a.len();
811 let len_b = src_b.len();
812 let out_len = (len_a + len_b - 1).min(dst.len());
813
814 for n in 0..out_len {
815 let mut acc: i32 = 0;
816 let k_min = if n >= len_b - 1 { n - (len_b - 1) } else { 0 };
817 let k_max = n.min(len_a - 1);
818 for k in k_min..=k_max {
819 acc += (src_a[k] as i32 * src_b[n - k] as i32) >> 15;
820 }
821 dst[n] = acc.clamp(i16::MIN as i32, i16::MAX as i32) as q15;
822 }
823}
824
825pub fn conv_q7(src_a: &[q7], src_b: &[q7], dst: &mut [q7]) {
826 let len_a = src_a.len();
827 let len_b = src_b.len();
828 let out_len = (len_a + len_b - 1).min(dst.len());
829
830 for n in 0..out_len {
831 let mut acc: i32 = 0;
832 let k_min = if n >= len_b - 1 { n - (len_b - 1) } else { 0 };
833 let k_max = n.min(len_a - 1);
834 for k in k_min..=k_max {
835 acc += (src_a[k] as i32 * src_b[n - k] as i32) >> 7;
836 }
837 dst[n] = acc.clamp(i8::MIN as i32, i8::MAX as i32) as q7;
838 }
839}
840
841pub fn correlate_f32(src_a: &[f32], src_b: &[f32], dst: &mut [f32]) {
844 let len_a = src_a.len();
845 let len_b = src_b.len();
846 let out_len = (len_a + len_b - 1).min(dst.len());
847
848 dst[..out_len].fill(0.0);
849 for n in 0..out_len {
850 let mut acc = 0.0f32;
851 for k in 0..len_a {
852 let idx_b = (k as isize) + (len_b as isize - 1) - (n as isize);
853 if idx_b >= 0 && (idx_b as usize) < len_b {
854 acc += src_a[k] * src_b[idx_b as usize];
855 }
856 }
857 dst[n] = acc;
858 }
859}
860
861pub fn correlate_q31(src_a: &[q31], src_b: &[q31], dst: &mut [q31]) {
862 let len_a = src_a.len();
863 let len_b = src_b.len();
864 let out_len = (len_a + len_b - 1).min(dst.len());
865
866 for n in 0..out_len {
867 let mut acc: i64 = 0;
868 for k in 0..len_a {
869 let idx_b = (k as isize) + (len_b as isize - 1) - (n as isize);
870 if idx_b >= 0 && (idx_b as usize) < len_b {
871 acc += (src_a[k] as i64 * src_b[idx_b as usize] as i64) >> 31;
872 }
873 }
874 dst[n] = acc.clamp(i32::MIN as i64, i32::MAX as i64) as q31;
875 }
876}
877
878pub fn correlate_q15(src_a: &[q15], src_b: &[q15], dst: &mut [q15]) {
879 let len_a = src_a.len();
880 let len_b = src_b.len();
881 let out_len = (len_a + len_b - 1).min(dst.len());
882
883 for n in 0..out_len {
884 let mut acc: i32 = 0;
885 for k in 0..len_a {
886 let idx_b = (k as isize) + (len_b as isize - 1) - (n as isize);
887 if idx_b >= 0 && (idx_b as usize) < len_b {
888 acc += (src_a[k] as i32 * src_b[idx_b as usize] as i32) >> 15;
889 }
890 }
891 dst[n] = acc.clamp(i16::MIN as i32, i16::MAX as i32) as q15;
892 }
893}
894
895#[allow(unused_imports)]
898use crate::math::FloatMath;
899#[cfg(feature = "transform")]
900use crate::transform::cfft_f32;
901
902pub fn median_filter_1d_f32(
909 src: &[f32],
910 dst: &mut [f32],
911 window_len: usize,
912 threshold: f32,
913) -> Status {
914 let n = src.len();
915 if n == 0 || dst.len() < n {
916 return Status::LengthError;
917 }
918 if window_len == 0 || window_len % 2 == 0 || window_len > 63 {
919 return Status::ArgumentError;
920 }
921
922 let half = window_len / 2;
923 let mut sort_buf = [0.0f32; 64];
924
925 for i in 0..n {
926 for j in 0..window_len {
928 let idx = (i as isize + j as isize - half as isize).clamp(0, (n - 1) as isize) as usize;
929 sort_buf[j] = src[idx];
930 }
931
932 for a in 1..window_len {
934 let mut b = a;
935 while b > 0 && sort_buf[b - 1] > sort_buf[b] {
936 sort_buf.swap(b - 1, b);
937 b -= 1;
938 }
939 }
940
941 let med = sort_buf[half];
942 let center = src[i];
943 if (center - med).abs() >= threshold {
944 dst[i] = med;
945 } else {
946 dst[i] = center;
947 }
948 }
949
950 Status::Success
951}
952
953pub fn median_filter_1d_q15(
955 src: &[q15],
956 dst: &mut [q15],
957 window_len: usize,
958 threshold: q15,
959) -> Status {
960 let n = src.len();
961 if n == 0 || dst.len() < n {
962 return Status::LengthError;
963 }
964 if window_len == 0 || window_len % 2 == 0 || window_len > 63 {
965 return Status::ArgumentError;
966 }
967
968 let half = window_len / 2;
969 let mut sort_buf = [0i16; 64];
970
971 for i in 0..n {
972 for j in 0..window_len {
973 let idx = (i as isize + j as isize - half as isize).clamp(0, (n - 1) as isize) as usize;
974 sort_buf[j] = src[idx];
975 }
976
977 for a in 1..window_len {
978 let mut b = a;
979 while b > 0 && sort_buf[b - 1] > sort_buf[b] {
980 sort_buf.swap(b - 1, b);
981 b -= 1;
982 }
983 }
984
985 let med = sort_buf[half];
986 let center = src[i];
987 let diff = (center as i32 - med as i32).abs();
988 if diff >= threshold as i32 {
989 dst[i] = med;
990 } else {
991 dst[i] = center;
992 }
993 }
994
995 Status::Success
996}
997
998pub fn median_filter_1d_q31(
1000 src: &[q31],
1001 dst: &mut [q31],
1002 window_len: usize,
1003 threshold: q31,
1004) -> Status {
1005 let n = src.len();
1006 if n == 0 || dst.len() < n {
1007 return Status::LengthError;
1008 }
1009 if window_len == 0 || window_len % 2 == 0 || window_len > 63 {
1010 return Status::ArgumentError;
1011 }
1012
1013 let half = window_len / 2;
1014 let mut sort_buf = [0i32; 64];
1015
1016 for i in 0..n {
1017 for j in 0..window_len {
1018 let idx = (i as isize + j as isize - half as isize).clamp(0, (n - 1) as isize) as usize;
1019 sort_buf[j] = src[idx];
1020 }
1021
1022 for a in 1..window_len {
1023 let mut b = a;
1024 while b > 0 && sort_buf[b - 1] > sort_buf[b] {
1025 sort_buf.swap(b - 1, b);
1026 b -= 1;
1027 }
1028 }
1029
1030 let med = sort_buf[half];
1031 let center = src[i];
1032 let diff = (center as i64 - med as i64).abs();
1033 if diff >= threshold as i64 {
1034 dst[i] = med;
1035 } else {
1036 dst[i] = center;
1037 }
1038 }
1039
1040 Status::Success
1041}
1042
1043#[cfg(feature = "transform")]
1050pub fn fast_convolve_f32(signal: &[f32], kernel: &[f32], dst: &mut [f32]) -> Status {
1051 let len_sig = signal.len();
1052 let len_ker = kernel.len();
1053 if len_sig == 0 || len_ker == 0 {
1054 return Status::LengthError;
1055 }
1056 let total_len = len_sig + len_ker - 1;
1057 if dst.len() < total_len {
1058 return Status::LengthError;
1059 }
1060
1061 let mut fft_n = 1;
1063 while fft_n < total_len {
1064 fft_n <<= 1;
1065 }
1066
1067 if fft_n > 512 {
1068 conv_f32(signal, kernel, dst);
1070 return Status::Success;
1071 }
1072
1073 let mut sig_buf = [0.0f32; 1024]; let mut ker_buf = [0.0f32; 1024];
1075
1076 for i in 0..len_sig {
1077 sig_buf[2 * i] = signal[i];
1078 }
1079 for i in 0..len_ker {
1080 ker_buf[2 * i] = kernel[i];
1081 }
1082
1083 cfft_f32(&mut sig_buf[..2 * fft_n], fft_n, 0, 1);
1084 cfft_f32(&mut ker_buf[..2 * fft_n], fft_n, 0, 1);
1085
1086 for i in 0..fft_n {
1088 let a = sig_buf[2 * i];
1089 let b = sig_buf[2 * i + 1];
1090 let c = ker_buf[2 * i];
1091 let d = ker_buf[2 * i + 1];
1092 sig_buf[2 * i] = a * c - b * d;
1093 sig_buf[2 * i + 1] = a * d + b * c;
1094 }
1095
1096 cfft_f32(&mut sig_buf[..2 * fft_n], fft_n, 1, 1);
1098
1099 for i in 0..total_len {
1100 dst[i] = sig_buf[2 * i];
1101 }
1102
1103 Status::Success
1104}
1105
1106#[derive(Debug, Clone, Copy)]
1110pub struct CircularBuffer<T, const N: usize> {
1111 buffer: [T; N],
1112 head: usize,
1113 count: usize,
1114}
1115
1116impl<T: Copy, const N: usize> CircularBuffer<T, N> {
1117 pub const fn new(init_val: T) -> Self {
1119 Self {
1120 buffer: [init_val; N],
1121 head: 0,
1122 count: 0,
1123 }
1124 }
1125
1126 #[inline(always)]
1128 pub fn push(&mut self, sample: T) {
1129 if N == 0 {
1130 return;
1131 }
1132 self.buffer[self.head] = sample;
1133 self.head = (self.head + 1) % N;
1134 if self.count < N {
1135 self.count += 1;
1136 }
1137 }
1138
1139 #[inline(always)]
1142 pub fn get(&self, lag: usize) -> Option<T> {
1143 if lag >= self.count || N == 0 {
1144 return None;
1145 }
1146 let idx = (self.head + N - 1 - (lag % N)) % N;
1147 Some(self.buffer[idx])
1148 }
1149
1150 #[inline(always)]
1152 pub fn latest(&self) -> Option<T> {
1153 self.get(0)
1154 }
1155
1156 #[inline(always)]
1158 pub fn oldest(&self) -> Option<T> {
1159 if self.count == 0 {
1160 None
1161 } else {
1162 self.get(self.count - 1)
1163 }
1164 }
1165
1166 #[inline(always)]
1168 pub const fn len(&self) -> usize {
1169 self.count
1170 }
1171
1172 #[inline(always)]
1174 pub const fn capacity(&self) -> usize {
1175 N
1176 }
1177
1178 #[inline(always)]
1180 pub const fn is_empty(&self) -> bool {
1181 self.count == 0
1182 }
1183
1184 #[inline(always)]
1186 pub const fn is_full(&self) -> bool {
1187 self.count == N
1188 }
1189
1190 pub fn clear(&mut self, reset_val: T) {
1192 self.buffer = [reset_val; N];
1193 self.head = 0;
1194 self.count = 0;
1195 }
1196}
1197
1198#[derive(Debug, Clone, Copy, Default)]
1206#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1207pub struct SinglePoleFilter {
1208 b0: f32,
1209 b1: f32,
1210 a1: f32,
1211 x1: f32,
1212 y1: f32,
1213}
1214
1215impl SinglePoleFilter {
1216 pub fn lowpass(decay: f32) -> Self {
1219 Self {
1220 b0: 1.0 - decay,
1221 b1: 0.0,
1222 a1: decay,
1223 x1: 0.0,
1224 y1: 0.0,
1225 }
1226 }
1227
1228 pub fn highpass(decay: f32) -> Self {
1231 let b0 = (1.0 + decay) / 2.0;
1232 Self {
1233 b0,
1234 b1: -b0,
1235 a1: decay,
1236 x1: 0.0,
1237 y1: 0.0,
1238 }
1239 }
1240
1241 #[inline(always)]
1243 pub fn process(&mut self, x: f32) -> f32 {
1244 let y = self.b0 * x + self.b1 * self.x1 + self.a1 * self.y1;
1245 self.x1 = x;
1246 self.y1 = y;
1247 y
1248 }
1249
1250 pub fn reset(&mut self) {
1252 self.x1 = 0.0;
1253 self.y1 = 0.0;
1254 }
1255}
1256
1257#[derive(Debug, Clone, Copy, Default)]
1260#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1261pub struct SinglePoleFilterQ15 {
1262 b0: q15,
1263 b1: q15,
1264 a1: q15,
1265 x1: q15,
1266 y1: q15,
1267}
1268
1269impl SinglePoleFilterQ15 {
1270 pub fn lowpass(decay: q15) -> Self {
1272 let decay = decay.max(0);
1273 Self {
1274 b0: (32767i32 - decay as i32) as q15,
1275 b1: 0,
1276 a1: decay,
1277 x1: 0,
1278 y1: 0,
1279 }
1280 }
1281
1282 pub fn highpass(decay: q15) -> Self {
1285 let decay = decay.max(0);
1286 let b0 = ((32767i32 + decay as i32) / 2) as q15;
1287 Self {
1288 b0,
1289 b1: -b0,
1290 a1: decay,
1291 x1: 0,
1292 y1: 0,
1293 }
1294 }
1295
1296 pub fn lowpass_from_f32(decay: f32) -> Self {
1298 Self::lowpass((decay * 32767.0).clamp(0.0, 32767.0) as q15)
1299 }
1300
1301 pub fn highpass_from_f32(decay: f32) -> Self {
1303 Self::highpass((decay * 32767.0).clamp(0.0, 32767.0) as q15)
1304 }
1305
1306 #[inline(always)]
1308 pub fn process(&mut self, x: q15) -> q15 {
1309 let y = (self.b0 as i64 * x as i64
1310 + self.b1 as i64 * self.x1 as i64
1311 + self.a1 as i64 * self.y1 as i64)
1312 >> 15;
1313 let y = y.clamp(i16::MIN as i64, i16::MAX as i64) as q15;
1314 self.x1 = x;
1315 self.y1 = y;
1316 y
1317 }
1318
1319 pub fn reset(&mut self) {
1321 self.x1 = 0;
1322 self.y1 = 0;
1323 }
1324}
1325
1326#[derive(Debug, Clone, Copy, Default)]
1328#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1329pub struct DcBlockerQ15 {
1330 inner: SinglePoleFilterQ15,
1331}
1332
1333impl DcBlockerQ15 {
1334 pub fn new(decay: q15) -> Self {
1336 Self {
1337 inner: SinglePoleFilterQ15::highpass(decay),
1338 }
1339 }
1340
1341 pub fn from_f32_decay(decay: f32) -> Self {
1343 Self {
1344 inner: SinglePoleFilterQ15::highpass_from_f32(decay),
1345 }
1346 }
1347
1348 #[inline(always)]
1349 pub fn process(&mut self, x: q15) -> q15 {
1350 self.inner.process(x)
1351 }
1352
1353 pub fn reset(&mut self) {
1354 self.inner.reset();
1355 }
1356}
1357
1358#[derive(Debug, Clone)]
1364#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1365pub struct RecursiveMovingAverage<const N: usize> {
1366 history: CircularBuffer<f32, N>,
1367 sum: f32,
1368}
1369
1370impl<const N: usize> RecursiveMovingAverage<N> {
1371 pub const fn new() -> Self {
1373 Self {
1374 history: CircularBuffer::new(0.0),
1375 sum: 0.0,
1376 }
1377 }
1378
1379 #[inline(always)]
1382 pub fn process(&mut self, x: f32) -> f32 {
1383 let oldest = if self.history.is_full() {
1384 self.history.oldest().unwrap_or(0.0)
1385 } else {
1386 0.0
1387 };
1388 self.sum += x - oldest;
1389 self.history.push(x);
1390 if self.history.len() == 0 {
1391 0.0
1392 } else {
1393 self.sum / self.history.len() as f32
1394 }
1395 }
1396
1397 pub fn reset(&mut self) {
1399 self.history.clear(0.0);
1400 self.sum = 0.0;
1401 }
1402}
1403
1404impl<const N: usize> Default for RecursiveMovingAverage<N> {
1405 fn default() -> Self {
1406 Self::new()
1407 }
1408}
1409
1410#[derive(Debug, Clone)]
1412#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1413pub struct RecursiveMovingAverageQ15<const N: usize> {
1414 history: CircularBuffer<q15, N>,
1415 sum: i32,
1416}
1417
1418impl<const N: usize> RecursiveMovingAverageQ15<N> {
1419 pub const fn new() -> Self {
1420 Self {
1421 history: CircularBuffer::new(0),
1422 sum: 0,
1423 }
1424 }
1425
1426 #[inline(always)]
1427 pub fn process(&mut self, x: q15) -> q15 {
1428 let oldest = if self.history.is_full() {
1429 self.history.oldest().unwrap_or(0)
1430 } else {
1431 0
1432 };
1433 self.sum += x as i32 - oldest as i32;
1434 self.history.push(x);
1435 if self.history.len() == 0 {
1436 0
1437 } else {
1438 (self.sum / self.history.len() as i32).clamp(i16::MIN as i32, i16::MAX as i32) as q15
1439 }
1440 }
1441
1442 pub fn reset(&mut self) {
1443 self.history.clear(0);
1444 self.sum = 0;
1445 }
1446}
1447
1448impl<const N: usize> Default for RecursiveMovingAverageQ15<N> {
1449 fn default() -> Self {
1450 Self::new()
1451 }
1452}