Audacity  3.0.3
FFT.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  FFT.cpp
4 
5  Dominic Mazzoni
6 
7  September 2000
8 
9 *******************************************************************//*******************************************************************/
31 /*
32  Salvo Ventura - November 2006
33  Added more window functions:
34  * 4: Blackman
35  * 5: Blackman-Harris
36  * 6: Welch
37  * 7: Gaussian(a=2.5)
38  * 8: Gaussian(a=3.5)
39  * 9: Gaussian(a=4.5)
40 */
41 
42 #include "FFT.h"
43 
44 #include "Internat.h"
45 
46 #include "SampleFormat.h"
47 
48 #include <wx/wxcrtvararg.h>
49 #include <wx/intl.h>
50 #include <stdlib.h>
51 #include <stdio.h>
52 #include <math.h>
53 
54 #include "RealFFTf.h"
55 
57 static const size_t MaxFastBits = 16;
58 
59 /* Declare Static functions */
60 static void InitFFT();
61 
62 static bool IsPowerOfTwo(size_t x)
63 {
64  if (x < 2)
65  return false;
66 
67  if (x & (x - 1)) /* Thanks to 'byang' for this cute trick! */
68  return false;
69 
70  return true;
71 }
72 
73 static size_t NumberOfBitsNeeded(size_t PowerOfTwo)
74 {
75  if (PowerOfTwo < 2) {
76  wxFprintf(stderr, "Error: FFT called with size %ld\n", PowerOfTwo);
77  exit(1);
78  }
79 
80  size_t i = 0;
81  while (PowerOfTwo > 1)
82  PowerOfTwo >>= 1, ++i;
83 
84  return i;
85 }
86 
87 int ReverseBits(size_t index, size_t NumBits)
88 {
89  size_t i, rev;
90 
91  for (i = rev = 0; i < NumBits; i++) {
92  rev = (rev << 1) | (index & 1);
93  index >>= 1;
94  }
95 
96  return rev;
97 }
98 
99 void InitFFT()
100 {
101  gFFTBitTable.reinit(MaxFastBits);
102 
103  size_t len = 2;
104  for (size_t b = 1; b <= MaxFastBits; b++) {
105  auto &array = gFFTBitTable[b - 1];
106  array.reinit(len);
107  for (size_t i = 0; i < len; i++)
108  array[i] = ReverseBits(i, b);
109 
110  len <<= 1;
111  }
112 }
113 
114 void DeinitFFT()
115 {
116  gFFTBitTable.reset();
117 }
118 
119 static inline size_t FastReverseBits(size_t i, size_t NumBits)
120 {
121  if (NumBits <= MaxFastBits)
122  return gFFTBitTable[NumBits - 1][i];
123  else
124  return ReverseBits(i, NumBits);
125 }
126 
127 /*
128  * Complex Fast Fourier Transform
129  */
130 
131 void FFT(size_t NumSamples,
132  bool InverseTransform,
133  const float *RealIn, const float *ImagIn,
134  float *RealOut, float *ImagOut)
135 {
136  double angle_numerator = 2.0 * M_PI;
137  double tr, ti; /* temp real, temp imaginary */
138 
139  if (!IsPowerOfTwo(NumSamples)) {
140  wxFprintf(stderr, "%ld is not a power of two\n", NumSamples);
141  exit(1);
142  }
143 
144  if (!gFFTBitTable)
145  InitFFT();
146 
147  if (!InverseTransform)
148  angle_numerator = -angle_numerator;
149 
150  /* Number of bits needed to store indices */
151  auto NumBits = NumberOfBitsNeeded(NumSamples);
152 
153  /*
154  ** Do simultaneous data copy and bit-reversal ordering into outputs...
155  */
156 
157  for (size_t i = 0; i < NumSamples; i++) {
158  auto j = FastReverseBits(i, NumBits);
159  RealOut[j] = RealIn[i];
160  ImagOut[j] = (ImagIn == NULL) ? 0.0 : ImagIn[i];
161  }
162 
163  /*
164  ** Do the FFT itself...
165  */
166 
167  size_t BlockEnd = 1;
168  for (size_t BlockSize = 2; BlockSize <= NumSamples; BlockSize <<= 1) {
169 
170  double delta_angle = angle_numerator / (double) BlockSize;
171 
172  double sm2 = sin(-2 * delta_angle);
173  double sm1 = sin(-delta_angle);
174  double cm2 = cos(-2 * delta_angle);
175  double cm1 = cos(-delta_angle);
176  double w = 2 * cm1;
177  double ar0, ar1, ar2, ai0, ai1, ai2;
178 
179  for (size_t i = 0; i < NumSamples; i += BlockSize) {
180  ar2 = cm2;
181  ar1 = cm1;
182 
183  ai2 = sm2;
184  ai1 = sm1;
185 
186  for (size_t j = i, n = 0; n < BlockEnd; j++, n++) {
187  ar0 = w * ar1 - ar2;
188  ar2 = ar1;
189  ar1 = ar0;
190 
191  ai0 = w * ai1 - ai2;
192  ai2 = ai1;
193  ai1 = ai0;
194 
195  size_t k = j + BlockEnd;
196  tr = ar0 * RealOut[k] - ai0 * ImagOut[k];
197  ti = ar0 * ImagOut[k] + ai0 * RealOut[k];
198 
199  RealOut[k] = RealOut[j] - tr;
200  ImagOut[k] = ImagOut[j] - ti;
201 
202  RealOut[j] += tr;
203  ImagOut[j] += ti;
204  }
205  }
206 
207  BlockEnd = BlockSize;
208  }
209 
210  /*
211  ** Need to normalize if inverse transform...
212  */
213 
214  if (InverseTransform) {
215  float denom = (float) NumSamples;
216 
217  for (size_t i = 0; i < NumSamples; i++) {
218  RealOut[i] /= denom;
219  ImagOut[i] /= denom;
220  }
221  }
222 }
223 
224 /*
225  * Real Fast Fourier Transform
226  *
227  * This is merely a wrapper of RealFFTf() from RealFFTf.h.
228  */
229 
230 void RealFFT(size_t NumSamples, const float *RealIn, float *RealOut, float *ImagOut)
231 {
232  auto hFFT = GetFFT(NumSamples);
233  Floats pFFT{ NumSamples };
234  // Copy the data into the processing buffer
235  for(size_t i = 0; i < NumSamples; i++)
236  pFFT[i] = RealIn[i];
237 
238  // Perform the FFT
239  RealFFTf(pFFT.get(), hFFT.get());
240 
241  // Copy the data into the real and imaginary outputs
242  for (size_t i = 1; i<(NumSamples / 2); i++) {
243  RealOut[i]=pFFT[hFFT->BitReversed[i] ];
244  ImagOut[i]=pFFT[hFFT->BitReversed[i]+1];
245  }
246  // Handle the (real-only) DC and Fs/2 bins
247  RealOut[0] = pFFT[0];
248  RealOut[NumSamples / 2] = pFFT[1];
249  ImagOut[0] = ImagOut[NumSamples / 2] = 0;
250  // Fill in the upper half using symmetry properties
251  for(size_t i = NumSamples / 2 + 1; i < NumSamples; i++) {
252  RealOut[i] = RealOut[NumSamples-i];
253  ImagOut[i] = -ImagOut[NumSamples-i];
254  }
255 }
256 
257 /*
258  * InverseRealFFT
259  *
260  * This function computes the inverse of RealFFT, above.
261  * The RealIn and ImagIn is assumed to be conjugate-symmetric
262  * and as a result the output is purely real.
263  * Only the first half of RealIn and ImagIn are used due to this
264  * symmetry assumption.
265  *
266  * This is merely a wrapper of InverseRealFFTf() from RealFFTf.h.
267  */
268 void InverseRealFFT(size_t NumSamples, const float *RealIn, const float *ImagIn,
269  float *RealOut)
270 {
271  auto hFFT = GetFFT(NumSamples);
272  Floats pFFT{ NumSamples };
273  // Copy the data into the processing buffer
274  for (size_t i = 0; i < (NumSamples / 2); i++)
275  pFFT[2*i ] = RealIn[i];
276  if(ImagIn == NULL) {
277  for (size_t i = 0; i < (NumSamples / 2); i++)
278  pFFT[2*i+1] = 0;
279  } else {
280  for (size_t i = 0; i < (NumSamples / 2); i++)
281  pFFT[2*i+1] = ImagIn[i];
282  }
283  // Put the fs/2 component in the imaginary part of the DC bin
284  pFFT[1] = RealIn[NumSamples / 2];
285 
286  // Perform the FFT
287  InverseRealFFTf(pFFT.get(), hFFT.get());
288 
289  // Copy the data to the (purely real) output buffer
290  ReorderToTime(hFFT.get(), pFFT.get(), RealOut);
291 }
292 
293 /*
294  * PowerSpectrum
295  *
296  * This function uses RealFFTf() from RealFFTf.h to perform the real
297  * FFT computation, and then squares the real and imaginary part of
298  * each coefficient, extracting the power and throwing away the phase.
299  *
300  * For speed, it does not call RealFFT, but duplicates some
301  * of its code.
302  */
303 
304 void PowerSpectrum(size_t NumSamples, const float *In, float *Out)
305 {
306  auto hFFT = GetFFT(NumSamples);
307  Floats pFFT{ NumSamples };
308  // Copy the data into the processing buffer
309  for (size_t i = 0; i<NumSamples; i++)
310  pFFT[i] = In[i];
311 
312  // Perform the FFT
313  RealFFTf(pFFT.get(), hFFT.get());
314 
315  // Copy the data into the real and imaginary outputs
316  for (size_t i = 1; i<NumSamples / 2; i++) {
317  Out[i]= (pFFT[hFFT->BitReversed[i] ]*pFFT[hFFT->BitReversed[i] ])
318  + (pFFT[hFFT->BitReversed[i]+1]*pFFT[hFFT->BitReversed[i]+1]);
319  }
320  // Handle the (real-only) DC and Fs/2 bins
321  Out[0] = pFFT[0]*pFFT[0];
322  Out[NumSamples / 2] = pFFT[1]*pFFT[1];
323 }
324 
325 /*
326  * Windowing Functions
327  */
328 
330 {
331  return eWinFuncCount;
332 }
333 
334 const TranslatableString WindowFuncName(int whichFunction)
335 {
336  switch (whichFunction) {
337  default:
338  case eWinFuncRectangular:
339  return XO("Rectangular");
340  case eWinFuncBartlett:
341  /* i18n-hint a proper name */
342  return XO("Bartlett");
343  case eWinFuncHamming:
344  /* i18n-hint a proper name */
345  return XO("Hamming");
346  case eWinFuncHann:
347  /* i18n-hint a proper name */
348  return XO("Hann");
349  case eWinFuncBlackman:
350  /* i18n-hint a proper name */
351  return XO("Blackman");
353  /* i18n-hint two proper names */
354  return XO("Blackman-Harris");
355  case eWinFuncWelch:
356  /* i18n-hint a proper name */
357  return XO("Welch");
358  case eWinFuncGaussian25:
359  /* i18n-hint a mathematical function named for C. F. Gauss */
360  return XO("Gaussian(a=2.5)");
361  case eWinFuncGaussian35:
362  /* i18n-hint a mathematical function named for C. F. Gauss */
363  return XO("Gaussian(a=3.5)");
364  case eWinFuncGaussian45:
365  /* i18n-hint a mathematical function named for C. F. Gauss */
366  return XO("Gaussian(a=4.5)");
367  }
368 }
369 
370 void NewWindowFunc(int whichFunction, size_t NumSamplesIn, bool extraSample, float *in)
371 {
372  int NumSamples = (int)NumSamplesIn;
373  if (extraSample) {
374  wxASSERT(NumSamples > 0);
375  --NumSamples;
376  }
377  wxASSERT(NumSamples > 0);
378 
379  switch (whichFunction) {
380  default:
381  wxFprintf(stderr, "FFT::WindowFunc - Invalid window function: %d\n", whichFunction);
382  break;
383  case eWinFuncRectangular:
384  // Multiply all by 1.0f -- do nothing
385  break;
386 
387  case eWinFuncBartlett:
388  {
389  // Bartlett (triangular) window
390  const int nPairs = (NumSamples - 1) / 2; // whether even or odd NumSamples, this is correct
391  const float denom = NumSamples / 2.0f;
392  in[0] = 0.0f;
393  for (int ii = 1;
394  ii <= nPairs; // Yes, <=
395  ++ii) {
396  const float value = ii / denom;
397  in[ii] *= value;
398  in[NumSamples - ii] *= value;
399  }
400  // When NumSamples is even, in[half] should be multiplied by 1.0, so unchanged
401  // When odd, the value of 1.0 is not reached
402  }
403  break;
404  case eWinFuncHamming:
405  {
406  // Hamming
407  const double multiplier = 2 * M_PI / NumSamples;
408  static const double coeff0 = 0.54, coeff1 = -0.46;
409  for (int ii = 0; ii < NumSamples; ++ii)
410  in[ii] *= coeff0 + coeff1 * cos(ii * multiplier);
411  }
412  break;
413  case eWinFuncHann:
414  {
415  // Hann
416  const double multiplier = 2 * M_PI / NumSamples;
417  static const double coeff0 = 0.5, coeff1 = -0.5;
418  for (int ii = 0; ii < NumSamples; ++ii)
419  in[ii] *= coeff0 + coeff1 * cos(ii * multiplier);
420  }
421  break;
422  case eWinFuncBlackman:
423  {
424  // Blackman
425  const double multiplier = 2 * M_PI / NumSamples;
426  const double multiplier2 = 2 * multiplier;
427  static const double coeff0 = 0.42, coeff1 = -0.5, coeff2 = 0.08;
428  for (int ii = 0; ii < NumSamples; ++ii)
429  in[ii] *= coeff0 + coeff1 * cos(ii * multiplier) + coeff2 * cos(ii * multiplier2);
430  }
431  break;
433  {
434  // Blackman-Harris
435  const double multiplier = 2 * M_PI / NumSamples;
436  const double multiplier2 = 2 * multiplier;
437  const double multiplier3 = 3 * multiplier;
438  static const double coeff0 = 0.35875, coeff1 = -0.48829, coeff2 = 0.14128, coeff3 = -0.01168;
439  for (int ii = 0; ii < NumSamples; ++ii)
440  in[ii] *= coeff0 + coeff1 * cos(ii * multiplier) + coeff2 * cos(ii * multiplier2) + coeff3 * cos(ii * multiplier3);
441  }
442  break;
443  case eWinFuncWelch:
444  {
445  // Welch
446  const float N = NumSamples;
447  for (int ii = 0; ii < NumSamples; ++ii) {
448  const float iOverN = ii / N;
449  in[ii] *= 4 * iOverN * (1 - iOverN);
450  }
451  }
452  break;
453  case eWinFuncGaussian25:
454  {
455  // Gaussian (a=2.5)
456  // Precalculate some values, and simplify the fmla to try and reduce overhead
457  static const double A = -2 * 2.5*2.5;
458  const float N = NumSamples;
459  for (int ii = 0; ii < NumSamples; ++ii) {
460  const float iOverN = ii / N;
461  // full
462  // in[ii] *= exp(-0.5*(A*((ii-NumSamples/2)/NumSamples/2))*(A*((ii-NumSamples/2)/NumSamples/2)));
463  // reduced
464  in[ii] *= exp(A * (0.25 + (iOverN * iOverN) - iOverN));
465  }
466  }
467  break;
468  case eWinFuncGaussian35:
469  {
470  // Gaussian (a=3.5)
471  static const double A = -2 * 3.5*3.5;
472  const float N = NumSamples;
473  for (int ii = 0; ii < NumSamples; ++ii) {
474  const float iOverN = ii / N;
475  in[ii] *= exp(A * (0.25 + (iOverN * iOverN) - iOverN));
476  }
477  }
478  break;
479  case eWinFuncGaussian45:
480  {
481  // Gaussian (a=4.5)
482  static const double A = -2 * 4.5*4.5;
483  const float N = NumSamples;
484  for (int ii = 0; ii < NumSamples; ++ii) {
485  const float iOverN = ii / N;
486  in[ii] *= exp(A * (0.25 + (iOverN * iOverN) - iOverN));
487  }
488  }
489  break;
490  }
491 
492  if (extraSample && whichFunction != eWinFuncRectangular) {
493  double value = 0.0;
494  switch (whichFunction) {
495  case eWinFuncHamming:
496  value = 0.08;
497  break;
498  case eWinFuncGaussian25:
499  value = exp(-2 * 2.5 * 2.5 * 0.25);
500  break;
501  case eWinFuncGaussian35:
502  value = exp(-2 * 3.5 * 3.5 * 0.25);
503  break;
504  case eWinFuncGaussian45:
505  value = exp(-2 * 4.5 * 4.5 * 0.25);
506  break;
507  default:
508  break;
509  }
510  in[NumSamples] *= value;
511  }
512 }
513 
514 // See cautions in FFT.h !
515 void WindowFunc(int whichFunction, size_t NumSamples, float *in)
516 {
517  bool extraSample = false;
518  switch (whichFunction)
519  {
520  case eWinFuncHamming:
521  case eWinFuncHann:
522  case eWinFuncBlackman:
524  extraSample = true;
525  break;
526  default:
527  break;
528  case eWinFuncBartlett:
529  // PRL: Do nothing here either
530  // But I want to comment that the old function did this case
531  // wrong in the second half of the array, in case NumSamples was odd
532  // but I think that never happened, so I am not bothering to preserve that
533  break;
534  }
535  NewWindowFunc(whichFunction, NumSamples, extraSample, in);
536 }
537 
538 void DerivativeOfWindowFunc(int whichFunction, size_t NumSamples, bool extraSample, float *in)
539 {
540  if (eWinFuncRectangular == whichFunction)
541  {
542  // Rectangular
543  // There are deltas at the ends
544  wxASSERT(NumSamples > 0);
545  --NumSamples;
546  // in[0] *= 1.0f;
547  for (int ii = 1; ii < (int)NumSamples; ++ii)
548  in[ii] = 0.0f;
549  in[NumSamples] *= -1.0f;
550  return;
551  }
552 
553  if (extraSample) {
554  wxASSERT(NumSamples > 0);
555  --NumSamples;
556  }
557 
558  wxASSERT(NumSamples > 0);
559 
560  double A;
561  switch (whichFunction) {
562  case eWinFuncBartlett:
563  {
564  // Bartlett (triangular) window
565  // There are discontinuities in the derivative at the ends, and maybe at the midpoint
566  const int nPairs = (NumSamples - 1) / 2; // whether even or odd NumSamples, this is correct
567  const float value = 2.0f / NumSamples;
568  in[0] *=
569  // Average the two limiting values of discontinuous derivative
570  value / 2.0f;
571  for (int ii = 1;
572  ii <= nPairs; // Yes, <=
573  ++ii) {
574  in[ii] *= value;
575  in[NumSamples - ii] *= -value;
576  }
577  if (NumSamples % 2 == 0)
578  // Average the two limiting values of discontinuous derivative
579  in[NumSamples / 2] = 0.0f;
580  if (extraSample)
581  in[NumSamples] *=
582  // Average the two limiting values of discontinuous derivative
583  -value / 2.0f;
584  else
585  // Halve the multiplier previously applied
586  // Average the two limiting values of discontinuous derivative
587  in[NumSamples - 1] *= 0.5f;
588  }
589  break;
590  case eWinFuncHamming:
591  {
592  // Hamming
593  // There are deltas at the ends
594  const double multiplier = 2 * M_PI / NumSamples;
595  static const double coeff0 = 0.54, coeff1 = -0.46 * multiplier;
596  // TODO This code should be more explicit about the precision it intends.
597  // For now we get C4305 warnings, truncation from 'const double' to 'float'
598  in[0] *= coeff0;
599  if (!extraSample)
600  --NumSamples;
601  for (int ii = 0; ii < (int)NumSamples; ++ii)
602  in[ii] *= - coeff1 * sin(ii * multiplier);
603  if (extraSample)
604  in[NumSamples] *= - coeff0;
605  else
606  // slightly different
607  in[NumSamples] *= - coeff0 - coeff1 * sin(NumSamples * multiplier);
608  }
609  break;
610  case eWinFuncHann:
611  {
612  // Hann
613  const double multiplier = 2 * M_PI / NumSamples;
614  const double coeff1 = -0.5 * multiplier;
615  for (int ii = 0; ii < (int)NumSamples; ++ii)
616  in[ii] *= - coeff1 * sin(ii * multiplier);
617  if (extraSample)
618  in[NumSamples] = 0.0f;
619  }
620  break;
621  case eWinFuncBlackman:
622  {
623  // Blackman
624  const double multiplier = 2 * M_PI / NumSamples;
625  const double multiplier2 = 2 * multiplier;
626  const double coeff1 = -0.5 * multiplier, coeff2 = 0.08 * multiplier2;
627  for (int ii = 0; ii < (int)NumSamples; ++ii)
628  in[ii] *= - coeff1 * sin(ii * multiplier) - coeff2 * sin(ii * multiplier2);
629  if (extraSample)
630  in[NumSamples] = 0.0f;
631  }
632  break;
634  {
635  // Blackman-Harris
636  const double multiplier = 2 * M_PI / NumSamples;
637  const double multiplier2 = 2 * multiplier;
638  const double multiplier3 = 3 * multiplier;
639  const double coeff1 = -0.48829 * multiplier,
640  coeff2 = 0.14128 * multiplier2, coeff3 = -0.01168 * multiplier3;
641  for (int ii = 0; ii < (int)NumSamples; ++ii)
642  in[ii] *= - coeff1 * sin(ii * multiplier) - coeff2 * sin(ii * multiplier2) - coeff3 * sin(ii * multiplier3);
643  if (extraSample)
644  in[NumSamples] = 0.0f;
645  }
646  break;
647  case eWinFuncWelch:
648  {
649  // Welch
650  const float N = NumSamples;
651  const float NN = NumSamples * NumSamples;
652  for (int ii = 0; ii < (int)NumSamples; ++ii) {
653  in[ii] *= 4 * (N - ii - ii) / NN;
654  }
655  if (extraSample)
656  in[NumSamples] = 0.0f;
657  // Average the two limiting values of discontinuous derivative
658  in[0] /= 2.0f;
659  in[NumSamples - 1] /= 2.0f;
660  }
661  break;
662  case eWinFuncGaussian25:
663  // Gaussian (a=2.5)
664  A = -2 * 2.5*2.5;
665  goto Gaussian;
666  case eWinFuncGaussian35:
667  // Gaussian (a=3.5)
668  A = -2 * 3.5*3.5;
669  goto Gaussian;
670  case eWinFuncGaussian45:
671  // Gaussian (a=4.5)
672  A = -2 * 4.5*4.5;
673  goto Gaussian;
674  Gaussian:
675  {
676  // Gaussian (a=2.5)
677  // There are deltas at the ends
678  const float invN = 1.0f / NumSamples;
679  const float invNN = invN * invN;
680  // Simplify formula from the loop for ii == 0, add term for the delta
681  in[0] *= exp(A * 0.25) * (1 - invN);
682  if (!extraSample)
683  --NumSamples;
684  for (int ii = 1; ii < (int)NumSamples; ++ii) {
685  const float iOverN = ii * invN;
686  in[ii] *= exp(A * (0.25 + (iOverN * iOverN) - iOverN)) * (2 * ii * invNN - invN);
687  }
688  if (extraSample)
689  in[NumSamples] *= exp(A * 0.25) * (invN - 1);
690  else {
691  // Slightly different
692  const float iOverN = NumSamples * invN;
693  in[NumSamples] *= exp(A * (0.25 + (iOverN * iOverN) - iOverN)) * (2 * NumSamples * invNN - invN - 1);
694  }
695  }
696  break;
697  default:
698  wxFprintf(stderr, "FFT::DerivativeOfWindowFunc - Invalid window function: %d\n", whichFunction);
699  }
700 }
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
WindowFunc
void WindowFunc(int whichFunction, size_t NumSamples, float *in)
Definition: FFT.cpp:515
eWinFuncGaussian25
@ eWinFuncGaussian25
Definition: FFT.h:118
PowerSpectrum
void PowerSpectrum(size_t NumSamples, const float *In, float *Out)
Definition: FFT.cpp:304
eWinFuncBlackman
@ eWinFuncBlackman
Definition: FFT.h:115
NumberOfBitsNeeded
static size_t NumberOfBitsNeeded(size_t PowerOfTwo)
Definition: FFT.cpp:73
eWinFuncRectangular
@ eWinFuncRectangular
Definition: FFT.h:111
RealFFTf
void RealFFTf(fft_type *buffer, const FFTParam *h)
Definition: RealFFTf.cpp:162
NumWindowFuncs
int NumWindowFuncs()
Definition: FFT.cpp:329
eWinFuncBlackmanHarris
@ eWinFuncBlackmanHarris
Definition: FFT.h:116
eWinFuncBartlett
@ eWinFuncBartlett
Definition: FFT.h:112
XO
#define XO(s)
Definition: Internat.h:31
RealFFTf.h
RealFFT
void RealFFT(size_t NumSamples, const float *RealIn, float *RealOut, float *ImagOut)
Definition: FFT.cpp:230
MaxFastBits
static const size_t MaxFastBits
Definition: FFT.cpp:57
ReorderToTime
void ReorderToTime(const FFTParam *hFFT, const fft_type *buffer, fft_type *TimeOut)
Definition: RealFFTf.cpp:361
eWinFuncHamming
@ eWinFuncHamming
Definition: FFT.h:113
FFT.h
FFT
void FFT(size_t NumSamples, bool InverseTransform, const float *RealIn, const float *ImagIn, float *RealOut, float *ImagOut)
Definition: FFT.cpp:131
ArraysOf
memory.h template class for making an array of arrays.
Definition: MemoryX.h:81
InverseRealFFT
void InverseRealFFT(size_t NumSamples, const float *RealIn, const float *ImagIn, float *RealOut)
Definition: FFT.cpp:268
gFFTBitTable
static ArraysOf< int > gFFTBitTable
Definition: FFT.cpp:56
eWinFuncHann
@ eWinFuncHann
Definition: FFT.h:114
InverseRealFFTf
void InverseRealFFTf(fft_type *buffer, const FFTParam *h)
Definition: RealFFTf.cpp:264
WindowFuncName
const TranslatableString WindowFuncName(int whichFunction)
Definition: FFT.cpp:334
ReverseBits
int ReverseBits(size_t index, size_t NumBits)
Definition: FFT.cpp:87
Internat.h
eWinFuncGaussian45
@ eWinFuncGaussian45
Definition: FFT.h:120
DerivativeOfWindowFunc
void DerivativeOfWindowFunc(int whichFunction, size_t NumSamples, bool extraSample, float *in)
Definition: FFT.cpp:538
eWinFuncWelch
@ eWinFuncWelch
Definition: FFT.h:117
NewWindowFunc
void NewWindowFunc(int whichFunction, size_t NumSamplesIn, bool extraSample, float *in)
Definition: FFT.cpp:370
IsPowerOfTwo
static bool IsPowerOfTwo(size_t x)
Definition: FFT.cpp:62
M_PI
#define M_PI
Definition: Distortion.cpp:29
GetFFT
HFFT GetFFT(size_t fftlen)
Definition: RealFFTf.cpp:105
eWinFuncGaussian35
@ eWinFuncGaussian35
Definition: FFT.h:119
DeinitFFT
void DeinitFFT()
Definition: FFT.cpp:114
InitFFT
static void InitFFT()
Definition: FFT.cpp:99
eWinFuncCount
@ eWinFuncCount
Definition: FFT.h:121
FastReverseBits
static size_t FastReverseBits(size_t i, size_t NumBits)
Definition: FFT.cpp:119
SampleFormat.h
ArrayOf< float >