C++实现裸音频数据的FFT变换

【C++实现裸音频数据的FFT变换】莫道桑榆晚,为霞尚满天。这篇文章主要讲述C++实现裸音频数据的FFT变换相关的知识,希望能为你提供帮助。

#include "waveconvertor.h"

//
// class CWaveConvertor

/* Pjotr 87.*/
// As best as I can determine this is in the public domain. No license was found
// withit what so ever. The author is listed as:
// Peter Valkenburg (valke@cs.vu.nl).
//
// If there is some disagreement then contact Bruce Forsberg (forsberg@tns.net)
#include < math.h>

#define pi3.1415926535897932384626434

#definec_re(c)((c).re)
#definec_im(c)((c).im)

/* C_add_mul adds product of c1 and c2 to c.*/
#define c_add_mul(c, c1, c2)COMPLEX C1, C2; C1 = (c1); C2 = (c2); \\
c_re (c) += C1.re * C2.re - C1.im * C2.im; \\
c_im (c) += C1.re * C2.im + C1.im * C2.re;

/* C_conj substitutes c by its complex conjugate. */
#define c_conj(c)c_im (c) = -c_im (c);

/* C_realdiv divides complex c by real.*/
#define c_realdiv(c, real)c_re (c) /= (real); c_im (c) /= (real);

/*
* W gives the (already computed) Wn ^ k (= e ^ (2pi * i * k / n)).
* Notice that the powerseries of Wn has period Nfactors.
*/
#define W(n, k)(W_factors [((k) * (Nfactors / (n))) % Nfactors])



/*! \\brief Constructor.
*/
aflibFFT::aflibFFT()

Nfactors = 0;
W_factors = NULL;



/*! \\brief Destructor.
*/
aflibFFT::~aflibFFT()

if (W_factors != NULL)
delete W_factors;



/*! \\brief Performs a forward or reverse FFT.

This is the main API is this class. It will perform either a forward or
inverse FFT depending how InverseTransform is set. If set to FALSE then
forward FFT will be performed, TRUE and a inverse FFT will be performed.
The number of samlpes (NumSamples) must be a power of 2. The ImagIn
pointer can be NULL if there are no imaginary values. The user is
responsable for passing in pointers for RealOut and ImagOut containing
arrays of the proper size.
*/
void
aflibFFT::fft_double (
unsignedNumSamples,
intInverseTransform,
const double*RealIn,
const double*ImagIn,
double*RealOut,
double*ImagOut )


COMPLEXin[1024];
COMPLEXout[1024];
COMPLEX* in_local = NULL;
COMPLEX* out_local = NULL;
register COMPLEX* in_ptr;
register COMPLEX* out_ptr;
register unsigned inti;


// IF 1024 samples or less use local buffer else allocate memory
if (NumSamples > 1024)

in_local = new COMPLEX[NumSamples];
out_local = new COMPLEX[NumSamples];
in_ptr = in_local;
out_ptr = out_local;

else

in_ptr = in;
out_ptr = out;


// Fill real and imaginary array
for (i = 0; i < NumSamples; i++)

c_re(in_ptr[i]) = RealIn[i];
if (ImagIn == NULL)
c_im(in_ptr[i]) = 0.0;
else
c_im(in_ptr[i]) = ImagIn[i];


// Perform transform
if (InverseTransform == TRUE)

rft(in_ptr, NumSamples, out_ptr);

else

fft(in_ptr, NumSamples, out_ptr);


// Fill real and imaginary array
for (i = 0; i < NumSamples; i++)

RealOut[i] = c_re(out_ptr[i]);
ImagOut[i] = c_im(out_ptr[i]);


// Free memory if local arrays were not used
if (in_local != NULL)
delete [] in_local;
if (out_local != NULL)
delete [] out_local;



/*
* Forward Fast Fourier Transform on the n samples of complex array in.
* The result is placed in out.The number of samples, n, is arbitrary.
* The W-factors are calculated in advance.
*/
int
aflibFFT::fft (
COMPLEX *in,
unsignedn,
COMPLEX *out)

unsigned i;

for (i = 0; i < n; i++)
c_conj (in [i]);

if (W_init (n) == -1)
return -1;

Fourier (in, n, out);

for (i = 0; i < n; i++)
c_conj (out [i]);
c_realdiv (out [i], n);


return 0;



/*
* Reverse Fast Fourier Transform on the n complex samples of array in.
* The result is placed in out.The number of samples, n, is arbitrary.
* The W-factors are calculated in advance.
*/
int
aflibFFT::rft (
COMPLEX *in,
unsignedn,
COMPLEX *out)

if (W_init (n) == -1)
return -1;

Fourier (in, n, out);

return 0;



/*
* Recursive (reverse) complex fast Fourier transform on the n
* complex samples of array in, with the Cooley-Tukey method.
* The result is placed in out.The number of samples, n, is arbitrary.
* The algorithm costs O (n * (r1 + .. + rk)), where k is the number
* of factors in the prime-decomposition of n (also the maximum
* depth of the recursion), and ri is the i-th primefactor.
*/
void

    推荐阅读