84 lines
2.4 KiB
Rust
84 lines
2.4 KiB
Rust
use rustfft::num_complex::Complex;
|
|
use std::f64;
|
|
|
|
use crate::DctNum;
|
|
|
|
#[inline(always)]
|
|
pub fn single_twiddle<T: DctNum>(i: usize, fft_len: usize) -> Complex<T> {
|
|
let angle_constant = f64::consts::PI * -2f64 / fft_len as f64;
|
|
|
|
let c = Complex::from_polar(1f64, angle_constant * i as f64);
|
|
|
|
Complex {
|
|
re: T::from_f64(c.re).unwrap(),
|
|
im: T::from_f64(c.im).unwrap(),
|
|
}
|
|
}
|
|
|
|
// Same as above, but only return the real portion, not the imaginary portion
|
|
#[inline(always)]
|
|
pub fn single_twiddle_re<T: DctNum>(i: usize, fft_len: usize) -> T {
|
|
let angle_constant = f64::consts::PI * -2f64 / fft_len as f64;
|
|
|
|
let c = (angle_constant * i as f64).cos();
|
|
|
|
T::from_f64(c).unwrap()
|
|
}
|
|
|
|
// Same as above, but we add 0.5 to 0 before
|
|
#[inline(always)]
|
|
pub fn single_twiddle_halfoffset<T: DctNum>(i: usize, fft_len: usize) -> Complex<T> {
|
|
let angle_constant = f64::consts::PI * -2f64 / fft_len as f64;
|
|
|
|
let c = Complex::from_polar(1f64, angle_constant * (i as f64 + 0.5f64));
|
|
|
|
Complex {
|
|
re: T::from_f64(c.re).unwrap(),
|
|
im: T::from_f64(c.im).unwrap(),
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod unit_tests {
|
|
use super::*;
|
|
use std::f32;
|
|
|
|
use crate::test_utils::fuzzy_cmp;
|
|
|
|
#[test]
|
|
fn test_single() {
|
|
let len = 20;
|
|
|
|
for i in 0..len {
|
|
let single: Complex<f32> = single_twiddle(i, len);
|
|
let single_inverse: Complex<f32> = single_twiddle(i, len).conj();
|
|
|
|
let expected =
|
|
Complex::from_polar(1f32, -2f32 * f32::consts::PI * i as f32 / len as f32);
|
|
let expected_inverse =
|
|
Complex::from_polar(1f32, 2f32 * f32::consts::PI * i as f32 / len as f32);
|
|
|
|
assert!(
|
|
fuzzy_cmp(single.re, expected.re, 0.001f32),
|
|
"forwards, i = {}",
|
|
i
|
|
);
|
|
assert!(
|
|
fuzzy_cmp(single.im, expected.im, 0.001f32),
|
|
"forwards, i = {}",
|
|
i
|
|
);
|
|
assert!(
|
|
fuzzy_cmp(single_inverse.re, expected_inverse.re, 0.001f32),
|
|
"inverse, i = {}",
|
|
i
|
|
);
|
|
assert!(
|
|
fuzzy_cmp(single_inverse.im, expected_inverse.im, 0.001f32),
|
|
"inverse, i = {}",
|
|
i
|
|
);
|
|
}
|
|
}
|
|
}
|