1#[allow(unused_imports)]
4use crate::math::FloatMath;
5use crate::types::*;
6
7pub fn bit_reversal(data: &mut [f32], n: usize) {
9 let mut j = 0;
10 for i in 0..n {
11 if i < j {
12 data.swap(2 * i, 2 * j);
13 data.swap(2 * i + 1, 2 * j + 1);
14 }
15 let mut m = n >> 1;
16 while m >= 1 && j >= m {
17 j -= m;
18 m >>= 1;
19 }
20 j += m;
21 }
22}
23
24pub fn cfft_f32(data: &mut [f32], n: usize, ifft_flag: u8, bit_reverse_flag: u8) {
29 if n < 2 || (n & (n - 1)) != 0 {
30 return;
31 }
32
33 if bit_reverse_flag != 0 {
34 bit_reversal(data, n);
35 }
36
37 let mut len = 2;
38 while len <= n {
39 let half_len = len / 2;
40 let angle =
41 (if ifft_flag != 0 { 2.0 } else { -2.0 }) * core::f32::consts::PI / (len as f32);
42 let w_step_re = angle.cos();
43 let w_step_im = angle.sin();
44
45 let mut i = 0;
46 while i < n {
47 let mut w_re = 1.0f32;
48 let mut w_im = 0.0f32;
49
50 for j in 0..half_len {
51 let u_idx = 2 * (i + j);
52 let v_idx = 2 * (i + j + half_len);
53
54 let u_re = data[u_idx];
55 let u_im = data[u_idx + 1];
56
57 let v_re = data[v_idx];
58 let v_im = data[v_idx + 1];
59
60 let t_re = v_re * w_re - v_im * w_im;
61 let t_im = v_re * w_im + v_im * w_re;
62
63 data[u_idx] = u_re + t_re;
64 data[u_idx + 1] = u_im + t_im;
65
66 data[v_idx] = u_re - t_re;
67 data[v_idx + 1] = u_im - t_im;
68
69 let next_w_re = w_re * w_step_re - w_im * w_step_im;
70 let next_w_im = w_re * w_step_im + w_im * w_step_re;
71 w_re = next_w_re;
72 w_im = next_w_im;
73 }
74 i += len;
75 }
76 len <<= 1;
77 }
78
79 if ifft_flag != 0 {
80 let norm = 1.0 / (n as f32);
81 for i in 0..(2 * n) {
82 data[i] *= norm;
83 }
84 }
85}
86
87const TWIDDLE_N: usize = 512;
89
90const fn wrap_pi(mut x: f32) -> f32 {
91 while x > core::f32::consts::PI {
92 x -= 2.0 * core::f32::consts::PI;
93 }
94 while x < -core::f32::consts::PI {
95 x += 2.0 * core::f32::consts::PI;
96 }
97 x
98}
99
100const fn cos_taylor(x: f32) -> f32 {
101 let x = wrap_pi(x);
102 let x2 = x * x;
103 let x4 = x2 * x2;
104 let x6 = x4 * x2;
105 let x8 = x4 * x4;
106 1.0 - x2 / 2.0 + x4 / 24.0 - x6 / 720.0 + x8 / 40320.0
107}
108
109const fn sin_taylor(x: f32) -> f32 {
110 let x = wrap_pi(x);
111 let x2 = x * x;
112 let x3 = x2 * x;
113 let x5 = x3 * x2;
114 let x7 = x5 * x2;
115 let x9 = x7 * x2;
116 x - x3 / 6.0 + x5 / 120.0 - x7 / 5040.0 + x9 / 362880.0
117}
118
119const fn gen_cos_q15() -> [i16; TWIDDLE_N] {
120 let mut t = [0i16; TWIDDLE_N];
121 let mut i = 0;
122 while i < TWIDDLE_N {
123 let a = (i as f32) * 2.0 * core::f32::consts::PI / TWIDDLE_N as f32;
124 let v = cos_taylor(a) * 32767.0;
125 t[i] = if v >= 32767.0 {
126 32767
127 } else if v <= -32768.0 {
128 -32768
129 } else {
130 v as i16
131 };
132 i += 1;
133 }
134 t
135}
136
137const fn gen_sin_q15() -> [i16; TWIDDLE_N] {
138 let mut t = [0i16; TWIDDLE_N];
139 let mut i = 0;
140 while i < TWIDDLE_N {
141 let a = (i as f32) * 2.0 * core::f32::consts::PI / TWIDDLE_N as f32;
142 let v = sin_taylor(a) * 32767.0;
143 t[i] = if v >= 32767.0 {
144 32767
145 } else if v <= -32768.0 {
146 -32768
147 } else {
148 v as i16
149 };
150 i += 1;
151 }
152 t
153}
154
155const COS_Q15: [i16; TWIDDLE_N] = gen_cos_q15();
156const SIN_Q15: [i16; TWIDDLE_N] = gen_sin_q15();
157
158fn twiddle_q15(k: usize, n: usize) -> (i16, i16) {
159 let idx = k.wrapping_mul(TWIDDLE_N / n) & (TWIDDLE_N - 1);
160 (COS_Q15[idx], SIN_Q15[idx])
161}
162
163fn bit_reversal_q15(data: &mut [q15], n: usize) {
164 let mut j = 0;
165 for i in 0..n {
166 if i < j {
167 data.swap(2 * i, 2 * j);
168 data.swap(2 * i + 1, 2 * j + 1);
169 }
170 let mut m = n >> 1;
171 while m >= 1 && j >= m {
172 j -= m;
173 m >>= 1;
174 }
175 j += m;
176 }
177}
178
179fn bit_reversal_q31(data: &mut [q31], n: usize) {
180 let mut j = 0;
181 for i in 0..n {
182 if i < j {
183 data.swap(2 * i, 2 * j);
184 data.swap(2 * i + 1, 2 * j + 1);
185 }
186 let mut m = n >> 1;
187 while m >= 1 && j >= m {
188 j -= m;
189 m >>= 1;
190 }
191 j += m;
192 }
193}
194
195#[inline]
196fn sat_q15(v: i32) -> q15 {
197 q15::from_bits(v.clamp(i16::MIN as i32, i16::MAX as i32) as i16)
198}
199
200#[inline]
201fn sat_q31(v: i64) -> q31 {
202 q31::from_bits(v.clamp(i32::MIN as i64, i32::MAX as i64) as i32)
203}
204
205pub fn cfft_q31(data: &mut [q31], n: usize, ifft_flag: u8, bit_reverse_flag: u8) {
214 if n < 2 || n > TWIDDLE_N || (n & (n - 1)) != 0 || data.len() < 2 * n {
215 return;
216 }
217
218 if bit_reverse_flag != 0 {
219 bit_reversal_q31(data, n);
220 }
221
222 let mut len = 2;
223 while len <= n {
224 let half_len = len / 2;
225 let mut i = 0;
226 while i < n {
227 for j in 0..half_len {
228 let (w_re_s, w_im_s) = twiddle_q15(j, len);
229 let w_re = (w_re_s as i32) << 16;
230 let mut w_im = (w_im_s as i32) << 16;
231 if ifft_flag == 0 {
232 w_im = -w_im;
233 }
234
235 let u_idx = 2 * (i + j);
236 let v_idx = 2 * (i + j + half_len);
237 let u_re = data[u_idx].to_bits() as i64;
238 let u_im = data[u_idx + 1].to_bits() as i64;
239 let v_re = data[v_idx].to_bits() as i64;
240 let v_im = data[v_idx + 1].to_bits() as i64;
241 let wr = w_re as i64;
242 let wi = w_im as i64;
243
244 let t_re = (v_re * wr - v_im * wi) >> 31;
245 let t_im = (v_re * wi + v_im * wr) >> 31;
246
247 data[u_idx] = sat_q31((u_re + t_re) >> 1);
248 data[u_idx + 1] = sat_q31((u_im + t_im) >> 1);
249 data[v_idx] = sat_q31((u_re - t_re) >> 1);
250 data[v_idx + 1] = sat_q31((u_im - t_im) >> 1);
251 }
252 i += len;
253 }
254 len <<= 1;
255 }
256}
257
258pub fn cfft_q15(data: &mut [q15], n: usize, ifft_flag: u8, bit_reverse_flag: u8) {
263 if n < 2 || n > TWIDDLE_N || (n & (n - 1)) != 0 || data.len() < 2 * n {
264 return;
265 }
266
267 if bit_reverse_flag != 0 {
268 bit_reversal_q15(data, n);
269 }
270
271 let mut len = 2;
272 while len <= n {
273 let half_len = len / 2;
274 let mut i = 0;
275 while i < n {
276 for j in 0..half_len {
277 let (w_re_s, mut w_im_s) = twiddle_q15(j, len);
278 if ifft_flag == 0 {
279 w_im_s = w_im_s.saturating_neg();
280 }
281
282 let u_idx = 2 * (i + j);
283 let v_idx = 2 * (i + j + half_len);
284 let u_re = data[u_idx].to_bits() as i32;
285 let u_im = data[u_idx + 1].to_bits() as i32;
286 let v_re = data[v_idx].to_bits() as i32;
287 let v_im = data[v_idx + 1].to_bits() as i32;
288 let wr = w_re_s as i32;
289 let wi = w_im_s as i32;
290
291 let t_re = (v_re * wr - v_im * wi) >> 15;
292 let t_im = (v_re * wi + v_im * wr) >> 15;
293
294 data[u_idx] = sat_q15((u_re + t_re) >> 1);
295 data[u_idx + 1] = sat_q15((u_im + t_im) >> 1);
296 data[v_idx] = sat_q15((u_re - t_re) >> 1);
297 data[v_idx + 1] = sat_q15((u_im - t_im) >> 1);
298 }
299 i += len;
300 }
301 len <<= 1;
302 }
303}
304
305pub fn cfft_bfp_q15(data: &mut [q15], n: usize, ifft_flag: u8, bit_reverse_flag: u8) -> u16 {
314 if n < 2 || n > TWIDDLE_N || (n & (n - 1)) != 0 || data.len() < 2 * n {
315 return 0;
316 }
317
318 if bit_reverse_flag != 0 {
319 bit_reversal_q15(data, n);
320 }
321
322 let mut scale_count: u16 = 0;
323 let mut len = 2;
324 while len <= n {
325 let half_len = len / 2;
326
327 let mut max_val: i16 = 0;
329 for i in 0..2 * n {
330 let val = data[i].abs().to_bits();
331 if val > max_val {
332 max_val = val;
333 }
334 }
335
336 let stage_shift = if max_val > 16383 {
338 scale_count += 1;
339 1
340 } else {
341 0
342 };
343
344 let mut i = 0;
345 while i < n {
346 for j in 0..half_len {
347 let (w_re_s, mut w_im_s) = twiddle_q15(j, len);
348 if ifft_flag == 0 {
349 w_im_s = w_im_s.saturating_neg();
350 }
351
352 let u_idx = 2 * (i + j);
353 let v_idx = 2 * (i + j + half_len);
354 let u_re = data[u_idx].to_bits() as i32;
355 let u_im = data[u_idx + 1].to_bits() as i32;
356 let v_re = data[v_idx].to_bits() as i32;
357 let v_im = data[v_idx + 1].to_bits() as i32;
358 let wr = w_re_s as i32;
359 let wi = w_im_s as i32;
360
361 let t_re = (v_re * wr - v_im * wi) >> 15;
362 let t_im = (v_re * wi + v_im * wr) >> 15;
363
364 data[u_idx] = sat_q15((u_re + t_re) >> stage_shift);
365 data[u_idx + 1] = sat_q15((u_im + t_im) >> stage_shift);
366 data[v_idx] = sat_q15((u_re - t_re) >> stage_shift);
367 data[v_idx + 1] = sat_q15((u_im - t_im) >> stage_shift);
368 }
369 i += len;
370 }
371 len <<= 1;
372 }
373
374 scale_count
375}
376
377pub fn cfft_bfp_q31(data: &mut [q31], n: usize, ifft_flag: u8, bit_reverse_flag: u8) -> u16 {
381 if n < 2 || n > TWIDDLE_N || (n & (n - 1)) != 0 || data.len() < 2 * n {
382 return 0;
383 }
384
385 if bit_reverse_flag != 0 {
386 bit_reversal_q31(data, n);
387 }
388
389 let mut scale_count: u16 = 0;
390 let mut len = 2;
391 while len <= n {
392 let half_len = len / 2;
393
394 let mut max_val: i32 = 0;
395 for i in 0..2 * n {
396 let val = data[i].abs().to_bits();
397 if val > max_val {
398 max_val = val;
399 }
400 }
401
402 let stage_shift = if max_val > 1073741823 {
403 scale_count += 1;
404 1
405 } else {
406 0
407 };
408
409 let mut i = 0;
410 while i < n {
411 for j in 0..half_len {
412 let (w_re_s, w_im_s) = twiddle_q15(j, len);
413 let w_re = (w_re_s as i32) << 16;
414 let mut w_im = (w_im_s as i32) << 16;
415 if ifft_flag == 0 {
416 w_im = -w_im;
417 }
418
419 let u_idx = 2 * (i + j);
420 let v_idx = 2 * (i + j + half_len);
421 let u_re = data[u_idx].to_bits() as i64;
422 let u_im = data[u_idx + 1].to_bits() as i64;
423 let v_re = data[v_idx].to_bits() as i64;
424 let v_im = data[v_idx + 1].to_bits() as i64;
425 let wr = w_re as i64;
426 let wi = w_im as i64;
427
428 let t_re = (v_re * wr - v_im * wi) >> 31;
429 let t_im = (v_re * wi + v_im * wr) >> 31;
430
431 data[u_idx] = sat_q31((u_re + t_re) >> stage_shift);
432 data[u_idx + 1] = sat_q31((u_im + t_im) >> stage_shift);
433 data[v_idx] = sat_q31((u_re - t_re) >> stage_shift);
434 data[v_idx + 1] = sat_q31((u_im - t_im) >> stage_shift);
435 }
436 i += len;
437 }
438 len <<= 1;
439 }
440
441 scale_count
442}
443
444pub fn real_cepstrum_f32(src: &[f32], cepstrum_out: &mut [f32]) -> Status {
450 let n = src.len();
451 if n < 2 || (n & (n - 1)) != 0 || n > 512 {
452 return Status::ArgumentError;
453 }
454 if cepstrum_out.len() < n {
455 return Status::LengthError;
456 }
457
458 let mut c_buf = [0.0f32; 1024];
459 for i in 0..n {
460 c_buf[2 * i] = src[i];
461 c_buf[2 * i + 1] = 0.0;
462 }
463
464 cfft_f32(&mut c_buf[..2 * n], n, 0, 1);
466
467 for i in 0..n {
469 let re = c_buf[2 * i];
470 let im = c_buf[2 * i + 1];
471 let mag = (re * re + im * im).sqrt().max(1e-12);
472 c_buf[2 * i] = mag.ln();
473 c_buf[2 * i + 1] = 0.0;
474 }
475
476 cfft_f32(&mut c_buf[..2 * n], n, 1, 1);
478
479 let inv_n = 1.0 / (n as f32);
481 for i in 0..n {
482 cepstrum_out[i] = c_buf[2 * i] * inv_n;
483 }
484
485 Status::Success
486}
487
488pub fn rfft_f32(src: &[f32], dst: &mut [f32], n: usize, ifft_flag: u8) {
491 let len = src.len().min(n);
492 let mut c_data = [0.0f32; 1024];
493 if 2 * len > c_data.len() || dst.len() < 2 * len {
494 return;
495 }
496
497 for i in 0..len {
498 c_data[2 * i] = src[i];
499 c_data[2 * i + 1] = 0.0;
500 }
501
502 cfft_f32(&mut c_data[..2 * len], len, ifft_flag, 1);
503 dst[..2 * len].copy_from_slice(&c_data[..2 * len]);
504}
505
506fn packed_rfft_q15_forward(src: &[q15], dst: &mut [q15], n: usize) {
509 let m = n / 2;
510 let mut z = [q15::ZERO; 1024];
511 if 2 * m > z.len() {
512 return;
513 }
514 for k in 0..m {
515 z[2 * k] = src[2 * k];
516 z[2 * k + 1] = src[2 * k + 1];
517 }
518 cfft_q15(&mut z[..2 * m], m, 0, 1);
519
520 let z0r = z[0].to_bits() as i32;
521 let z0i = z[1].to_bits() as i32;
522 dst[0] = sat_q15((z0r + z0i) >> 1);
523 dst[1] = q15::ZERO;
524 dst[n] = sat_q15((z0r - z0i) >> 1);
525 dst[n + 1] = q15::ZERO;
526
527 for k in 1..m {
528 let zr = z[2 * k].to_bits() as i32;
529 let zi = z[2 * k + 1].to_bits() as i32;
530 let znr = z[2 * (m - k)].to_bits() as i32;
531 let zni = z[2 * (m - k) + 1].to_bits() as i32;
532
533 let xe_re = (zr + znr) >> 1;
534 let xe_im = (zi - zni) >> 1;
535 let xo_re = (zi + zni) >> 1;
536 let xo_im = (znr - zr) >> 1;
537
538 let (wr, wi_s) = twiddle_q15(k, n);
539 let wr = wr as i32;
540 let wi = -(wi_s as i32);
541
542 let t_re = (xo_re * wr - xo_im * wi) >> 15;
543 let t_im = (xo_re * wi + xo_im * wr) >> 15;
544
545 dst[2 * k] = sat_q15((xe_re + t_re) >> 1);
546 dst[2 * k + 1] = sat_q15((xe_im + t_im) >> 1);
547 dst[2 * (n - k)] = sat_q15((xe_re - t_re) >> 1);
548 dst[2 * (n - k) + 1] = sat_q15((t_im - xe_im) >> 1);
549 }
550}
551
552fn packed_rfft_q31_forward(src: &[q31], dst: &mut [q31], n: usize) {
553 let m = n / 2;
554 let mut z = [q31::ZERO; 1024];
555 if 2 * m > z.len() {
556 return;
557 }
558 for k in 0..m {
559 z[2 * k] = src[2 * k];
560 z[2 * k + 1] = src[2 * k + 1];
561 }
562 cfft_q31(&mut z[..2 * m], m, 0, 1);
563
564 let z0r = z[0].to_bits() as i64;
565 let z0i = z[1].to_bits() as i64;
566 dst[0] = sat_q31((z0r + z0i) >> 1);
567 dst[1] = q31::ZERO;
568 dst[n] = sat_q31((z0r - z0i) >> 1);
569 dst[n + 1] = q31::ZERO;
570
571 for k in 1..m {
572 let zr = z[2 * k].to_bits() as i64;
573 let zi = z[2 * k + 1].to_bits() as i64;
574 let znr = z[2 * (m - k)].to_bits() as i64;
575 let zni = z[2 * (m - k) + 1].to_bits() as i64;
576
577 let xe_re = (zr + znr) >> 1;
578 let xe_im = (zi - zni) >> 1;
579 let xo_re = (zi + zni) >> 1;
580 let xo_im = (znr - zr) >> 1;
581
582 let (wr_s, wi_s) = twiddle_q15(k, n);
583 let wr = (wr_s as i64) << 16;
584 let wi = -((wi_s as i64) << 16);
585
586 let t_re = (xo_re * wr - xo_im * wi) >> 31;
587 let t_im = (xo_re * wi + xo_im * wr) >> 31;
588
589 dst[2 * k] = sat_q31((xe_re + t_re) >> 1);
590 dst[2 * k + 1] = sat_q31((xe_im + t_im) >> 1);
591 dst[2 * (n - k)] = sat_q31((xe_re - t_re) >> 1);
592 dst[2 * (n - k) + 1] = sat_q31((t_im - xe_im) >> 1);
593 }
594}
595
596fn packed_irfft_q15(src: &[q15], dst: &mut [q15], n: usize) {
597 let m = n / 2;
598 let mut z = [q15::ZERO; 1024];
599 if 2 * m > z.len() {
600 return;
601 }
602
603 let dc = src[0].to_bits() as i32;
604 let ny = src[n].to_bits() as i32;
605 z[0] = sat_q15(dc + ny);
606 z[1] = sat_q15(dc - ny);
607
608 for k in 1..m {
609 let xkr = src[2 * k].to_bits() as i32;
610 let xki = src[2 * k + 1].to_bits() as i32;
611 let xnr = src[2 * (n - k)].to_bits() as i32;
612 let xni = src[2 * (n - k) + 1].to_bits() as i32;
613
614 let xe_re = xkr + xnr;
615 let xe_im = xki - xni;
616 let t_re = xkr - xnr;
617 let t_im = xki + xni;
618
619 let (wr, wi_s) = twiddle_q15(k, n);
620 let wr = wr as i32;
621 let wi = wi_s as i32;
622 let xo_re = (t_re * wr - t_im * wi) >> 15;
623 let xo_im = (t_re * wi + t_im * wr) >> 15;
624
625 z[2 * k] = sat_q15(xe_re - xo_im);
626 z[2 * k + 1] = sat_q15(xe_im + xo_re);
627 }
628
629 cfft_q15(&mut z[..2 * m], m, 1, 1);
630 for k in 0..m {
631 dst[2 * k] = sat_q15((z[2 * k].to_bits() as i32) >> 1);
632 dst[2 * k + 1] = sat_q15((z[2 * k + 1].to_bits() as i32) >> 1);
633 }
634}
635
636fn packed_irfft_q31(src: &[q31], dst: &mut [q31], n: usize) {
637 let m = n / 2;
638 let mut z = [q31::ZERO; 1024];
639 if 2 * m > z.len() {
640 return;
641 }
642
643 let dc = src[0].to_bits() as i64;
644 let ny = src[n].to_bits() as i64;
645 z[0] = sat_q31(dc + ny);
646 z[1] = sat_q31(dc - ny);
647
648 for k in 1..m {
649 let xkr = src[2 * k].to_bits() as i64;
650 let xki = src[2 * k + 1].to_bits() as i64;
651 let xnr = src[2 * (n - k)].to_bits() as i64;
652 let xni = src[2 * (n - k) + 1].to_bits() as i64;
653
654 let xe_re = xkr + xnr;
655 let xe_im = xki - xni;
656 let t_re = xkr - xnr;
657 let t_im = xki + xni;
658
659 let (wr_s, wi_s) = twiddle_q15(k, n);
660 let wr = (wr_s as i64) << 16;
661 let wi = (wi_s as i64) << 16;
662 let xo_re = (t_re * wr - t_im * wi) >> 31;
663 let xo_im = (t_re * wi + t_im * wr) >> 31;
664
665 z[2 * k] = sat_q31(xe_re - xo_im);
666 z[2 * k + 1] = sat_q31(xe_im + xo_re);
667 }
668
669 cfft_q31(&mut z[..2 * m], m, 1, 1);
670 for k in 0..m {
671 dst[2 * k] = sat_q31((z[2 * k].to_bits() as i64) >> 1);
672 dst[2 * k + 1] = sat_q31((z[2 * k + 1].to_bits() as i64) >> 1);
673 }
674}
675
676fn rfft_q_can_pack(len: usize, ifft_flag: u8) -> bool {
677 ifft_flag == 0 && len >= 4 && len <= TWIDDLE_N && (len & (len - 1)) == 0
678}
679
680pub fn rfft_q31(src: &[q31], dst: &mut [q31], n: usize, ifft_flag: u8) {
687 let len = src.len().min(n);
688 if dst.len() < 2 * len {
689 return;
690 }
691
692 if rfft_q_can_pack(len, ifft_flag) {
693 packed_rfft_q31_forward(&src[..len], dst, len);
694 return;
695 }
696
697 let mut c_data = [q31::ZERO; 1024];
698 if 2 * len > c_data.len() {
699 return;
700 }
701
702 for i in 0..len {
703 c_data[2 * i] = src[i];
704 c_data[2 * i + 1] = q31::ZERO;
705 }
706 cfft_q31(&mut c_data[..2 * len], len, ifft_flag, 1);
707 dst[..2 * len].copy_from_slice(&c_data[..2 * len]);
708}
709
710pub fn rfft_q15(src: &[q15], dst: &mut [q15], n: usize, ifft_flag: u8) {
715 let len = src.len().min(n);
716 if dst.len() < 2 * len {
717 return;
718 }
719
720 if rfft_q_can_pack(len, ifft_flag) {
721 packed_rfft_q15_forward(&src[..len], dst, len);
722 return;
723 }
724
725 let mut c_data = [q15::ZERO; 1024];
726 if 2 * len > c_data.len() {
727 return;
728 }
729
730 for i in 0..len {
731 c_data[2 * i] = src[i];
732 c_data[2 * i + 1] = q15::ZERO;
733 }
734 cfft_q15(&mut c_data[..2 * len], len, ifft_flag, 1);
735 dst[..2 * len].copy_from_slice(&c_data[..2 * len]);
736}
737
738pub fn irfft_q31(src: &[q31], dst: &mut [q31], n: usize) {
742 if n < 4 || n > TWIDDLE_N || (n & (n - 1)) != 0 || src.len() < 2 * n || dst.len() < n {
743 return;
744 }
745 packed_irfft_q31(&src[..2 * n], dst, n);
746}
747
748pub fn irfft_q15(src: &[q15], dst: &mut [q15], n: usize) {
752 if n < 4 || n > TWIDDLE_N || (n & (n - 1)) != 0 || src.len() < 2 * n || dst.len() < n {
753 return;
754 }
755 packed_irfft_q15(&src[..2 * n], dst, n);
756}
757
758pub fn dct4_f32(src: &[f32], dst: &mut [f32], n: usize) {
760 let len = src.len().min(dst.len()).min(n);
761 let pi_over_n = core::f32::consts::PI / (len as f32);
762
763 for k in 0..len {
764 let mut sum = 0.0f32;
765 let k_factor = (k as f32 + 0.5) * pi_over_n;
766 for n_idx in 0..len {
767 let angle = (n_idx as f32 + 0.5) * k_factor;
768 sum += src[n_idx] * angle.cos();
769 }
770 let norm = (2.0 / len as f32).sqrt();
771 dst[k] = sum * norm;
772 }
773}
774
775pub fn fwht_f32(data: &mut [f32]) -> Status {
781 let n = data.len();
782 if n < 2 || (n & (n - 1)) != 0 {
783 return Status::ArgumentError;
784 }
785
786 let mut h = 1;
787 while h < n {
788 let mut i = 0;
789 while i < n {
790 for j in i..(i + h) {
791 let x = data[j];
792 let y = data[j + h];
793 data[j] = x + y;
794 data[j + h] = x - y;
795 }
796 i += h * 2;
797 }
798 h *= 2;
799 }
800
801 Status::Success
802}
803
804pub fn ifwht_f32(data: &mut [f32]) -> Status {
806 let status = fwht_f32(data);
807 if status != Status::Success {
808 return status;
809 }
810 let norm = 1.0f32 / (data.len() as f32);
811 for val in data.iter_mut() {
812 *val *= norm;
813 }
814 Status::Success
815}
816
817pub fn fwht_i32(data: &mut [i32]) -> Status {
819 let n = data.len();
820 if n < 2 || (n & (n - 1)) != 0 {
821 return Status::ArgumentError;
822 }
823
824 let mut h = 1;
825 while h < n {
826 let mut i = 0;
827 while i < n {
828 for j in i..(i + h) {
829 let x = data[j];
830 let y = data[j + h];
831 data[j] = x.wrapping_add(y);
832 data[j + h] = x.wrapping_sub(y);
833 }
834 i += h * 2;
835 }
836 h *= 2;
837 }
838
839 Status::Success
840}
841
842pub fn haar_transform_f32(data: &mut [f32]) -> Status {
850 let n = data.len();
851 if n < 2 || (n & (n - 1)) != 0 {
852 return Status::ArgumentError;
853 }
854
855 let s2 = (0.5f32).sqrt();
856 let mut v = 1.0f32;
857 let mut js = 2;
858 while js <= n {
859 v *= s2;
860 let half = js >> 1;
861 let mut j = 0;
862 while j < n {
863 let t = j + half;
864 let x = data[j];
865 let y = data[t];
866 data[j] = x + y;
867 data[t] = (x - y) * v;
868 j += js;
869 }
870 js <<= 1;
871 }
872 data[0] *= v; Status::Success
875}
876
877pub fn inverse_haar_transform_f32(data: &mut [f32]) -> Status {
879 let n = data.len();
880 if n < 2 || (n & (n - 1)) != 0 {
881 return Status::ArgumentError;
882 }
883
884 let s2 = 2.0f32.sqrt();
885 let mut v = 1.0f32 / (n as f32).sqrt();
886 data[0] *= v;
887
888 let mut js = n;
889 while js >= 2 {
890 let half = js >> 1;
891 let mut j = 0;
892 while j < n {
893 let t = j + half;
894 let x = data[j];
895 let y = data[t] * v;
896 data[j] = x + y;
897 data[t] = x - y;
898 j += js;
899 }
900 v *= s2;
901 js >>= 1;
902 }
903
904 Status::Success
905}
906
907pub fn haar_transform_i32(data: &mut [i32]) -> Status {
916 let n = data.len();
917 if n < 2 || (n & (n - 1)) != 0 {
918 return Status::ArgumentError;
919 }
920
921 let mut js = 2;
922 while js <= n {
923 let half = js >> 1;
924 let mut j = 0;
925 while j < n {
926 let t = j + half;
927 let x = data[j];
928 let y = data[t];
929 data[j] = x.wrapping_add(y);
930 data[t] = x.wrapping_sub(y);
931 j += js;
932 }
933 js <<= 1;
934 }
935
936 Status::Success
937}
938
939pub fn hartley_transform_f32(data: &mut [f32]) -> Status {
953 let n = data.len();
954 if n < 2 || (n & (n - 1)) != 0 {
955 return Status::ArgumentError;
956 }
957 if 2 * n > 1024 {
958 return Status::LengthError;
959 }
960
961 let mut c_data = [0.0f32; 1024];
962 for i in 0..n {
963 c_data[2 * i] = data[i];
964 c_data[2 * i + 1] = 0.0;
965 }
966
967 cfft_f32(&mut c_data[..2 * n], n, 0, 1);
968
969 let inv_sqrt_n = 1.0 / (n as f32).sqrt();
970 for i in 0..n {
971 data[i] = (c_data[2 * i] - c_data[2 * i + 1]) * inv_sqrt_n;
972 }
973
974 Status::Success
975}
976
977pub const DAUBECHIES_4: [f32; 4] = [0.482_962_9, 0.836_516_3, 0.224_143_87, -0.129_409_52];
983
984#[inline(always)]
987fn wavelet_high_pass_tap(h: &[f32], k: usize) -> f32 {
988 let v = h[h.len() - 1 - k];
989 if k % 2 == 0 { v } else { -v }
990}
991
992pub fn wavelet_step_f32(data: &mut [f32], m: usize, h: &[f32]) -> Status {
999 let taps = h.len();
1000 if m < 2 || (m & (m - 1)) != 0 || taps == 0 || taps % 2 != 0 || taps > m || data.len() < m {
1001 return Status::ArgumentError;
1002 }
1003 if m > 1024 {
1004 return Status::LengthError;
1005 }
1006
1007 let mut scratch = [0.0f32; 1024];
1008 let nh = m >> 1;
1009 let mut i = 0;
1010 while i < m {
1011 let mut s = 0.0f32;
1012 let mut d = 0.0f32;
1013 for k in 0..taps {
1014 let idx = (i + k) % m;
1015 let x = data[idx];
1016 s += h[k] * x;
1017 d += wavelet_high_pass_tap(h, k) * x;
1018 }
1019 let j = i / 2;
1020 scratch[j] = s;
1021 scratch[nh + j] = d;
1022 i += 2;
1023 }
1024 data[..m].copy_from_slice(&scratch[..m]);
1025
1026 Status::Success
1027}
1028
1029pub fn inverse_wavelet_step_f32(data: &mut [f32], m: usize, h: &[f32]) -> Status {
1033 let taps = h.len();
1034 if m < 2 || (m & (m - 1)) != 0 || taps == 0 || taps % 2 != 0 || taps > m || data.len() < m {
1035 return Status::ArgumentError;
1036 }
1037 if m > 1024 {
1038 return Status::LengthError;
1039 }
1040
1041 let mut scratch = [0.0f32; 1024];
1042 let nh = m >> 1;
1043 for j in 0..nh {
1044 let s = data[j];
1045 let d = data[nh + j];
1046 for k in 0..taps {
1047 let idx = (2 * j + k) % m;
1048 scratch[idx] += h[k] * s + wavelet_high_pass_tap(h, k) * d;
1049 }
1050 }
1051 data[..m].copy_from_slice(&scratch[..m]);
1052
1053 Status::Success
1054}
1055
1056pub fn wavelet_transform_f32(data: &mut [f32], h: &[f32]) -> Status {
1063 let n = data.len();
1064 if n < 2 || (n & (n - 1)) != 0 || h.len() > n {
1065 return Status::ArgumentError;
1066 }
1067
1068 let mut m = n;
1069 while m >= h.len() {
1070 let status = wavelet_step_f32(&mut data[..m], m, h);
1071 if status != Status::Success {
1072 return status;
1073 }
1074 m >>= 1;
1075 }
1076
1077 Status::Success
1078}
1079
1080pub fn inverse_wavelet_transform_f32(data: &mut [f32], h: &[f32]) -> Status {
1084 let n = data.len();
1085 if n < 2 || (n & (n - 1)) != 0 || h.len() > n {
1086 return Status::ArgumentError;
1087 }
1088
1089 let mut smallest = n;
1090 while smallest >= h.len() {
1091 smallest >>= 1;
1092 }
1093 smallest <<= 1;
1094
1095 let mut m = smallest;
1096 while m <= n {
1097 let status = inverse_wavelet_step_f32(&mut data[..m], m, h);
1098 if status != Status::Success {
1099 return status;
1100 }
1101 m <<= 1;
1102 }
1103
1104 Status::Success
1105}