basic_dsp_vector/vector_types/time_freq/
freq_to_time.rs1use super::super::{
2 Buffer, ComplexNumberSpace, DataDomain, DspVec, ErrorReason, FloatIndex, FrequencyDomain,
3 FrequencyDomainOperations, InsertZerosOpsBuffered, MetaData, RededicateForceOps, ScaleOps,
4 TimeDomainOperations, ToRealTimeResult, ToSliceMut, ToTimeResult, TransRes, Vector,
5};
6use super::fft;
7use crate::multicore_support::*;
8use crate::numbers::*;
9use crate::window_functions::*;
10use rustfft::FftDirection;
11
12pub trait FrequencyToTimeDomainOperations<S, T>: ToTimeResult
17where
18 S: ToSliceMut<T>,
19 T: RealNumber,
20{
21 fn plain_ifft<B>(self, buffer: &mut B) -> Self::TimeResult
43 where
44 B: for<'a> Buffer<'a, S, T>;
45
46 fn ifft<B>(self, buffer: &mut B) -> Self::TimeResult
65 where
66 B: for<'a> Buffer<'a, S, T>;
67
68 fn windowed_ifft<B>(self, buffer: &mut B, window: &dyn WindowFunction<T>) -> Self::TimeResult
71 where
72 B: for<'a> Buffer<'a, S, T>;
73}
74
75pub trait SymmetricFrequencyToTimeDomainOperations<S, T>: ToRealTimeResult
82where
83 S: ToSliceMut<T>,
84 T: RealNumber,
85{
86 fn plain_sifft<B>(self, buffer: &mut B) -> TransRes<Self::RealTimeResult>
97 where
98 B: for<'a> Buffer<'a, S, T>;
99
100 fn sifft<B>(self, buffer: &mut B) -> TransRes<Self::RealTimeResult>
108 where
109 B: for<'a> Buffer<'a, S, T>;
110
111 fn windowed_sifft<B>(
120 self,
121 buffer: &mut B,
122 window: &dyn WindowFunction<T>,
123 ) -> TransRes<Self::RealTimeResult>
124 where
125 B: for<'a> Buffer<'a, S, T>;
126}
127
128impl<S, T, N, D> FrequencyToTimeDomainOperations<S, T> for DspVec<S, T, N, D>
129where
130 DspVec<S, T, N, D>: ToTimeResult,
131 <DspVec<S, T, N, D> as ToTimeResult>::TimeResult:
132 RededicateForceOps<DspVec<S, T, N, D>> + TimeDomainOperations<S, T>,
133 S: ToSliceMut<T>,
134 T: RealNumber,
135 N: ComplexNumberSpace,
136 D: FrequencyDomain,
137{
138 fn plain_ifft<B>(mut self, buffer: &mut B) -> Self::TimeResult
139 where
140 B: for<'a> Buffer<'a, S, T>,
141 {
142 if self.domain() != DataDomain::Frequency {
143 self.mark_vector_as_invalid();
144 self.number_space.to_complex();
145 self.domain.to_freq();
146 return Self::TimeResult::rededicate_from_force(self);
147 }
148
149 if !self.is_complex() {
150 self.zero_interleave_b(buffer, 2);
151 self.number_space.to_complex();
152 }
153
154 fft(&mut self, buffer, FftDirection::Inverse);
155
156 self.domain.to_freq();
157 Self::TimeResult::rededicate_from_force(self)
158 }
159
160 fn ifft<B>(mut self, buffer: &mut B) -> Self::TimeResult
161 where
162 B: for<'a> Buffer<'a, S, T>,
163 {
164 let points = self.points();
165 self.scale(T::one() / T::from(points).unwrap());
166 self.ifft_shift();
167 self.plain_ifft(buffer)
168 }
169
170 fn windowed_ifft<B>(self, buffer: &mut B, window: &dyn WindowFunction<T>) -> Self::TimeResult
171 where
172 B: for<'a> Buffer<'a, S, T>,
173 {
174 let mut result = self.ifft(buffer);
175 result.unapply_window(window);
176 result
177 }
178}
179
180impl<S, T, N, D> SymmetricFrequencyToTimeDomainOperations<S, T> for DspVec<S, T, N, D>
181where
182 DspVec<S, T, N, D>: ToRealTimeResult + ToTimeResult + FrequencyDomainOperations<S, T>,
183 <DspVec<S, T, N, D> as ToRealTimeResult>::RealTimeResult:
184 RededicateForceOps<DspVec<S, T, N, D>> + TimeDomainOperations<S, T>,
185 S: ToSliceMut<T>,
186 T: RealNumber,
187 N: ComplexNumberSpace,
188 D: FrequencyDomain,
189{
190 fn plain_sifft<B>(mut self, buffer: &mut B) -> TransRes<Self::RealTimeResult>
191 where
192 B: for<'a> Buffer<'a, S, T>,
193 {
194 if self.domain() != DataDomain::Frequency || !self.is_complex() {
195 self.mark_vector_as_invalid();
196 self.number_space.to_complex();
197 self.domain.to_freq();
198 return Err((
199 ErrorReason::InputMustBeInFrequencyDomain,
200 Self::RealTimeResult::rededicate_from_force(self),
201 ));
202 }
203
204 if self.points() > 0 && self.data(1).abs() > T::from(1e-10).unwrap() {
205 self.mark_vector_as_invalid();
206 self.number_space.to_complex();
207 self.domain.to_freq();
208 return Err((
209 ErrorReason::InputMustBeConjSymmetric,
210 Self::RealTimeResult::rededicate_from_force(self),
211 ));
212 }
213
214 self.mirror(buffer);
215
216 fft(&mut self, buffer, FftDirection::Inverse);
217
218 self.domain.to_freq();
219 self.pure_complex_to_real_operation(buffer, |x, _arg| x.re, (), Complexity::Small);
220 Ok(Self::RealTimeResult::rededicate_from_force(self))
221 }
222
223 fn sifft<B>(mut self, buffer: &mut B) -> TransRes<Self::RealTimeResult>
224 where
225 B: for<'a> Buffer<'a, S, T>,
226 {
227 let points = self.points();
228 self.scale(Complex::<T>::new(
229 T::one() / T::from(points).unwrap(),
230 T::zero(),
231 ));
232 self.ifft_shift();
233 self.plain_sifft(buffer)
234 }
235
236 fn windowed_sifft<B>(
237 self,
238 buffer: &mut B,
239 window: &dyn WindowFunction<T>,
240 ) -> TransRes<Self::RealTimeResult>
241 where
242 B: for<'a> Buffer<'a, S, T>,
243 {
244 let mut result = self.sifft(buffer)?;
245 result.unapply_window(window);
246 Ok(result)
247 }
248}