Audacity 3.2.0
Classes | Typedefs | Functions
RealFFTf.h File Reference
#include "MemoryX.h"
Include dependency graph for RealFFTf.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  FFTParam
 
struct  FFTDeleter
 

Typedefs

using fft_type = float
 
using HFFT = std::unique_ptr< FFTParam, FFTDeleter >
 

Functions

FFT_API HFFT GetFFT (size_t)
 
FFT_API void RealFFTf (fft_type *, const FFTParam *)
 
FFT_API void InverseRealFFTf (fft_type *, const FFTParam *)
 
FFT_API void ReorderToTime (const FFTParam *hFFT, const fft_type *buffer, fft_type *TimeOut)
 
FFT_API void ReorderToFreq (const FFTParam *hFFT, const fft_type *buffer, fft_type *RealOut, fft_type *ImagOut)
 

Typedef Documentation

◆ fft_type

using fft_type = float

Definition at line 6 of file RealFFTf.h.

◆ HFFT

using HFFT = std::unique_ptr< FFTParam, FFTDeleter >

Definition at line 20 of file RealFFTf.h.

Function Documentation

◆ GetFFT()

FFT_API HFFT GetFFT ( size_t  fftlen)

Definition at line 104 of file RealFFTf.cpp.

105{
106 // To do: smarter policy about when to retain in the pool and when to
107 // allocate a unique instance.
108
109 wxCriticalSectionLocker locker{ getFFTMutex };
110
111 size_t h = 0;
112 auto n = fftlen/2;
113 auto size = hFFTArray.size();
114 for(;
115 (h < size) && hFFTArray[h] && (n != hFFTArray[h]->Points);
116 h++)
117 ;
118 if(h < size) {
119 if(hFFTArray[h] == NULL) {
120 hFFTArray[h].reset( InitializeFFT(fftlen).release() );
121 }
122 return HFFT{ hFFTArray[h].get() };
123 } else {
124 // All buffers used, so fall back to allocating a NEW set of tables
125 return InitializeFFT(fftlen);
126 }
127}
static std::vector< std::unique_ptr< FFTParam > > hFFTArray(MAX_HFFT)
HFFT InitializeFFT(size_t fftlen)
Definition: RealFFTf.cpp:55
wxCriticalSection getFFTMutex
Definition: RealFFTf.cpp:100
std::unique_ptr< FFTParam, FFTDeleter > HFFT
Definition: RealFFTf.h:22

References getFFTMutex, hFFTArray(), InitializeFFT(), and size.

Referenced by SpectrogramSettings::CacheWindows(), InverseRealFFT(), PowerSpectrum(), and RealFFT().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ InverseRealFFTf()

FFT_API void InverseRealFFTf ( fft_type buffer,
const FFTParam h 
)

Definition at line 263 of file RealFFTf.cpp.

264{
265 fft_type *A,*B;
266 const fft_type *sptr;
267 const fft_type *endptr1,*endptr2;
268 const int *br1;
269 fft_type HRplus,HRminus,HIplus,HIminus;
270 fft_type v1,v2,sin,cos;
271
272 auto ButterfliesPerGroup = h->Points / 2;
273
274 /* Massage input to get the input for a real output sequence. */
275 A = buffer + 2;
276 B = buffer + h->Points * 2 - 2;
277 br1 = h->BitReversed.get() + 1;
278 while(A<B)
279 {
280 sin=h->SinTable[*br1];
281 cos=h->SinTable[*br1+1];
282 HRplus = (HRminus = *A - *B ) + (*B * 2);
283 HIplus = (HIminus = *(A+1) - *(B+1)) + (*(B+1) * 2);
284 v1 = (sin*HRminus + cos*HIplus);
285 v2 = (cos*HRminus - sin*HIplus);
286 *A = (HRplus + v1) * (fft_type)0.5;
287 *B = *A - v1;
288 *(A+1) = (HIminus - v2) * (fft_type)0.5;
289 *(B+1) = *(A+1) - HIminus;
290
291 A+=2;
292 B-=2;
293 br1++;
294 }
295 /* Handle center bin (just need conjugate) */
296 *(A+1)=-*(A+1);
297 /* Handle DC bin separately - this ignores any Fs/2 component
298 buffer[1]=buffer[0]=buffer[0]/2;*/
299 /* Handle DC and Fs/2 bins specially */
300 /* The DC bin is passed in as the real part of the DC complex value */
301 /* The Fs/2 bin is passed in as the imaginary part of the DC complex value */
302 /* (v1+v2) = buffer[0] == the DC component */
303 /* (v1-v2) = buffer[1] == the Fs/2 component */
304 v1=0.5f*(buffer[0]+buffer[1]);
305 v2=0.5f*(buffer[0]-buffer[1]);
306 buffer[0]=v1;
307 buffer[1]=v2;
308
309 /*
310 * Butterfly:
311 * Ain-----Aout
312 * \ /
313 * / \
314 * Bin-----Bout
315 */
316
317 endptr1 = buffer + h->Points * 2;
318
319 while(ButterfliesPerGroup > 0)
320 {
321 A = buffer;
322 B = buffer + ButterfliesPerGroup * 2;
323 sptr = h->SinTable.get();
324
325 while(A < endptr1)
326 {
327 sin = *(sptr++);
328 cos = *(sptr++);
329 endptr2 = B;
330 while(A < endptr2)
331 {
332 v1 = *B * cos - *(B + 1) * sin;
333 v2 = *B * sin + *(B + 1) * cos;
334 *B = (*A + v1) * (fft_type)0.5;
335 *(A++) = *(B++) - v1;
336 *B = (*A + v2) * (fft_type)0.5;
337 *(A++) = *(B++) - v2;
338 }
339 A = B;
340 B += ButterfliesPerGroup * 2;
341 }
342 ButterfliesPerGroup >>= 1;
343 }
344}
float fft_type
Definition: RealFFTf48x.h:6
#define A(N)
Definition: ToChars.cpp:62
size_t Points
Definition: RealFFTf.h:10
ArrayOf< int > BitReversed
Definition: RealFFTf.h:8
ArrayOf< fft_type > SinTable
Definition: RealFFTf.h:9

