47#include <wx/wxcrtvararg.h>
74 wxFprintf(stderr,
"Error: FFT called with size %ld\n", PowerOfTwo);
79 while (PowerOfTwo > 1)
80 PowerOfTwo >>= 1, ++i;
89 for (i = rev = 0; i < NumBits; i++) {
90 rev = (rev << 1) | (index & 1);
105 for (
size_t i = 0; i < len; i++)
129void FFT(
size_t NumSamples,
130 bool InverseTransform,
131 const float *RealIn,
const float *ImagIn,
132 float *RealOut,
float *ImagOut)
134 double angle_numerator = 2.0 *
M_PI;
138 wxFprintf(stderr,
"%ld is not a power of two\n", NumSamples);
145 if (!InverseTransform)
146 angle_numerator = -angle_numerator;
155 for (
size_t i = 0; i < NumSamples; i++) {
157 RealOut[j] = RealIn[i];
158 ImagOut[j] = (ImagIn == NULL) ? 0.0 : ImagIn[i];
166 for (
size_t BlockSize = 2; BlockSize <= NumSamples; BlockSize <<= 1) {
168 double delta_angle = angle_numerator / (double) BlockSize;
170 double sm2 = sin(-2 * delta_angle);
171 double sm1 = sin(-delta_angle);
172 double cm2 = cos(-2 * delta_angle);
173 double cm1 = cos(-delta_angle);
175 double ar0, ar1, ar2, ai0, ai1, ai2;
177 for (
size_t i = 0; i < NumSamples; i += BlockSize) {
184 for (
size_t j = i, n = 0; n < BlockEnd; j++, n++) {
193 size_t k = j + BlockEnd;
194 tr = ar0 * RealOut[k] - ai0 * ImagOut[k];
195 ti = ar0 * ImagOut[k] + ai0 * RealOut[k];
197 RealOut[k] = RealOut[j] - tr;
198 ImagOut[k] = ImagOut[j] - ti;
205 BlockEnd = BlockSize;
212 if (InverseTransform) {
213 float denom = (float) NumSamples;
215 for (
size_t i = 0; i < NumSamples; i++) {
228void RealFFT(
size_t NumSamples,
const float *RealIn,
float *RealOut,
float *ImagOut)
230 auto hFFT =
GetFFT(NumSamples);
231 Floats pFFT{ NumSamples };
233 for(
size_t i = 0; i < NumSamples; i++)
240 for (
size_t i = 1; i<(NumSamples / 2); i++) {
241 RealOut[i]=pFFT[hFFT->BitReversed[i] ];
242 ImagOut[i]=pFFT[hFFT->BitReversed[i]+1];
245 RealOut[0] = pFFT[0];
246 RealOut[NumSamples / 2] = pFFT[1];
247 ImagOut[0] = ImagOut[NumSamples / 2] = 0;
249 for(
size_t i = NumSamples / 2 + 1; i < NumSamples; i++) {
250 RealOut[i] = RealOut[NumSamples-i];
251 ImagOut[i] = -ImagOut[NumSamples-i];
269 auto hFFT =
GetFFT(NumSamples);
270 Floats pFFT{ NumSamples };
272 for (
size_t i = 0; i < (NumSamples / 2); i++)
273 pFFT[2*i ] = RealIn[i];
275 for (
size_t i = 0; i < (NumSamples / 2); i++)
278 for (
size_t i = 0; i < (NumSamples / 2); i++)
279 pFFT[2*i+1] = ImagIn[i];
282 pFFT[1] = RealIn[NumSamples / 2];
304 auto hFFT =
GetFFT(NumSamples);
305 Floats pFFT{ NumSamples };
307 for (
size_t i = 0; i<NumSamples; i++)
314 for (
size_t i = 1; i<NumSamples / 2; i++) {
315 Out[i]= (pFFT[hFFT->BitReversed[i] ]*pFFT[hFFT->BitReversed[i] ])
316 + (pFFT[hFFT->BitReversed[i]+1]*pFFT[hFFT->BitReversed[i]+1]);
319 Out[0] = pFFT[0]*pFFT[0];
320 Out[NumSamples / 2] = pFFT[1]*pFFT[1];
334 switch (whichFunction) {
337 return XO(
"Rectangular");
340 return XO(
"Bartlett");
343 return XO(
"Hamming");
349 return XO(
"Blackman");
352 return XO(
"Blackman-Harris");
358 return XO(
"Gaussian(a=2.5)");
361 return XO(
"Gaussian(a=3.5)");
364 return XO(
"Gaussian(a=4.5)");
368void NewWindowFunc(
int whichFunction,
size_t NumSamplesIn,
bool extraSample,
float *in)
370 int NumSamples = (int)NumSamplesIn;
372 wxASSERT(NumSamples > 0);
375 wxASSERT(NumSamples > 0);
377 switch (whichFunction) {
379 wxFprintf(stderr,
"FFT::WindowFunc - Invalid window function: %d\n", whichFunction);
388 const int nPairs = (NumSamples - 1) / 2;
389 const float denom = NumSamples / 2.0f;
394 const float value = ii / denom;
396 in[NumSamples - ii] *= value;
405 const double multiplier = 2 *
M_PI / NumSamples;
406 static const double coeff0 = 0.54, coeff1 = -0.46;
407 for (
int ii = 0; ii < NumSamples; ++ii)
408 in[ii] *= coeff0 + coeff1 * cos(ii * multiplier);
414 const double multiplier = 2 *
M_PI / NumSamples;
415 static const double coeff0 = 0.5, coeff1 = -0.5;
416 for (
int ii = 0; ii < NumSamples; ++ii)
417 in[ii] *= coeff0 + coeff1 * cos(ii * multiplier);
423 const double multiplier = 2 *
M_PI / NumSamples;
424 const double multiplier2 = 2 * multiplier;
425 static const double coeff0 = 0.42, coeff1 = -0.5, coeff2 = 0.08;
426 for (
int ii = 0; ii < NumSamples; ++ii)
427 in[ii] *= coeff0 + coeff1 * cos(ii * multiplier) + coeff2 * cos(ii * multiplier2);
433 const double multiplier = 2 *
M_PI / NumSamples;
434 const double multiplier2 = 2 * multiplier;
435 const double multiplier3 = 3 * multiplier;
436 static const double coeff0 = 0.35875, coeff1 = -0.48829, coeff2 = 0.14128, coeff3 = -0.01168;
437 for (
int ii = 0; ii < NumSamples; ++ii)
438 in[ii] *= coeff0 + coeff1 * cos(ii * multiplier) + coeff2 * cos(ii * multiplier2) + coeff3 * cos(ii * multiplier3);
444 const float N = NumSamples;
445 for (
int ii = 0; ii < NumSamples; ++ii) {
446 const float iOverN = ii / N;
447 in[ii] *= 4 * iOverN * (1 - iOverN);
455 static const double A = -2 * 2.5*2.5;
456 const float N = NumSamples;
457 for (
int ii = 0; ii < NumSamples; ++ii) {
458 const float iOverN = ii / N;
462 in[ii] *= exp(
A * (0.25 + (iOverN * iOverN) - iOverN));
469 static const double A = -2 * 3.5*3.5;
470 const float N = NumSamples;
471 for (
int ii = 0; ii < NumSamples; ++ii) {
472 const float iOverN = ii / N;
473 in[ii] *= exp(
A * (0.25 + (iOverN * iOverN) - iOverN));
480 static const double A = -2 * 4.5*4.5;
481 const float N = NumSamples;
482 for (
int ii = 0; ii < NumSamples; ++ii) {
483 const float iOverN = ii / N;
484 in[ii] *= exp(
A * (0.25 + (iOverN * iOverN) - iOverN));
492 switch (whichFunction) {
497 value = exp(-2 * 2.5 * 2.5 * 0.25);
500 value = exp(-2 * 3.5 * 3.5 * 0.25);
503 value = exp(-2 * 4.5 * 4.5 * 0.25);
508 in[NumSamples] *= value;
513void WindowFunc(
int whichFunction,
size_t NumSamples,
float *in)
515 bool extraSample =
false;
516 switch (whichFunction)
542 wxASSERT(NumSamples > 0);
545 for (
int ii = 1; ii < (int)NumSamples; ++ii)
547 in[NumSamples] *= -1.0f;
552 wxASSERT(NumSamples > 0);
556 wxASSERT(NumSamples > 0);
559 switch (whichFunction) {
564 const int nPairs = (NumSamples - 1) / 2;
565 const float value = 2.0f / NumSamples;
573 in[NumSamples - ii] *= -value;
575 if (NumSamples % 2 == 0)
577 in[NumSamples / 2] = 0.0f;
585 in[NumSamples - 1] *= 0.5f;
592 const double multiplier = 2 *
M_PI / NumSamples;
593 static const double coeff0 = 0.54, coeff1 = -0.46 * multiplier;
599 for (
int ii = 0; ii < (int)NumSamples; ++ii)
600 in[ii] *= - coeff1 * sin(ii * multiplier);
602 in[NumSamples] *= - coeff0;
605 in[NumSamples] *= - coeff0 - coeff1 * sin(NumSamples * multiplier);
611 const double multiplier = 2 *
M_PI / NumSamples;
612 const double coeff1 = -0.5 * multiplier;
613 for (
int ii = 0; ii < (int)NumSamples; ++ii)
614 in[ii] *= - coeff1 * sin(ii * multiplier);
616 in[NumSamples] = 0.0f;
622 const double multiplier = 2 *
M_PI / NumSamples;
623 const double multiplier2 = 2 * multiplier;
624 const double coeff1 = -0.5 * multiplier, coeff2 = 0.08 * multiplier2;
625 for (
int ii = 0; ii < (int)NumSamples; ++ii)
626 in[ii] *= - coeff1 * sin(ii * multiplier) - coeff2 * sin(ii * multiplier2);
628 in[NumSamples] = 0.0f;
634 const double multiplier = 2 *
M_PI / NumSamples;
635 const double multiplier2 = 2 * multiplier;
636 const double multiplier3 = 3 * multiplier;
637 const double coeff1 = -0.48829 * multiplier,
638 coeff2 = 0.14128 * multiplier2, coeff3 = -0.01168 * multiplier3;
639 for (
int ii = 0; ii < (int)NumSamples; ++ii)
640 in[ii] *= - coeff1 * sin(ii * multiplier) - coeff2 * sin(ii * multiplier2) - coeff3 * sin(ii * multiplier3);
642 in[NumSamples] = 0.0f;
648 const float N = NumSamples;
649 const float NN = NumSamples * NumSamples;
650 for (
int ii = 0; ii < (int)NumSamples; ++ii) {
651 in[ii] *= 4 * (N - ii - ii) / NN;
654 in[NumSamples] = 0.0f;
657 in[NumSamples - 1] /= 2.0f;
676 const float invN = 1.0f / NumSamples;
677 const float invNN = invN * invN;
679 in[0] *= exp(
A * 0.25) * (1 - invN);
682 for (
int ii = 1; ii < (int)NumSamples; ++ii) {
683 const float iOverN = ii * invN;
684 in[ii] *= exp(
A * (0.25 + (iOverN * iOverN) - iOverN)) * (2 * ii * invNN - invN);
687 in[NumSamples] *= exp(
A * 0.25) * (invN - 1);
690 const float iOverN = NumSamples * invN;
691 in[NumSamples] *= exp(
A * (0.25 + (iOverN * iOverN) - iOverN)) * (2 * NumSamples * invNN - invN - 1);
696 wxFprintf(stderr,
"FFT::DerivativeOfWindowFunc - Invalid window function: %d\n", whichFunction);
void NewWindowFunc(int whichFunction, size_t NumSamplesIn, bool extraSample, float *in)
static bool IsPowerOfTwo(size_t x)
static const size_t MaxFastBits
void DerivativeOfWindowFunc(int whichFunction, size_t NumSamples, bool extraSample, float *in)
int ReverseBits(size_t index, size_t NumBits)
static size_t NumberOfBitsNeeded(size_t PowerOfTwo)
void WindowFunc(int whichFunction, size_t NumSamples, float *in)
void PowerSpectrum(size_t NumSamples, const float *In, float *Out)
static ArraysOf< int > gFFTBitTable
const TranslatableString WindowFuncName(int whichFunction)
void InverseRealFFT(size_t NumSamples, const float *RealIn, const float *ImagIn, float *RealOut)
void RealFFT(size_t NumSamples, const float *RealIn, float *RealOut, float *ImagOut)
void FFT(size_t NumSamples, bool InverseTransform, const float *RealIn, const float *ImagIn, float *RealOut, float *ImagOut)
static size_t FastReverseBits(size_t i, size_t NumBits)
void RealFFTf(fft_type *buffer, const FFTParam *h)
void InverseRealFFTf(fft_type *buffer, const FFTParam *h)
void ReorderToTime(const FFTParam *hFFT, const fft_type *buffer, fft_type *TimeOut)
HFFT GetFFT(size_t fftlen)
Holds a msgid for the translation catalog; may also bind format arguments.