Initial import
git-svn-id: http://moon:8086/svn/software/trunk/libsrc/cfft@1 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
@@ -0,0 +1,755 @@
|
||||
/***************************************************************************/
|
||||
/* FFT.CPP
|
||||
/* Fast-Fourier-Transformation
|
||||
/* Author: Jens Ahrensfeld
|
||||
/* Datum : 24.06.1999
|
||||
/* letzte Änderung: 09.06.2000
|
||||
/***************************************************************************/
|
||||
#include <math.h>
|
||||
#include <malloc.h>
|
||||
#include <memory.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "../../include/fft.h"
|
||||
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
|
||||
//#define FFTMsg
|
||||
|
||||
/***************************************************************************/
|
||||
/* Konstruktor FFT-Objekt */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
cfft::cfft(unsigned N)
|
||||
{
|
||||
if(BiPower(N) != 0)
|
||||
{
|
||||
printf("\n%u is not a power of 2!\n",N);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
m_numStages = (unsigned) (1e-06 + log((double)N)/log(2.0));
|
||||
m_numPoints = (unsigned int)N;
|
||||
|
||||
pTwiddleTbl = new COMPLEX[m_numPoints/2];
|
||||
if (!pTwiddleTbl)
|
||||
{
|
||||
printf("\nZu wenig Speicher !\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
FFTCalcTwiddleTable(pTwiddleTbl, m_numPoints);
|
||||
|
||||
#ifdef FFTMsg
|
||||
printf("\n%d-Point FFT object created.\n",m_numPoints);
|
||||
#endif
|
||||
}
|
||||
/***************************************************************************/
|
||||
/* Destruktor FFT-Objekt */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
cfft::~cfft()
|
||||
{
|
||||
delete [] pTwiddleTbl;
|
||||
|
||||
#ifdef FFTMsg
|
||||
printf("\n%d-Point FFT object deleted.\n",m_numPoints);
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* FFT */
|
||||
/* FAST-FOURIER-TRANSFORMATION s(t) -> S(f) */
|
||||
/***************************************************************************/
|
||||
void cfft::fft(double *in_re, double *in_im)
|
||||
{
|
||||
register unsigned stageCnt, k, kk, twf, numNodesPerStage, nodeCnt, opsPerNode, opCnt, i, i2, j;
|
||||
double tempr, tempi, s, c;
|
||||
|
||||
#ifdef FFTMsg
|
||||
unsigned numMul, numAdd;
|
||||
printf ("\nStart %d-Point FFT.\n\n",m_numPoints);
|
||||
#endif
|
||||
|
||||
// Do the bit reversal
|
||||
i2 = m_numPoints >> 1;
|
||||
j = 0;
|
||||
for (i=0; i<m_numPoints-1;i++) {
|
||||
if (i < j) {
|
||||
tempr = in_re[i];
|
||||
tempi = in_im[i];
|
||||
in_re[i] = in_re[j];
|
||||
in_im[i] = in_im[j];
|
||||
in_re[j] = tempr;
|
||||
in_im[j] = tempi;
|
||||
}
|
||||
k = i2;
|
||||
while (k <= j) {
|
||||
j = j-k;
|
||||
k >>= 1;
|
||||
}
|
||||
j = j+k;
|
||||
}
|
||||
|
||||
// Calculate the FFT
|
||||
|
||||
#ifdef FFTMsg
|
||||
numMul =0;
|
||||
numAdd =0;
|
||||
#endif
|
||||
numNodesPerStage = m_numPoints;
|
||||
for (stageCnt=1; stageCnt <= m_numStages; stageCnt++) {
|
||||
k=0;
|
||||
numNodesPerStage = numNodesPerStage/2;
|
||||
opsPerNode = m_numPoints/(2*numNodesPerStage);
|
||||
|
||||
#ifdef FFTMsg
|
||||
printf ("Processing STAGE # %2d",stageCnt);
|
||||
#endif
|
||||
for (nodeCnt=1; nodeCnt <= numNodesPerStage; nodeCnt++) {
|
||||
twf = 0;
|
||||
opCnt = opsPerNode;
|
||||
|
||||
while (opCnt) {
|
||||
#ifdef FFTMsg
|
||||
numMul++;
|
||||
numAdd +=2;
|
||||
#endif
|
||||
c = pTwiddleTbl[twf].real;
|
||||
s = - pTwiddleTbl[twf].imag;
|
||||
kk = k + opsPerNode;
|
||||
tempr = (c * in_re[kk]) - (s * in_im[kk]);
|
||||
tempi = (s * in_re[kk]) + (c * in_im[kk]);
|
||||
in_re[kk] = in_re[k] - tempr;
|
||||
in_im[kk] = in_im[k] - tempi;
|
||||
in_re[k] = in_re[k] + tempr;
|
||||
in_im[k] = in_im[k] + tempi;
|
||||
k++;
|
||||
opCnt--;
|
||||
twf += numNodesPerStage;
|
||||
}
|
||||
|
||||
k += opsPerNode;
|
||||
}
|
||||
#ifdef FFTMsg
|
||||
printf (" ... finished.\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef FFTMsg
|
||||
printf ("\n%d-Point FFT is completed.\n",m_numPoints);
|
||||
printf ("Total number of complex additions = %u\n",numAdd);
|
||||
printf ("Total number of complex multiplications = %u\n",numMul);
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* IFFT */
|
||||
/* INVERSE-FAST-FOURIER-TRANSFORMATION S(f) -> s(t) */
|
||||
/***************************************************************************/
|
||||
void cfft::ifft(double *in_re, double *in_im)
|
||||
{
|
||||
register unsigned stageCnt, k, kk, twf, numNodesPerStage, nodeCnt, opsPerNode, opCnt, i, i2, j;
|
||||
double tempr, tempi, s, c;
|
||||
|
||||
#ifdef FFTMsg
|
||||
printf ("\nStart %d-Point IFFT.\n\n",m_numPoints);
|
||||
#endif
|
||||
|
||||
// Do the bit reversal
|
||||
i2 = m_numPoints >> 1;
|
||||
j = 0;
|
||||
for (i=0; i<m_numPoints-1;i++) {
|
||||
if (i < j) {
|
||||
tempr = in_re[i];
|
||||
tempi = in_im[i];
|
||||
in_re[i] = in_re[j];
|
||||
in_im[i] = in_im[j];
|
||||
in_re[j] = tempr;
|
||||
in_im[j] = tempi;
|
||||
}
|
||||
k = i2;
|
||||
while (k <= j) {
|
||||
j = j-k;
|
||||
k >>= 1;
|
||||
}
|
||||
j = j+k;
|
||||
}
|
||||
|
||||
// Calculate the IFFT
|
||||
numNodesPerStage = m_numPoints;
|
||||
for (stageCnt=1; stageCnt <= m_numStages; stageCnt++) {
|
||||
k=0;
|
||||
numNodesPerStage = numNodesPerStage/2;
|
||||
opsPerNode = m_numPoints/(2*numNodesPerStage);
|
||||
|
||||
#ifdef FFTMsg
|
||||
printf ("Processing STAGE # %2d",stageCnt);
|
||||
#endif
|
||||
|
||||
for (nodeCnt=1; nodeCnt <= numNodesPerStage; nodeCnt++) {
|
||||
twf = 0;
|
||||
opCnt = opsPerNode;
|
||||
|
||||
while (opCnt) {
|
||||
c = pTwiddleTbl[twf].real;
|
||||
s = pTwiddleTbl[twf].imag;
|
||||
kk = k + opsPerNode;
|
||||
tempr = (c * in_re[kk]) - (s * in_im[kk]);
|
||||
tempi = (s * in_re[kk]) + (c * in_im[kk]);
|
||||
in_re[kk] = in_re[k] - tempr;
|
||||
in_im[kk] = in_im[k] - tempi;
|
||||
in_re[k] = in_re[k] + tempr;
|
||||
in_im[k] = in_im[k] + tempi;
|
||||
k++;
|
||||
opCnt--;
|
||||
twf += numNodesPerStage;
|
||||
}
|
||||
k += opsPerNode;
|
||||
}
|
||||
#ifdef FFTMsg
|
||||
printf (" ... finished.\n");
|
||||
#endif
|
||||
}
|
||||
#ifdef FFTMsg
|
||||
printf ("\n%d-Point IFFT is completed.\n",m_numPoints);
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* Konstruktor FFT-Objekt */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
void FFTinit(FFT *pFFT, unsigned N)
|
||||
{
|
||||
|
||||
pFFT->m_numPoints = 0;
|
||||
pFFT->m_numStages = 0;
|
||||
pFFT->pTwiddleTbl = NULL;
|
||||
|
||||
if(BiPower(N) != 0)
|
||||
{
|
||||
printf("\n%u is not a power of 2!\n",N);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pFFT->m_numStages = (unsigned) (1e-06 + log((double)N)/log(2.0));
|
||||
pFFT->m_numPoints = (unsigned int)N;
|
||||
|
||||
pFFT->pTwiddleTbl = (COMPLEX*)malloc(pFFT->m_numPoints * sizeof(COMPLEX) /2);
|
||||
if (!pFFT->pTwiddleTbl)
|
||||
{
|
||||
printf("\nZu wenig Speicher !");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
FFTCalcTwiddleTable(pFFT->pTwiddleTbl, pFFT->m_numPoints);
|
||||
|
||||
#ifdef FFTMsg
|
||||
printf("\n%d-Point FFT object created.\n",pFFT->m_numPoints);
|
||||
#endif
|
||||
}
|
||||
/***************************************************************************/
|
||||
/* Destruktor FFT-Objekt */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
void FFTfree(FFT *pFFT)
|
||||
{
|
||||
if (pFFT->pTwiddleTbl != NULL)
|
||||
{
|
||||
free(pFFT->pTwiddleTbl);
|
||||
pFFT->pTwiddleTbl = NULL;
|
||||
}
|
||||
|
||||
pFFT->m_numPoints = 0;
|
||||
pFFT->m_numStages = 0;
|
||||
|
||||
#ifdef FFTMsg
|
||||
printf("\n%d-Point FFT object deleted.\n",pFFT->m_numPoints);
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* FFT */
|
||||
/* FAST-FOURIER-TRANSFORMATION s(t) -> S(f) */
|
||||
/***************************************************************************/
|
||||
void fft(FFT *pFFT, double *in_re, double *in_im)
|
||||
{
|
||||
register unsigned stageCnt, k, kk, twf, numNodesPerStage, nodeCnt, opsPerNode, opCnt, i, i2, j;
|
||||
double tempr, tempi, s, c;
|
||||
|
||||
#ifdef FFTMsg
|
||||
unsigned numMul, numAdd;
|
||||
printf ("\nStart %d-Point FFT.\n\n",pFFT->m_numPoints);
|
||||
#endif
|
||||
|
||||
// Do the bit reversal
|
||||
i2 = pFFT->m_numPoints >> 1;
|
||||
j = 0;
|
||||
for (i=0; i <pFFT->m_numPoints-1;i++) {
|
||||
if (i < j) {
|
||||
tempr = in_re[i];
|
||||
tempi = in_im[i];
|
||||
in_re[i] = in_re[j];
|
||||
in_im[i] = in_im[j];
|
||||
in_re[j] = tempr;
|
||||
in_im[j] = tempi;
|
||||
}
|
||||
k = i2;
|
||||
while (k <= j) {
|
||||
j = j-k;
|
||||
k >>= 1;
|
||||
}
|
||||
j = j+k;
|
||||
}
|
||||
|
||||
// Calculate the FFT
|
||||
|
||||
#ifdef FFTMsg
|
||||
numMul =0;
|
||||
numAdd =0;
|
||||
#endif
|
||||
numNodesPerStage = pFFT->m_numPoints;
|
||||
for (stageCnt=1; stageCnt <= pFFT->m_numStages; stageCnt++) {
|
||||
k=0;
|
||||
numNodesPerStage = numNodesPerStage/2;
|
||||
opsPerNode = pFFT->m_numPoints/(2*numNodesPerStage);
|
||||
|
||||
#ifdef FFTMsg
|
||||
printf ("Processing STAGE # %2d",stageCnt);
|
||||
#endif
|
||||
for (nodeCnt=1; nodeCnt <= numNodesPerStage; nodeCnt++) {
|
||||
twf = 0;
|
||||
opCnt = opsPerNode;
|
||||
|
||||
while (opCnt) {
|
||||
#ifdef FFTMsg
|
||||
numMul++;
|
||||
numAdd +=2;
|
||||
#endif
|
||||
c = pFFT->pTwiddleTbl[twf].real;
|
||||
s = - pFFT->pTwiddleTbl[twf].imag;
|
||||
kk = k + opsPerNode;
|
||||
tempr = (c * in_re[kk]) - (s * in_im[kk]);
|
||||
tempi = (s * in_re[kk]) + (c * in_im[kk]);
|
||||
in_re[kk] = in_re[k] - tempr;
|
||||
in_im[kk] = in_im[k] - tempi;
|
||||
in_re[k] = in_re[k] + tempr;
|
||||
in_im[k] = in_im[k] + tempi;
|
||||
k++;
|
||||
opCnt--;
|
||||
twf += numNodesPerStage;
|
||||
}
|
||||
|
||||
k += opsPerNode;
|
||||
}
|
||||
#ifdef FFTMsg
|
||||
printf (" ... finished.\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef FFTMsg
|
||||
printf ("\n%d-Point FFT is completed.\n",pFFT->m_numPoints);
|
||||
printf ("Total number of complex additions = %u\n",numAdd);
|
||||
printf ("Total number of complex multiplications = %u\n",numMul);
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* IFFT */
|
||||
/* INVERSE-FAST-FOURIER-TRANSFORMATION S(f) -> s(t) */
|
||||
/***************************************************************************/
|
||||
void ifft(FFT *pFFT, double *in_re, double *in_im)
|
||||
{
|
||||
register unsigned stageCnt, k, kk, twf, numNodesPerStage, nodeCnt, opsPerNode, opCnt, i, i2, j;
|
||||
double tempr, tempi, s, c;
|
||||
|
||||
#ifdef FFTMsg
|
||||
printf ("\nStart %d-Point IFFT.\n\n",pFFT->m_numPoints);
|
||||
#endif
|
||||
|
||||
// Do the bit reversal
|
||||
i2 = pFFT->m_numPoints >> 1;
|
||||
j = 0;
|
||||
for (i=0; i <pFFT->m_numPoints-1;i++) {
|
||||
if (i < j) {
|
||||
tempr = in_re[i];
|
||||
tempi = in_im[i];
|
||||
in_re[i] = in_re[j];
|
||||
in_im[i] = in_im[j];
|
||||
in_re[j] = tempr;
|
||||
in_im[j] = tempi;
|
||||
}
|
||||
k = i2;
|
||||
while (k <= j) {
|
||||
j = j-k;
|
||||
k >>= 1;
|
||||
}
|
||||
j = j+k;
|
||||
}
|
||||
|
||||
// Calculate the IFFT
|
||||
numNodesPerStage = pFFT->m_numPoints;
|
||||
for (stageCnt=1; stageCnt <= pFFT->m_numStages; stageCnt++) {
|
||||
k=0;
|
||||
numNodesPerStage = numNodesPerStage/2;
|
||||
opsPerNode = pFFT->m_numPoints/(2*numNodesPerStage);
|
||||
|
||||
#ifdef FFTMsg
|
||||
printf ("Processing STAGE # %2d",stageCnt);
|
||||
#endif
|
||||
|
||||
for (nodeCnt=1; nodeCnt <= numNodesPerStage; nodeCnt++) {
|
||||
twf = 0;
|
||||
opCnt = opsPerNode;
|
||||
|
||||
while (opCnt) {
|
||||
c = pFFT->pTwiddleTbl[twf].real;
|
||||
s = pFFT->pTwiddleTbl[twf].imag;
|
||||
kk = k + opsPerNode;
|
||||
tempr = (c * in_re[kk]) - (s * in_im[kk]);
|
||||
tempi = (s * in_re[kk]) + (c * in_im[kk]);
|
||||
in_re[kk] = in_re[k] - tempr;
|
||||
in_im[kk] = in_im[k] - tempi;
|
||||
in_re[k] = in_re[k] + tempr;
|
||||
in_im[k] = in_im[k] + tempi;
|
||||
k++;
|
||||
opCnt--;
|
||||
twf += numNodesPerStage;
|
||||
}
|
||||
k += opsPerNode;
|
||||
}
|
||||
#ifdef FFTMsg
|
||||
printf (" ... finished.\n");
|
||||
#endif
|
||||
}
|
||||
#ifdef FFTMsg
|
||||
printf ("\n%d-Point IFFT is completed.\n",pFFT->m_numPoints);
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* TWIDDLE-FAKTOR-TABLE */
|
||||
/* Erstellt Twiddle-Faktor-Tabelle von WN^0 bis WN^N/2 */
|
||||
/***************************************************************************/
|
||||
void FFTCalcTwiddleTable (COMPLEX *pTwfTbl, unsigned numPoints)
|
||||
{
|
||||
unsigned i, size;
|
||||
double arg1;
|
||||
|
||||
size = numPoints/2;
|
||||
arg1 = (2.0 * PI / (double)numPoints );
|
||||
|
||||
#ifdef FFTMsg
|
||||
printf ("Calculating and initializing Twiddle-Table (%d kB)...",size*sizeof(COMPLEX));
|
||||
#endif
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
pTwfTbl[i].real = cos(arg1* (double)i);
|
||||
pTwfTbl[i].imag = sin(arg1* (double)i);
|
||||
}
|
||||
#ifdef FFTMsg
|
||||
printf(" completed.\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* MODULUS */
|
||||
/* Berechnet den Betrag einer komplexen Zahl */
|
||||
/***************************************************************************/
|
||||
void Modulus(double *pRealData, double *pImagData, unsigned N)
|
||||
{
|
||||
unsigned i;
|
||||
double temp;
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
temp = sqrt( pRealData[i] * pRealData[i] + pImagData[i] * pImagData[i]);
|
||||
pImagData[i] = atan2(pImagData[i],pRealData[i]);
|
||||
pRealData[i] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* MODULUS2 */
|
||||
/* Berechnet den Betrag einer komplexen Zahl */
|
||||
/***************************************************************************/
|
||||
void Modulus2(double *pRealData, double *pImagData, double *pModulus, unsigned N)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
pModulus[i] = sqrt( pRealData[i] * pRealData[i] + pImagData[i] * pImagData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* Hanning */
|
||||
/* Legt das Hanningfenster auf die Abtastwerte im Zeitbereich der Groesse N */
|
||||
/***************************************************************************/
|
||||
void Hanning(double *pRealData, double *pImagData, unsigned N, unsigned maximum)
|
||||
{
|
||||
unsigned n;
|
||||
double arg;
|
||||
|
||||
for (n=0; n < N; n++)
|
||||
{
|
||||
arg = (2*PI*n /(N-1) - 2*PI*maximum/N);
|
||||
pRealData[n] = pRealData[n] * (1 + cos(arg)) /2;
|
||||
pImagData[n] = pImagData[n] * (1 + cos(arg)) /2;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* HANNING_K */
|
||||
/* Gibt einen Faktor k in Abhängigkeit von n bezogen auf N zurück. */
|
||||
/***************************************************************************/
|
||||
double hanning_k(unsigned n, unsigned N)
|
||||
{
|
||||
double arg;
|
||||
arg = (2 * PI / (double)N);
|
||||
|
||||
return ((1-cos(arg*(double)n))/2);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* GAUSS_K */
|
||||
/* Gibt einen Faktor k in Abhängigkeit von n bezogen auf N zurück. */
|
||||
/***************************************************************************/
|
||||
double gauss_k(unsigned n, unsigned m, unsigned s)
|
||||
{
|
||||
double arg;
|
||||
arg = ((n-m)*(n-m)/(2*s*s));
|
||||
|
||||
return (exp(-arg));
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* Normalize) */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
void Scale(double *pRealData, double *pImagData, double scaleFactor, unsigned N)
|
||||
{
|
||||
unsigned int k;
|
||||
|
||||
// Scaling Data
|
||||
for (k=0; k < N; k++)
|
||||
{
|
||||
pRealData[k] *= (double)scaleFactor;
|
||||
pImagData[k] *= (double)scaleFactor;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* BiPower()
|
||||
/* checks if N is power of 2
|
||||
/***************************************************************************/
|
||||
int BiPower(unsigned int N)
|
||||
{
|
||||
int i, iterations;
|
||||
iterations = sizeof(int)*8;
|
||||
|
||||
if (N == 0)
|
||||
return -1;
|
||||
|
||||
for (i=0; i <iterations; i++)
|
||||
{
|
||||
if (N == (unsigned)(2 << i))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* FFT2Dinit()
|
||||
/*
|
||||
/***************************************************************************/
|
||||
void FFT2Dinit(struct _sFFT2D *pFFT, unsigned Nx, unsigned Ny)
|
||||
{
|
||||
pFFT->pXfft = NULL;
|
||||
pFFT->pYfft = NULL;
|
||||
|
||||
pFFT->m_Nx = Nx;
|
||||
pFFT->m_Ny = Ny;
|
||||
|
||||
pFFT->pXfft = (struct _sFFT*)malloc(sizeof(pFFT->pXfft));
|
||||
FFTinit(pFFT->pXfft, Nx);
|
||||
|
||||
if (Nx == Ny)
|
||||
pFFT->pYfft = pFFT->pXfft;
|
||||
|
||||
else
|
||||
{
|
||||
pFFT->pYfft = (struct _sFFT*)malloc(sizeof(pFFT->pYfft));
|
||||
FFTinit(pFFT->pYfft, Ny);
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* FFT2Dfree()
|
||||
/*
|
||||
/***************************************************************************/
|
||||
void FFT2Dfree(struct _sFFT2D *pFFT)
|
||||
{
|
||||
if (pFFT->pXfft != NULL)
|
||||
{
|
||||
FFTfree(pFFT->pXfft);
|
||||
pFFT->pXfft = NULL;
|
||||
}
|
||||
if (pFFT->pYfft != NULL)
|
||||
{
|
||||
FFTfree(pFFT->pYfft);
|
||||
pFFT->pYfft = NULL;
|
||||
}
|
||||
|
||||
pFFT->m_Nx = 0;
|
||||
pFFT->m_Ny = 0;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* fft2d()
|
||||
/*
|
||||
/***************************************************************************/
|
||||
void fft2d(struct _sFFT2D *pFFT, double **ppReal, double **ppImag)
|
||||
{
|
||||
double *pTempr, *pTempi;
|
||||
unsigned i, row;
|
||||
|
||||
|
||||
pTempr = (double*)malloc(pFFT->m_Ny*sizeof(double));
|
||||
pTempi = (double*)malloc(pFFT->m_Ny*sizeof(double));
|
||||
|
||||
/* Transform ROWs */
|
||||
for (row=0; row <pFFT->m_Ny; row++)
|
||||
fft(pFFT->pXfft, ppReal[row], ppImag[row]);
|
||||
|
||||
/* Transform COLs */
|
||||
for (row=0; row <pFFT->m_Nx; row++)
|
||||
{
|
||||
for(i=0; i <pFFT->m_Ny; i++)
|
||||
{
|
||||
pTempr[i] = ppReal[i][row];
|
||||
pTempi[i] = ppImag[i][row];
|
||||
}
|
||||
|
||||
fft(pFFT->pYfft, pTempr, pTempi);
|
||||
for(i=0; i <pFFT->m_Ny; i++)
|
||||
{
|
||||
ppReal[i][row] = pTempr[i];
|
||||
ppImag[i][row] = pTempi[i];
|
||||
}
|
||||
}
|
||||
free(pTempr);
|
||||
free(pTempi);
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* ifft2d()
|
||||
/*
|
||||
/***************************************************************************/
|
||||
void ifft2d(struct _sFFT2D *pFFT, double **ppReal, double **ppImag)
|
||||
{
|
||||
double *pTempr, *pTempi;
|
||||
unsigned i, row;
|
||||
|
||||
|
||||
pTempr = (double*)malloc(pFFT->m_Ny*sizeof(double));
|
||||
pTempi = (double*)malloc(pFFT->m_Ny*sizeof(double));
|
||||
|
||||
/* Transform COLs */
|
||||
for (row=0; row <pFFT->m_Nx; row++)
|
||||
{
|
||||
for(i=0; i <pFFT->m_Ny; i++)
|
||||
{
|
||||
pTempr[i] = ppReal[i][row];
|
||||
pTempi[i] = ppImag[i][row];
|
||||
}
|
||||
|
||||
ifft(pFFT->pYfft, pTempr, pTempi);
|
||||
for(i=0; i <pFFT->m_Ny; i++)
|
||||
{
|
||||
ppReal[i][row] = pTempr[i];
|
||||
ppImag[i][row] = pTempi[i];
|
||||
}
|
||||
}
|
||||
free(pTempr);
|
||||
free(pTempi);
|
||||
|
||||
/* Transform ROWs */
|
||||
for (row=0; row <pFFT->m_Ny; row++)
|
||||
ifft(pFFT->pXfft, ppReal[row], ppImag[row]);
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* DFT()
|
||||
/* DISKRETE FOURIER-TRANSFORMATION S(f) -> s(t) */
|
||||
/***************************************************************************/
|
||||
void DFT(double *pDataR, double *pDataI, unsigned N)
|
||||
{
|
||||
double *a, *b;
|
||||
double phi, c, s;
|
||||
unsigned i, j;
|
||||
|
||||
a = (double*)malloc(N * sizeof(double));
|
||||
b = (double*)malloc(N * sizeof(double));
|
||||
|
||||
memcpy((double*)a,(double*)pDataR,N * sizeof(double));
|
||||
memcpy((double*)b,(double*)pDataI,N * sizeof(double));
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
{
|
||||
pDataR[i] = 0;
|
||||
pDataI[i] = 0;
|
||||
|
||||
for (j = 0; j < N; j++)
|
||||
{
|
||||
phi = 2*i*j*PI/N;
|
||||
c = 0.5*cos(phi);
|
||||
s = 0.5*sin(phi);
|
||||
|
||||
pDataR[i] += c*a[j] - s*b[j];
|
||||
pDataI[i] += s*a[j] + c*b[j];
|
||||
}
|
||||
}
|
||||
free(a);
|
||||
free(b);
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* IDFT()
|
||||
/* INVERSE DISKRETE FOURIER-TRANSFORMATION S(f) -> s(t) */
|
||||
/***************************************************************************/
|
||||
void IDFT(double *pDataR, double *pDataI, unsigned N)
|
||||
{
|
||||
double *a, *b;
|
||||
double phi, c, s;
|
||||
unsigned i, j;
|
||||
|
||||
a = (double*)malloc(N * sizeof(double));
|
||||
b = (double*)malloc(N * sizeof(double));
|
||||
|
||||
memcpy((double*)a,(double*)pDataR,N * sizeof(double));
|
||||
memcpy((double*)b,(double*)pDataI,N * sizeof(double));
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
{
|
||||
pDataR[i] = 0;
|
||||
pDataI[i] = 0;
|
||||
|
||||
for (j = 0; j < N; j++)
|
||||
{
|
||||
phi = 2*i*j*PI/N;
|
||||
c = 0.5*cos(phi);
|
||||
s = -0.5*sin(phi);
|
||||
|
||||
pDataR[i] += c*a[j] - s*b[j];
|
||||
pDataI[i] += s*a[j] + c*b[j];
|
||||
}
|
||||
}
|
||||
free(a);
|
||||
free(b);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/***************************************************************************/
|
||||
/* FFT.H */
|
||||
/* Fast-Fourier-Transformation
|
||||
/* Author: Jens Ahrensfeld */
|
||||
/* Datum : 24.06.1999 */
|
||||
/* letzte Änderung: 09.06.2000 */
|
||||
/***************************************************************************/
|
||||
/* Tabellen und Funktionen für die FFT */
|
||||
/***************************************************************************/
|
||||
#ifndef FFT_H
|
||||
#define FFT_H
|
||||
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
typedef struct _sCOMPLEX
|
||||
{
|
||||
double real, imag;
|
||||
} COMPLEX;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
class cfft
|
||||
{
|
||||
public:
|
||||
cfft(unsigned);
|
||||
~cfft();
|
||||
void fft (double*, double*);
|
||||
void ifft (double*, double*);
|
||||
COMPLEX *pTwiddleTbl;
|
||||
|
||||
protected:
|
||||
unsigned m_numPoints, m_numStages;
|
||||
|
||||
};
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct _sFFT
|
||||
{
|
||||
unsigned m_numPoints, m_numStages;
|
||||
COMPLEX *pTwiddleTbl;
|
||||
} FFT;
|
||||
|
||||
typedef struct _sFFT2D
|
||||
{
|
||||
struct _sFFT *pXfft, *pYfft;
|
||||
unsigned m_Nx, m_Ny;
|
||||
} FFT2D;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* DFT functions */
|
||||
extern void DFT(double *pDataR, double *pDataI, unsigned N);
|
||||
extern void IDFT(double *pDataR, double *pDataI, unsigned N);
|
||||
|
||||
/* FFT functions */
|
||||
extern void FFTinit(FFT *pFFT, unsigned N);
|
||||
extern void FFTfree(FFT *pFFT);
|
||||
extern void fft (FFT *pFFT, double*, double*);
|
||||
extern void ifft (FFT *pFFT, double*, double*);
|
||||
extern void FFTCalcTwiddleTable (COMPLEX *pTwfTbl, unsigned numPoints);
|
||||
|
||||
/* 2D FFT functions */
|
||||
extern void FFT2Dinit(struct _sFFT2D *pFFT, unsigned Nx, unsigned Ny);
|
||||
extern void FFT2Dfree(struct _sFFT2D *pFFT);
|
||||
extern void fft2d(struct _sFFT2D *pFFT, double **ppReal, double **ppImag);
|
||||
extern void ifft2d(struct _sFFT2D *pFFT, double **ppReal, double **ppImag);
|
||||
|
||||
/* Helper functions */
|
||||
extern void Scale(double *pRealData, double *pImagData , double scaleFactor, unsigned N);
|
||||
extern void Modulus(double *pRealData, double *pImagData, unsigned N);
|
||||
extern void Modulus2(double *pRealData, double *pImagData, double *pModulus, unsigned N);
|
||||
extern void Hanning (double *pRealData, double *pImagData, unsigned N, unsigned maximum);
|
||||
extern double hanning_k (unsigned, unsigned);
|
||||
extern double gauss_k(unsigned, unsigned, unsigned);
|
||||
extern int BiPower(unsigned int N);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* FFT_H */
|
||||
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
@@ -0,0 +1,100 @@
|
||||
# Microsoft Developer Studio Project File - Name="cfft" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** NICHT BEARBEITEN **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=cfft - Win32 Debug
|
||||
!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
|
||||
!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "cfft.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
|
||||
!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "cfft.mak" CFG="cfft - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Für die Konfiguration stehen zur Auswahl:
|
||||
!MESSAGE
|
||||
!MESSAGE "cfft - Win32 Release" (basierend auf "Win32 (x86) Static Library")
|
||||
!MESSAGE "cfft - Win32 Debug" (basierend auf "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "cfft - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x407 /d "NDEBUG"
|
||||
# ADD RSC /l 0x407 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo /out:"..\..\lib\release\fft.lib"
|
||||
|
||||
!ELSEIF "$(CFG)" == "cfft - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x407 /d "_DEBUG"
|
||||
# ADD RSC /l 0x407 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo /out:"..\..\lib\debug\fft.lib"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "cfft - Win32 Release"
|
||||
# Name "cfft - Win32 Debug"
|
||||
# Begin Group "Quellcodedateien"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\fft.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header-Dateien"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\Fft.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "cfft"=.\cfft.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<html>
|
||||
<body>
|
||||
<pre>
|
||||
<h1>Erstellungsprotokoll</h1>
|
||||
<h3>
|
||||
--------------------Konfiguration: cfft - Win32 Release--------------------
|
||||
</h3>
|
||||
<h3>Befehlszeilen</h3>
|
||||
Erstellen der temporären Datei "E:\WIN95\TEMP\RSPD363.TMP" mit Inhalten
|
||||
[
|
||||
/nologo /ML /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /Fp"Release/cfft.pch" /YX /Fo"Release/" /Fd"Release/" /FD /c
|
||||
"G:\work\Develope\MSVC\LIBSRC\CFFT\fft.cpp"
|
||||
]
|
||||
Creating command line "cl.exe @E:\WIN95\TEMP\RSPD363.TMP"
|
||||
Erstellen der Befehlzeile "link.exe -lib /nologo /out:"..\..\lib\release\fft.lib" .\Release\fft.obj "
|
||||
<h3>Ausgabefenster</h3>
|
||||
Kompilierung läuft...
|
||||
fft.cpp
|
||||
Bibliothek wird erstellt...
|
||||
|
||||
|
||||
|
||||
<h3>Ergebnisse</h3>
|
||||
fft.lib - 0 Fehler, 0 Warnung(en)
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user