#if 0
#define FFT_SIZE 2048 // 采样点数
#else
#define FFT_SIZE 128 // 采样点数
#endif///////这是什么意思?有Cfft类如下:
class Cfft
{
public:
LONG GetClosestPeak( INT Start, INT Stop);
INT FindPKfreq( INT Center, INT range);
void CalcFFT(double * InBuf);
void ResetFFT();
void SetFFTParams( INT ave, double gain, INT type,double clkerror);
BOOL GetFFTData( INT start, INT stop, LONG* OutBuf, BOOL UseOffset);
Cfft();
virtual ~Cfft();
private:
BOOL m_Overload;
BOOL m_LogMode;
BOOL m_LastLogMode;
INT m_LastAve;
INT m_AveSize;
INT m_OffsetIndxTable[FFT_SIZE/2];
double m_Gain;
double m_Clip;
double * SinCosTbl;
double * WindowTbl;
double* pFFTAveBuf;
double* pFFTInBuf;
INT * WorkArea;
void makewt(int nw, int *ip, double *w);
void makect(int nc, int *ip, double *c);
void bitrv2(int n, int *ip, double *a);
void cftfsub(int n, double *a, double *w);
void rftfsub(int n, double *a, int nc, double *c);
void cft1st(int n, double *a, double *w);
void cftmdl(int n, int l, double *a, double *w);
};///////我要如何使用?
#define FFT_SIZE 2048 // 采样点数
#else
#define FFT_SIZE 128 // 采样点数
#endif///////这是什么意思?有Cfft类如下:
class Cfft
{
public:
LONG GetClosestPeak( INT Start, INT Stop);
INT FindPKfreq( INT Center, INT range);
void CalcFFT(double * InBuf);
void ResetFFT();
void SetFFTParams( INT ave, double gain, INT type,double clkerror);
BOOL GetFFTData( INT start, INT stop, LONG* OutBuf, BOOL UseOffset);
Cfft();
virtual ~Cfft();
private:
BOOL m_Overload;
BOOL m_LogMode;
BOOL m_LastLogMode;
INT m_LastAve;
INT m_AveSize;
INT m_OffsetIndxTable[FFT_SIZE/2];
double m_Gain;
double m_Clip;
double * SinCosTbl;
double * WindowTbl;
double* pFFTAveBuf;
double* pFFTInBuf;
INT * WorkArea;
void makewt(int nw, int *ip, double *w);
void makect(int nc, int *ip, double *c);
void bitrv2(int n, int *ip, double *a);
void cftfsub(int n, double *a, double *w);
void rftfsub(int n, double *a, int nc, double *c);
void cft1st(int n, double *a, double *w);
void cftmdl(int n, int l, double *a, double *w);
};///////我要如何使用?
2.如果没有代码就看文档,或该类的演示程序
3.如果什么都不有,只能靠名字猜了。
你能看懂吗?
// fft.cpp: implementation of the Cfft class.
// This is a slightly modified version of Takuya OOURA's
// original radix 4 FFT package.
//Copyright(C) 1996-1998 Takuya OOURA
// (email: [email protected]).
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include <math.h>
#include "Cfft.h"//////////////////////////////////////////////////////////////////////
// Local Defines
//////////////////////////////////////////////////////////////////////
#if 0
#define SQRT_FFT_SIZE 46 //sqrt(2048)
#define K_2PI (8.0*atan(1.0))
#define SAMPLE_RATE 8000 // 采样率
#define FREQ_SCALE (8000.0/2048.0) // 2048采样点
#else
#define SQRT_FFT_SIZE 11 //sqrt(128)
#define K_2PI (8.0*atan(1.0))
#define SAMPLE_RATE 8000 // 采样率
#define FREQ_SCALE (8000.0/128.0) // 2048采样点
#endif//////////////////////////////////////////////////////////////////////
// A pure input sin wave ... Asin(wt)... will produce an fft output
// peak of (N*A/4)^2 where N is FFT_SIZE.
// To convert to a Power dB range:
// PdBmax = 10*log10( (N*A/4)^2 + K_C ) + K_B
// PdBmin = 10*log10( 0 + K_C ) + K_B
// if (N*A/4)^2 >> K_C
// Then K_B = PdBmax - 20*log10( N*A/4 )
// K_C = 10 ^ ( (PdBmin-K_B)/10 )
// for power range of 0 to 100 dB with input(A) of 32767 and N=2048
// K_B = -44.494132 and K_C = 2.81458e4
// To eliminate the multiply by 10, divide by 10 so for an output
// range of 0 to 100dB the stored value is 0.0 to 10.0
// so final constant K_B = -4.4494132
#define K_B (-4.4494132)
#define K_C (2.81458e4)#define K_ROOT (1.0/4.0)
#define K_ROOTGN 289.626 //(A*N/8)^(2/4) / 10//////////////////////////////////////////////////////////////////////
// Construction/Destruction//////////////////////////////////////////////////////////////////////
//////////////构造函数!!!
Cfft::Cfft()
{
WindowTbl = new double[FFT_SIZE];
SinCosTbl = new double[FFT_SIZE/2];
WorkArea = new int[SQRT_FFT_SIZE+2];
pFFTAveBuf = new double[FFT_SIZE]; //Even index's hold average
pFFTInBuf = new double[FFT_SIZE];
WorkArea[0] = 0;
makewt(FFT_SIZE/4, WorkArea, SinCosTbl);
makect(FFT_SIZE/4, WorkArea, SinCosTbl + WorkArea[0]);
for(INT i=0; i<FFT_SIZE; i++)
{
pFFTAveBuf[i] = 0.0;
// Pick a data windowing function:
// WindowTbl[i] = 1.0; //rectangle
// WindowTbl[i] = .54 - .46*cos( (K_2PI*i)/(FFT_SIZE-1) ); //Hamming
WindowTbl[i] = (.5 - .5*cos( (K_2PI*i)/(FFT_SIZE-1) )); //Hanning
}
m_LastAve = 0;
m_LastLogMode = FALSE;
SetFFTParams( 1, 10.0, TRUE, 1.0 );
m_Clip = 0.0;
m_Overload = FALSE;
}Cfft::~Cfft()
{ // free all resources
if(WorkArea)
{
delete WorkArea;
WorkArea = NULL;
}
if(SinCosTbl)
{
delete SinCosTbl;
SinCosTbl = NULL;
}
if(WindowTbl)
{
delete WindowTbl;
WindowTbl = NULL;
}
if(pFFTAveBuf)
{
delete pFFTAveBuf;
pFFTAveBuf = NULL;
}
if(pFFTInBuf)
{
delete pFFTInBuf;
pFFTInBuf = NULL;
}}// FFT初始化函数
// 入口参数:
// ave [1.0, 10.0]FFT "smoothing"值,1 = no smoothing, 10 = max smoothing (default = 1)
// gain [0.0, 10.0]缩放值, default = 10.0
// type [0, 99], data output type
// 0 = root mode, data is the 4th root of linear FFT output power
// 1 = log mode, data is 10log() of the fft power(default)
// 10..90 = log mode with (10% ~ 90%) baseline clipping applied to the data
void Cfft::SetFFTParams(INT ave, double gain, INT type, double clkerror )
{
if( type==0 )
m_LogMode = FALSE;
else
m_LogMode = TRUE;
if( (type>=10) && (type<=99) )
m_Clip = (double)type/10.0;
else
m_Clip = 0.0;
if(ave>0)
m_AveSize = ave;
else
m_AveSize = 1;
if( (m_LastAve != ave) || (m_LastLogMode != m_LogMode) )
ResetFFT();
m_LastLogMode = m_LogMode;
m_LastAve = m_AveSize;
m_Gain = gain*10.0/(10.0-m_Clip);
for(int i=0; i<(FFT_SIZE/2); i++)
{
m_OffsetIndxTable[i] = (INT)( clkerror*(double)i )<<1;
}}void Cfft::ResetFFT()
{
for(INT i=0; i<FFT_SIZE;i++)
pFFTAveBuf[i] = 0.0;}
//////////////////////////////////////////////////////////////////////
// "InBuf[]" is first multiplied by a window function and then
// calculates an "FFT_SIZE" point FFT on "InBuf[]".
// The result is converted to dB or 4th root and stored in pFFTAveBuf
// If "Ave" is > 1, a LP smoothing filter
// is calculated on the output.
//////////////////////////////////////////////////////////////////////
void Cfft::CalcFFT(double * InBuf)
{
INT i;
m_Overload = FALSE;
for(i=0; i<FFT_SIZE; i++)
{
if( InBuf[i] > 32768.0*0.90 ) //flag overload if within 10% of max
m_Overload = TRUE;
pFFTInBuf[i] = WindowTbl[i] * InBuf[i]; //window the data
}
//Calculate the FFT
bitrv2(FFT_SIZE, WorkArea + 2, pFFTInBuf);
cftfsub(FFT_SIZE, pFFTInBuf, SinCosTbl);
rftfsub(FFT_SIZE, pFFTInBuf, WorkArea[1], SinCosTbl + WorkArea[0]);
}//////////////////////////////////////////////////////////////////////
// the range "start" to "stop" is multiplied by "gain" and copied
// into "OutBuf[]".
// The function returns TRUE if the input is overloaded
//////////////////////////////////////////////////////////////////////
BOOL Cfft::GetFFTData(INT start, INT stop, LONG* OutBuf, BOOL UseOffset )
{
INT j;
if(UseOffset)
{
for( INT i=start; i<=stop; i++ ) //copy and scale into OutBuf[]
{
j = m_OffsetIndxTable[i];
OutBuf[i] = (LONG)( m_Gain*pFFTAveBuf[j] );
}
}
else
{
for( INT i=start; i<=stop; i++ ) //copy and scale into OutBuf[]
{
OutBuf[i] = (LONG)( m_Gain*pFFTAveBuf[i<<1] );
}
}
return m_Overload;
}
......................
还是哪个系统自带的..最近在做dsp的fft
挺难弄的,多尝试吧!
你有没有FFT的源码?
给我一个??
[email protected]
FFT有多种多样的程序类型,历史上曾经有FFT/DFT手册(程序库)出版,针对性不同。
缺少了关键的函数代码:
bitrv2(FFT_SIZE, WorkArea + 2, pFFTInBuf);
cftfsub(FFT_SIZE, pFFTInBuf, SinCosTbl);
rftfsub(FFT_SIZE, pFFTInBuf, WorkArea[1], SinCosTbl + WorkArea[0]);CalcFFT是实际计算函数是算法的核心,缺少上述代码,看不到如何构造蝶形运算;
SetFFTParams是设置FFT参数的子程序;
GetFFTData是输入端函数。GetFFTData( INT start, INT stop, LONG* OutBuf, BOOL UseOffset);
Cfft();
LONG* OutBuf可以认为输入是长度为FFT_SIZE的LONG数组,start,stop是编号的首尾。
日本鬼子的程序,有啥好研究的。
用法
设置变换的输出参数,线性对数(分贝)范围
void SetFFTParams( INT ave, double gain, INT type,double clkerror);
输入2048个样本
void CalcFFT(double * InBuf);
得到变换后的结果
BOOL GetFFTData( INT start, INT stop, LONG* OutBuf, BOOL UseOffset);
重置计算参数
void ResetFFT();
/*
This computes an in-place complex-to-complex FFT
x and y are the real and imaginary arrays of n=2^m points.
o(n)=n*log2(n)
dir = 1 gives forward transform
dir = -1 gives reverse transform
FFT algorithm by Cooley and Tukey, 1965
*/
bool _stdcall FFT(int dir,int m,double *x,double *y)
{
long nn,i,i1,j,k,i2,l,l1,l2;
double c1,c2,tx,ty,t1,t2,u1,u2,z;
/* Calculate the number of points */
nn = 1<<m;
/* Do the bit reversal */
i2 = nn >> 1;
j = 0;
for (i=0;i<nn-1;i++) {
if (i < j) {
tx = x[i];
ty = y[i];
x[i] = x[j];
y[i] = y[j];
x[j] = tx;
y[j] = ty;
}
k = i2;
while (k <= j) {
j -= k;
k >>= 1;
}
j += k;
}
/* Compute the FFT */
c1 = -1.0;
c2 = 0.0;
l2 = 1;
for (l=0;l<m;l++) {
l1 = l2;
l2 <<= 1;
u1 = 1.0;
u2 = 0.0;
for (j=0;j<l1;j++) {
for (i=j;i<nn;i+=l2) {
i1 = i + l1;
t1 = u1 * x[i1] - u2 * y[i1];
t2 = u1 * y[i1] + u2 * x[i1];
x[i1] = x[i] - t1;
y[i1] = y[i] - t2;
x[i] += t1;
y[i] += t2;
}
z = u1 * c1 - u2 * c2;
u2 = u1 * c2 + u2 * c1;
u1 = z;
}
c2 = sqrt((1.0 - c1) / 2.0);
if (dir == 1)
c2 = -c2;
c1 = sqrt((1.0 + c1) / 2.0);
}
/* Scaling for forward transform */
if (dir == 1) {
for (i=0;i<nn;i++) {
x[i] /= (double)nn;
y[i] /= (double)nn;
}
}
return true;
}
// (email: [email protected]).tokyo