Audacity  2.3.1
Classes | Typedefs | Functions
RealFFTf.h File Reference
#include "Audacity.h"
#include "Experimental.h"
#include "MemoryX.h"

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

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

Typedef Documentation

using fft_type = float

Definition at line 8 of file RealFFTf.h.

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

Definition at line 24 of file RealFFTf.h.

Function Documentation

HFFT GetFFT ( size_t  )

Definition at line 110 of file RealFFTf.cpp.

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

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

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

Definition at line 269 of file RealFFTf.cpp.

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

Referenced by EffectEqualization::Filter(), InverseRealFFT(), and EffectNoiseReduction::Worker::ReduceNoise().

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

Definition at line 167 of file RealFFTf.cpp.

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

Referenced by SpecCache::CalculateOneSpectrum(), ComputeSpectrumUsingRealFFTf(), EffectNoiseReduction::Worker::FillFirstHistoryWindow(), EffectEqualization::Filter(), PowerSpectrum(), and RealFFT().

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

Definition at line 352 of file RealFFTf.cpp.

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

354 {
355  // Copy the data into the real and imaginary outputs
356  for(size_t i = 1; i < hFFT->Points; i++) {
357  RealOut[i] = buffer[hFFT->BitReversed[i] ];
358  ImagOut[i] = buffer[hFFT->BitReversed[i]+1];
359  }
360  RealOut[0] = buffer[0]; // DC component
361  ImagOut[0] = 0;
362  RealOut[hFFT->Points] = buffer[1]; // Fs/2 component
363  ImagOut[hFFT->Points] = 0;
364 }
size_t Points
Definition: RealFFTf.h:12
ArrayOf< int > BitReversed
Definition: RealFFTf.h:10
void ReorderToTime ( const FFTParam hFFT,
const fft_type buffer,
fft_type TimeOut 
)

Definition at line 366 of file RealFFTf.cpp.

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

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

367 {
368  // Copy the data into the real outputs
369  for(size_t i = 0; i < hFFT->Points; i++) {
370  TimeOut[i*2 ]=buffer[hFFT->BitReversed[i] ];
371  TimeOut[i*2+1]=buffer[hFFT->BitReversed[i]+1];
372  }
373 }
size_t Points
Definition: RealFFTf.h:12
ArrayOf< int > BitReversed
Definition: RealFFTf.h:10