1use crate::{
2 check_init, ffi,
3 vec::{CVec, CVecMut, CVecNormMut, CVecPhasMut, FVec, FVecMut},
4 Result, Status,
5};
6
7pub struct FFT {
19 fft: *mut ffi::aubio_fft_t,
20 win_size: usize,
21}
22
23impl Drop for FFT {
24 fn drop(&mut self) {
25 unsafe {
26 ffi::del_aubio_fft(self.fft);
27 }
28 }
29}
30
31impl FFT {
32 pub fn new(win_size: usize) -> Result<Self> {
36 let fft = unsafe { ffi::new_aubio_fft(win_size as ffi::uint_t) };
37
38 check_init(fft)?;
39
40 Ok(Self { fft, win_size })
41 }
42
43 pub fn get_win(&self) -> usize {
47 self.win_size
48 }
49
50 pub fn get_fft(&self) -> usize {
54 self.get_win() / 2 + 1
55 }
56
57 pub fn do_<'i, 'o, I, O>(&mut self, input: I, spectrum: O) -> Status
61 where
62 I: Into<FVec<'i>>,
63 O: Into<CVecMut<'o>>,
64 {
65 let input = input.into();
66 let mut spectrum = spectrum.into();
67
68 input.check_size(self.get_win())?;
69
70 unsafe {
71 ffi::aubio_fft_do(self.fft, input.as_ptr(), spectrum.as_mut_ptr());
72 }
73 Ok(())
74 }
75
76 pub fn rdo<'i, 'o, I, O>(&mut self, spectrum: I, output: O) -> Status
80 where
81 I: Into<CVec<'i>>,
82 O: Into<FVecMut<'o>>,
83 {
84 let spectrum = spectrum.into();
85 let mut output = output.into();
86
87 output.check_size(self.get_win())?;
88
89 unsafe {
90 ffi::aubio_fft_rdo(self.fft, spectrum.as_ptr(), output.as_mut_ptr());
91 }
92 Ok(())
93 }
94
95 pub fn do_complex<'i, 'o, I, O>(&mut self, input: I, compspec: O) -> Status
99 where
100 I: Into<FVec<'i>>,
101 O: Into<FVecMut<'o>>,
102 {
103 let input = input.into();
104 let mut compspec = compspec.into();
105
106 input.check_size(self.get_win())?;
107 compspec.check_size(self.get_win())?;
108
109 unsafe {
110 ffi::aubio_fft_do_complex(self.fft, input.as_ptr(), compspec.as_mut_ptr());
111 }
112 Ok(())
113 }
114
115 pub fn rdo_complex<'i, 'o, I, O>(&mut self, compspec: I, output: O) -> Status
119 where
120 I: Into<FVec<'i>>,
121 O: Into<FVecMut<'o>>,
122 {
123 let compspec = compspec.into();
124 let mut output = output.into();
125
126 compspec.check_size(self.get_win())?;
127 output.check_size(self.get_win())?;
128
129 unsafe {
130 ffi::aubio_fft_rdo_complex(self.fft, compspec.as_ptr(), output.as_mut_ptr());
131 }
132 Ok(())
133 }
134
135 pub fn get_spectrum<'i, 'o, I, O>(compspec: I, spectrum: O) -> Status
139 where
140 I: Into<FVec<'i>>,
141 O: Into<CVecMut<'o>>,
142 {
143 let compspec = compspec.into();
144 let mut spectrum = spectrum.into();
145
146 spectrum.check_size(compspec.size())?;
147
148 unsafe {
149 ffi::aubio_fft_get_spectrum(compspec.as_ptr(), spectrum.as_mut_ptr());
150 }
151 Ok(())
152 }
153
154 pub fn get_realimag<'i, 'o, I, O>(spectrum: I, compspec: O) -> Status
158 where
159 I: Into<CVec<'i>>,
160 O: Into<FVecMut<'o>>,
161 {
162 let spectrum = spectrum.into();
163 let mut compspec = compspec.into();
164
165 compspec.check_size(spectrum.size())?;
166
167 unsafe {
168 ffi::aubio_fft_get_realimag(spectrum.as_ptr(), compspec.as_mut_ptr());
169 }
170 Ok(())
171 }
172
173 pub fn get_phas<'i, 'o, I, O>(compspec: I, spectrum_phas: O) -> Status
177 where
178 I: Into<FVec<'i>>,
179 O: Into<CVecPhasMut<'o>>,
180 {
181 let compspec = compspec.into();
182 let mut spectrum_phas = spectrum_phas.into();
183
184 spectrum_phas.check_size(compspec.size())?;
185
186 unsafe {
187 ffi::aubio_fft_get_phas(compspec.as_ptr(), spectrum_phas.as_mut_ptr());
188 }
189 Ok(())
190 }
191
192 pub fn get_norm<'i, 'o, I, O>(compspec: I, spectrum_norm: O) -> Status
196 where
197 I: Into<FVec<'i>>,
198 O: Into<CVecNormMut<'o>>,
199 {
200 let compspec = compspec.into();
201 let mut spectrum_norm = spectrum_norm.into();
202
203 spectrum_norm.check_size(compspec.size())?;
204
205 unsafe {
206 ffi::aubio_fft_get_norm(compspec.as_ptr(), spectrum_norm.as_mut_ptr());
207 }
208 Ok(())
209 }
210
211 pub fn get_imag<'i, 'o, I, O>(spectrum: I, compspec: O) -> Status
215 where
216 I: Into<CVec<'i>>,
217 O: Into<FVecMut<'o>>,
218 {
219 let spectrum = spectrum.into();
220 let mut compspec = compspec.into();
221
222 compspec.check_size(spectrum.size())?;
223
224 unsafe {
225 ffi::aubio_fft_get_imag(spectrum.as_ptr(), compspec.as_mut_ptr());
226 }
227 Ok(())
228 }
229
230 pub fn get_real<'i, 'o, I, O>(spectrum: I, compspec: O) -> Status
234 where
235 I: Into<CVec<'i>>,
236 O: Into<FVecMut<'o>>,
237 {
238 let spectrum = spectrum.into();
239 let mut compspec = compspec.into();
240
241 compspec.check_size(spectrum.size())?;
242
243 unsafe {
244 ffi::aubio_fft_get_real(spectrum.as_ptr(), compspec.as_mut_ptr());
245 }
246 Ok(())
247 }
248}
249
250#[cfg(test)]
251mod test {
252 use crate::*;
253
254 #[test]
255 fn test() {
256 const ITERS: usize = 100; const WIN: usize = 512; let mut in_ = [0.; WIN]; let mut fftgrain = carr!(WIN); let mut out = [0.; WIN]; let mut fft = FFT::new(WIN).unwrap();
266
267 in_[0] = 1.0;
269 in_[1] = 2.0;
270 in_[2] = 3.0;
271 in_[3] = 4.0;
272 in_[4] = 5.0;
273 in_[5] = 6.0;
274 in_[6] = 5.0;
275 in_[7] = 6.0;
276 println!("in: {:?}", in_.as_ref());
277
278 for _i in 0..ITERS {
279 fft.do_(in_.as_ref(), fftgrain.as_mut()).unwrap();
281 println!("fftgrain: {:?}", fftgrain.as_ref());
282 fft.rdo(fftgrain.as_ref(), out.as_mut()).unwrap();
284 }
285
286 println!("out: {:?}", out.as_ref());
287 }
288}