ffts_sys/
lib.rs

1#![allow(non_camel_case_types)]
2
3include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
4
5#[cfg(test)]
6mod tests {
7    use super::*;
8    use libc::{c_float, free, posix_memalign};
9    use std::{f64, mem::size_of, ptr, slice};
10
11    fn impulse_error(n: usize, sign: i32, data: &[f32]) -> f64 {
12        let mut delta_sum: f64 = 0.0;
13        let mut sum: f64 = 0.0;
14
15        let mut re: f64;
16        let mut im: f64;
17        let mut inner: f64;
18
19        for i in 0..n {
20            inner = 2.0 * f64::consts::PI * (i as f64) / (n as f64);
21            re = inner.cos();
22            im = if sign < 0 { -inner.sin() } else { inner.sin() };
23
24            sum += re * re + im * im;
25
26            re = re - (data[2 * i] as f64);
27            im = im - (data[2 * i + 1] as f64);
28
29            delta_sum += re * re + im * im;
30        }
31
32        delta_sum.sqrt() / sum.sqrt()
33    }
34
35    fn test_transform(n: usize, sign: i32) {
36        unsafe {
37            let mut _input = ptr::null_mut();
38            let mut _output = ptr::null_mut();
39
40            match posix_memalign(&mut _input, 32, 2 * n * size_of::<f32>()) {
41                0 => (),
42                _ => panic!("posix_memalign failed for input array"),
43            }
44
45            match posix_memalign(&mut _output, 32, 2 * n * size_of::<f32>()) {
46                0 => (),
47                _ => panic!("posix_memalign failed for output array"),
48            }
49
50            let input: &mut [c_float] = slice::from_raw_parts_mut(_input as *mut c_float, 2 * n);
51            let output: &mut [c_float] = slice::from_raw_parts_mut(_output as *mut c_float, 2 * n);
52
53            for i in 0..n {
54                input[2 * i + 0] = 0.0;
55                input[2 * i + 1] = 0.0;
56            }
57
58            input[2] = 1.0;
59
60            let p = ffts_init_1d(n, sign);
61
62            if p.is_null() {
63                panic!("ffts plan unsupported")
64            }
65
66            ffts_execute(p, _input, _output);
67
68            println!(
69                " {:3}  | {:9} | {:.6E}",
70                sign,
71                n,
72                impulse_error(n, sign, output)
73            );
74
75            ffts_free(p);
76
77            free(_input);
78            free(_output);
79        }
80    }
81
82    #[test]
83    fn test_ffts_errors() {
84        let mut n: usize = 1;
85        let mut power2: usize = 2;
86
87        while n <= 18 {
88            test_transform(power2, -1);
89            n += 1;
90            power2 <<= 1;
91        }
92
93        n = 1;
94        power2 = 2;
95        while n <= 18 {
96            test_transform(power2, 1);
97            n += 1;
98            power2 <<= 1;
99        }
100    }
101}