00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00038
00039
00040 #include <string.h>
00041 #include <math.h>
00042
00043
00044 #include "zplVecLib.h"
00045 #include "fft.h"
00046
00047 #if !defined(_2PI)
00048 #define _2PI (float)(6.283185307179586476925286766559)
00049 #endif
00050
00051 class CzplfFFTGen : public CzplfFFT_If
00052 {
00053 public:
00054
00055
00057 CzplfFFTGen (int iBlockLength, int iZeroPadFactor, _Fft_Windows_ eWindowType);
00059 virtual ~CzplfFFTGen ();
00060
00061
00070 void zplfFFT (zCOMPLEX *pfDest, float *pfSrc);
00071
00080 void zplfIFFT (float *pfDest, zCOMPLEX *pfSrc);
00081
00082 int m_eLastError;
00083
00084 protected:
00085
00086 int BuildFFTTables ();
00087 void FreeFFTTables ();
00088
00089 float *m_pfSinTable,
00090 *m_pfCosTable;
00091
00092 };
00093
00094
00095
00096 CzplfFFTGen::CzplfFFTGen (int iBlockLength, int iZeroPadFactor, _Fft_Windows_ eWindowType)
00097 {
00098 m_eLastError = 0;
00099 m_iBlockLength = iBlockLength;
00100 m_iFFTLength = m_iBlockLength * iZeroPadFactor;
00101
00102 m_pfWindow = 0;
00103 m_pfWindow = zplfMalloc (m_iBlockLength);
00104
00105 if (!m_pfWindow)
00106 m_eLastError = -1;
00107 else
00108 this->CalculateWindow (eWindowType);
00109
00110 m_pfSinTable = 0;
00111 m_pfCosTable = 0;
00112
00113 m_eLastError |= this->BuildFFTTables ();
00114 }
00115
00116
00117 CzplfFFTGen::~CzplfFFTGen ()
00118 {
00119 if (m_pfWindow)
00120 zplfFree (m_pfWindow);
00121
00122 this->FreeFFTTables ();
00123 }
00124
00125
00126 void CzplfFFTGen::zplfFFT (zCOMPLEX *pfDest, float *pfSrc)
00127 {
00128 ZASSERT ((pfDest == 0) || (pfSrc == 0));
00129 ZASSERT ((m_pfSinTable == 0) || (m_pfCosTable == 0) || (m_pfWindow == 0));
00130 ZASSERT (m_eLastError != 0);
00131
00132
00133 if (pfDest != pfSrc)
00134 memcpy (pfDest, pfSrc, sizeof (float) * m_iBlockLength);
00135
00136
00137 if (m_iFFTLength-m_iBlockLength > 0)
00138 zplfSetZero (&pfDest[m_iBlockLength], (m_iFFTLength - m_iBlockLength));
00139
00140
00141 zplfRealMul_I (pfDest, m_pfWindow, m_iBlockLength);
00142
00143
00144 zRealFFTSplitGeneric (pfDest, m_iFFTLength, m_pfSinTable, m_pfCosTable);
00145
00146 return;
00147 }
00148
00149 void CzplfFFTGen::zplfIFFT (float *pfDest, zCOMPLEX *pfSrc)
00150 {
00151 ZASSERT ((pfDest == 0) || (pfSrc == 0));
00152 ZASSERT ((m_pfSinTable == 0) || (m_pfCosTable == 0) || (m_pfWindow == 0));
00153 ZASSERT (m_eLastError != 0);
00154
00155
00156 zRealIFFTSplitGeneric (pfSrc, m_iFFTLength, m_pfSinTable, m_pfCosTable);
00157
00158
00159 memcpy (pfDest, pfSrc, sizeof (float) * m_iBlockLength);
00160
00161 return;
00162 }
00163
00164 int CzplfFFTGen::BuildFFTTables ()
00165 {
00166 int iQuarterBlockSize = (m_iFFTLength>>3)-1;
00167 float fPiBlock = _2PI / m_iFFTLength,
00168 f3PiBlock = 3.0F * fPiBlock;
00169
00170 m_pfSinTable = zplfMalloc (1+(iQuarterBlockSize<<1));
00171 if (m_pfSinTable == 0)
00172 return -1;
00173 m_pfCosTable = zplfMalloc (1+(iQuarterBlockSize<<1));
00174 if (m_pfCosTable == 0)
00175 return -1;
00176
00177 for (int i = 0; i < iQuarterBlockSize; i++)
00178 {
00179 m_pfSinTable[i] = sinf ((i+1) * fPiBlock);
00180 m_pfCosTable[i] = cosf ((i+1) * fPiBlock);
00181
00182 m_pfSinTable[i+iQuarterBlockSize] = sinf ((i+1) * f3PiBlock);
00183 m_pfCosTable[i+iQuarterBlockSize] = cosf ((i+1) * f3PiBlock);
00184 }
00185
00186 return 0;
00187 }
00188
00189 void CzplfFFTGen::FreeFFTTables ()
00190 {
00191 if (m_pfSinTable)
00192 zplfFree (m_pfSinTable);
00193 if (m_pfCosTable)
00194 zplfFree (m_pfCosTable);
00195 }
00196
00197
00198
00199 int zplfFFTCreateInstance_Gen (CzplfFFT_If*& pCFFT, int iBlockLength, int iZeroPadFactor, CzplfFFT_If::_Fft_Windows_ eWindowType)
00200 {
00201 int rErr = 0;
00202 CzplfFFTGen *pCNewFFT = 0;
00203 pCFFT = 0;
00204
00205
00206 if ((iZeroPadFactor <= 0))
00207 return -1;
00208 if ((iBlockLength <= 0))
00209 return -1;
00210 if ((iBlockLength%4 != 0))
00211 return -1;
00212 if ((iZeroPadFactor != Int2PowTwo (iZeroPadFactor)))
00213 return -1;
00214 if ((iBlockLength != Int2PowTwo (iBlockLength)))
00215 return -1;
00216
00217 pCNewFFT = new CzplfFFTGen (iBlockLength, iZeroPadFactor, eWindowType);
00218
00219 if ((pCNewFFT == 0) || (pCNewFFT->m_eLastError != 0))
00220 return -1;
00221 else
00222 pCFFT = pCNewFFT;
00223
00224 return 0;
00225 }
00226
00227
00228 int zplfFFTDestroyInstance_Gen (CzplfFFT_If*& pCFFT)
00229 {
00230 CzplfFFTGen *pCRealFFT = (CzplfFFTGen*)pCFFT;
00231 if (pCRealFFT == 0)
00232 return -1;
00233
00234 delete pCRealFFT;
00235 pCFFT = 0;
00236
00237 return 0;
00238
00239 }