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