首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

请相助解释傅里叶变换的代码

2013-06-25 
请帮助解释傅里叶变换的代码在网上找了一个音频播放同时显示波形的代码,主要是为了学习傅里叶变换。我第一

请帮助解释傅里叶变换的代码
在网上找了一个音频播放同时显示波形的代码,主要是为了学习傅里叶变换。
我第一次接触,理解不了。
请懂得的朋友帮助解释。
谢谢。



class CFastFourierTransform
{
private:
float* xre;//实部
float* xim;//虚部
float* mag;
float* fftSin;//正弦
float* fftCos;//余弦
int* fftBr; 
int ss;
int ss2;
int nu;
int nu1;

int BitRev(int j, int nu);
void PrepareFFTTables();
public:
CFastFourierTransform(int pSampleSize);
~CFastFourierTransform(void);

float* Calculate(float* pSample, size_t pSampleSize);
};

//构造函数
CFastFourierTransform::CFastFourierTransform(int pSampleSize)
{
xre = NULL;
xim = NULL;
mag = NULL;
fftSin = NULL;
fftCos = NULL;
fftBr = NULL;

ss = pSampleSize;//样本大小
ss2 = ss >> 1;//相当除以2
nu = (int) (log((float)ss) / log((float)2));
nu1 = nu - 1;

xre = new float[ss]; // real part
xim = new float[ss]; // image part
mag = new float[ss2];

PrepareFFTTables();
}
//析构函数容易懂,没有贴
//下面3个函数,完全没理解
void CFastFourierTransform::PrepareFFTTables()
{
int n2 = ss2;
int nu1 = nu - 1;

fftSin = new float[nu * n2];
fftCos = new float[nu * n2];

int k = 0;
int x = 0;
for (int l = 1; l <= nu; l++) {
while (k < ss) {
for (int i = 1; i <= n2; i++) {
float p = (float)BitRev(k >> nu1, nu);
float arg = (PI_2 * p) / (float) ss;
fftSin[x] = (float) sin(arg);
fftCos[x] = (float) cos(arg);
k++;
x++;
}

k += n2;
}

k = 0;
nu1--;
n2 >>= 1;
}

fftBr = new int[ss];
for (k = 0; k < ss; k++)
fftBr[k] = BitRev(k, nu);
}

int CFastFourierTransform::BitRev(int j, int nu) {
int j1 = j;
int k = 0;//返回值
for (int i = 1; i <= nu; i++) {
int j2 = j1 >> 1;
k = ((k << 1) + j1) - (j2 << 1);
j1 = j2;
}

return k;
}

float* CFastFourierTransform::Calculate(float* pSample, size_t pSampleSize) {
int n2 = ss2;
int nu1 = nu - 1;
int wAps = pSampleSize / ss;
size_t a = 0;

for (size_t b = 0; a < pSampleSize; b++) {
xre[b] = pSample[a];
xim[b] = 0.0F;
a += wAps;
}

int x = 0;
for (int l = 1; l <= nu; l++) {
for (int k = 0; k < ss; k += n2) {
for (int i = 1; i <= n2; i++) {
float c = fftCos[x];


float s = fftSin[x];
int kn2 = k + n2;
float tr = xre[kn2] * c + xim[kn2] * s;
float ti = xim[kn2] * c - xre[kn2] * s;
xre[kn2] = xre[k] - tr;
xim[kn2] = xim[k] - ti;
xre[k] += tr;
xim[k] += ti;
k++;
x++;
}
}

nu1--;
n2 >>= 1;
}

for (int k = 0; k < ss; k++) {
int r = fftBr[k];
if (r > k) {
float tr = xre[k];
float ti = xim[k];
xre[k] = xre[r];
xim[k] = xim[r];
xre[r] = tr;
xim[r] = ti;
}
}

mag[0] = (float) sqrt(xre[0] * xre[0] + xim[0] * xim[0]) / (float) ss;
for (int i = 1; i < ss2; i++)
mag[i] = (2.0F * (float) sqrt(xre[i] * xre[i] + xim[i] * xim[i])) / (float) ss;

return mag;
}
//下面是调用代码,可以不解释
void CSpectrumAnalyser::Process(float pFrameRateRatioHint)
{
if(IsIconic(m_Player->m_hWnd) == TRUE)
return;

for (int a = 0; a < m_SampleSize; a++) {
m_Left[a] = (m_Left[a] + m_Right[a]) / 2.0f;
}

float c = 0;
float pFrrh = pFrameRateRatioHint;
float* wFFT = m_FFT->Calculate(m_Left, m_SampleSize);//调用傅里叶变换
float wSadfrr = m_saDecay * pFrrh;
float wBw = ((float) m_width / (float) m_saBands);

RECT rect;
rect.left = 0;
rect.top = 0;
rect.right = rect.left + m_winwidth;
rect.bottom = rect.top + m_winheight;
FillRect(m_hdcMem, &rect, m_hbrush);

for (int a = 0,  bd = 0; bd < m_saBands; a += (INT)m_saMultiplier, bd++) {
float wFs = 0;
for (int b = 0; b < (INT)m_saMultiplier; b++) {
wFs += wFFT[a + b];
}

wFs = (wFs * (float) log(bd + 2.0F));

if(wFs > 0.005F && wFs < 0.009F)
wFs *= 9.0F * PI;
else if(wFs > 0.01F && wFs < 0.1F)
wFs *= 3.0F * PI;
else if(wFs > 0.1F && wFs < 0.5F)
wFs *= PI; //enlarge PI times, if do not, the bar display abnormally, why??

if (wFs > 1.0F) {
wFs = 0.9F;
}

if (wFs >= (m_oldFFT[a] - wSadfrr)) {
m_oldFFT[a] = wFs;
} else {
m_oldFFT[a] -= wSadfrr;
if (m_oldFFT[a] < 0) {
m_oldFFT[a] = 0;
}
wFs = m_oldFFT[a];
}

drawSpectrumAnalyserBar(&rect, (int) c, m_height, (int) wBw - 1, (int) (wFs * m_height), bd);
c += wBw;
}

BitBlt(m_hdcScreen, 2, 41, m_winwidth, m_winheight, m_hdcMem, 0, 0, SRCCOPY);


}



[解决办法]
是为了做蝶形算法
[解决办法]
  推荐一本书《信号与系统》里面说的很详细的。

热点排行