References A, FFTParam::BitReversed, FFTParam::Points, and FFTParam::SinTable.

Referenced by EqualizationFilter::Filter(), InverseRealFFT(), and SpectrumTransformer::OutputStep().

Here is the caller graph for this function:

◆ RealFFTf()

FFT_API void RealFFTf ( fft_type buffer,
const FFTParam h 
)

Definition at line 161 of file RealFFTf.cpp.

162{
163 fft_type *A,*B;
164 const fft_type *sptr;
165 const fft_type *endptr1,*endptr2;
166 const int *br1,*br2;
167 fft_type HRplus,HRminus,HIplus,HIminus;
168 fft_type v1,v2,sin,cos;
169
170 auto ButterfliesPerGroup = h->Points/2;
171
172 /*
173 * Butterfly:
174 * Ain-----Aout
175 * \ /
176 * / \
177 * Bin-----Bout
178 */
179
180 endptr1 = buffer + h->Points * 2;
181
182 while(ButterfliesPerGroup > 0)
183 {
184 A = buffer;
185 B = buffer + ButterfliesPerGroup * 2;
186 sptr = h->SinTable.get();
187
188 while(A < endptr1)
189 {
190 sin = *sptr;
191 cos = *(sptr+1);
192 endptr2 = B;
193 while(A < endptr2)
194 {
195 v1 = *B * cos + *(B + 1) * sin;
196 v2 = *B * sin - *(B + 1) * cos;
197 *B = (*A + v1);
198 *(A++) = *(B++) - 2 * v1;
199 *B = (*A - v2);
200 *(A++) = *(B++) + 2 * v2;
201 }
202 A = B;
203 B += ButterfliesPerGroup * 2;
204 sptr += 2;
205 }
206 ButterfliesPerGroup >>= 1;
207 }
208 /* Massage output to get the output for a real input sequence. */
209 br1 = h->BitReversed.get() + 1;
210 br2 = h->BitReversed.get() + h->Points - 1;
211
212 while(br1<br2)
213 {
214 sin=h->SinTable[*br1];
215 cos=h->SinTable[*br1+1];
216 A=buffer+*br1;
217 B=buffer+*br2;
218 HRplus = (HRminus = *A - *B ) + (*B * 2);
219 HIplus = (HIminus = *(A+1) - *(B+1)) + (*(B+1) * 2);
220 v1 = (sin*HRminus - cos*HIplus);
221 v2 = (cos*HRminus + sin*HIplus);
222 *A = (HRplus + v1) * (fft_type)0.5;
223 *B = *A - v1;
224 *(A+1) = (HIminus + v2) * (fft_type)0.5;
225 *(B+1) = *(A+1) - HIminus;
226
227 br1++;
228 br2--;
229 }
230 /* Handle the center bin (just need a conjugate) */
231 A=buffer+*br1+1;
232 *A=-*A;
233 /* Handle DC bin separately - and ignore the Fs/2 bin
234 buffer[0]+=buffer[1];
235 buffer[1]=(fft_type)0;*/
236 /* Handle DC and Fs/2 bins separately */
237 /* Put the Fs/2 value into the imaginary part of the DC bin */
238 v1=buffer[0]-buffer[1];
239 buffer[0]+=buffer[1];
240 buffer[1]=v1;
241}

References A, FFTParam::BitReversed, FFTParam::Points, and FFTParam::SinTable.

Referenced by SpecCache::CalculateOneSpectrum(), anonymous_namespace{SpectrumCache.cpp}::ComputeSpectrumUsingRealFFTf(), SpectrumTransformer::FillFirstWindow(), EqualizationFilter::Filter(), PowerSpectrum(), and RealFFT().

Here is the caller graph for this function:

◆ ReorderToFreq()

FFT_API void ReorderToFreq ( const FFTParam hFFT,
const fft_type buffer,
fft_type RealOut,
fft_type ImagOut 
)

Definition at line 346 of file RealFFTf.cpp.

348{
349 // Copy the data into the real and imaginary outputs
350 for(size_t i = 1; i < hFFT->Points; i++) {
351 RealOut[i] = buffer[hFFT->BitReversed[i] ];
352 ImagOut[i] = buffer[hFFT->BitReversed[i]+1];
353 }
354 RealOut[0] = buffer[0]; // DC component
355 ImagOut[0] = 0;
356 RealOut[hFFT->Points] = buffer[1]; // Fs/2 component
357 ImagOut[hFFT->Points] = 0;
358}

References FFTParam::BitReversed, and FFTParam::Points.

◆ ReorderToTime()

FFT_API void ReorderToTime ( const FFTParam hFFT,
const fft_type buffer,
fft_type TimeOut 
)

Definition at line 360 of file RealFFTf.cpp.

361{
362 // Copy the data into the real outputs
363 for(size_t i = 0; i < hFFT->Points; i++) {
364 TimeOut[i*2 ]=buffer[hFFT->BitReversed[i] ];
365 TimeOut[i*2+1]=buffer[hFFT->BitReversed[i]+1];
366 }
367}

References FFTParam::BitReversed, and FFTParam::Points.

Referenced by EqualizationFilter::Filter(), and InverseRealFFT().

Here is the caller graph for this function: