use cmsis_dsp_sys_pregenerated::{
arm_cfft_f32, arm_cfft_instance_f32, arm_rfft_fast_f32, arm_rfft_fast_instance_f32,
};
use num::Complex;
#[derive(Clone, Copy)]
#[repr(usize)]
pub enum FftSize {
Size32 = 32,
Size64 = 64,
Size128 = 128,
Size256 = 256,
Size512 = 512,
Size1024 = 1024,
Size2048 = 2048,
Size4096 = 4096,
}
pub struct RealFft {
instance: arm_rfft_fast_instance_f32,
}
impl RealFft {
pub(crate) fn new(instance: arm_rfft_fast_instance_f32) -> Self {
Self { instance }
}
pub fn real_size(&self) -> usize {
self.instance.fftLenRFFT as usize
}
pub fn complex_size(&self) -> usize {
(self.instance.fftLenRFFT / 2) as usize
}
pub fn fft(&self, src: &mut [f32], dest: &mut [Complex<f32>]) {
assert!(src.len() >= self.real_size(), "Input slice too small");
assert!(dest.len() >= self.complex_size(), "Output slice too small");
unsafe {
arm_rfft_fast_f32(
&self.instance as *const arm_rfft_fast_instance_f32,
src.as_mut_ptr(),
dest.as_mut_ptr() as *mut f32,
0,
);
}
}
pub fn ifft(&self, src: &mut [Complex<f32>], dest: &mut [f32]) {
assert!(src.len() >= self.complex_size(), "Input slice too small");
assert!(dest.len() >= self.real_size(), "Output slice too small");
unsafe {
arm_rfft_fast_f32(
&self.instance as *const arm_rfft_fast_instance_f32,
src.as_mut_ptr() as *mut f32,
dest.as_mut_ptr(),
1,
);
}
}
}
impl Clone for RealFft {
fn clone(&self) -> Self {
Self {
instance: arm_rfft_fast_instance_f32 {
Sint: arm_cfft_instance_f32 {
fftLen: self.instance.Sint.fftLen,
pTwiddle: self.instance.Sint.pTwiddle,
pBitRevTable: self.instance.Sint.pBitRevTable,
bitRevLength: self.instance.Sint.bitRevLength,
},
fftLenRFFT: self.instance.fftLenRFFT,
pTwiddleRFFT: self.instance.pTwiddleRFFT,
},
}
}
}
unsafe impl Send for RealFft {}
unsafe impl Sync for RealFft {}
pub struct ComplexFft {
instance: arm_cfft_instance_f32,
}
impl ComplexFft {
pub(crate) fn new(instance: arm_cfft_instance_f32) -> Self {
Self { instance }
}
pub fn size(&self) -> usize {
self.instance.fftLen as usize
}
pub fn fft(&self, buff: &mut [Complex<f32>]) {
assert!(buff.len() >= self.size(), "Input slice too small");
unsafe {
arm_cfft_f32(
&self.instance as *const arm_cfft_instance_f32,
buff.as_mut_ptr() as *mut f32,
0,
0,
);
}
}
pub fn ifft(&self, buff: &mut [Complex<f32>]) {
assert!(buff.len() >= self.size(), "Input slice too small");
unsafe {
arm_cfft_f32(
&self.instance as *const arm_cfft_instance_f32,
buff.as_mut_ptr() as *mut f32,
1,
0,
);
}
}
}
impl Clone for ComplexFft {
fn clone(&self) -> Self {
Self {
instance: arm_cfft_instance_f32 {
fftLen: self.instance.fftLen,
pTwiddle: self.instance.pTwiddle,
pBitRevTable: self.instance.pBitRevTable,
bitRevLength: self.instance.bitRevLength,
},
}
}
}
unsafe impl Send for ComplexFft {}
unsafe impl Sync for ComplexFft {}