#include <math.h>
/************************************************************************/
/* 音频波形FFT变化,转为频谱信号
* All rights reserved.
*
* 文件名称:FFT.h
* 摘 要:FFT
*
* 当前版本:1.0
* 修改内容:
* 作 者:adolph
* 完成日期:2010年10月13日
*
* 取代版本:
* 原作者 :
* 修改内容:
* 完成日期:
* 使用方法
* 1,申明方法, 在文件头里进行类型申明
*/
/************************************************************************/
#ifndef INCLUDE_FFT
#define INCLUDE_FFT
#define PI_2 6.283185f
#define BASE_WAVE_HZ 16 //起始频率
#define FREQUENCY_TIMES 1 //倍频 1 为1倍频 11段, 3为3倍频 32段, 6为6倍频 64段
class FFT
{
private:
float* xre;
float* xim;
float* mag;
float* fftSin;
float* fftCos;
int* fftBr; //返回傅立叶变换的实部
int m_samplesize;
int m_samplesize2;
int nu;
int nu1;
public:
FFT(int sampleSize)
{
m_samplesize = sampleSize;
m_samplesize2 = sampleSize >> 1;
xre = new float[sampleSize];
xim = new float[sampleSize];
mag = new float[m_samplesize2];
nu = (int)(log((float)sampleSize) / log((float)2));
nu1 = nu - 1;
prepareFFTTables();
}
~FFT()
{
if(xre != NULL) delete[] xre;
if(xim != NULL) delete[] xim;
if(mag != NULL) delete[] mag;
if(fftSin != NULL) delete[] fftSin;
if(fftCos != NULL) delete[] fftCos;
if(fftBr != NULL) delete[] fftBr;
}
float* calculate(float* pSample, int nSampleSize) {
int n2 = m_samplesize2; //m_samplesize2 == 512
int nu1 = nu - 1; //nu==10
int wAps = nSampleSize / m_samplesize;
int a = 0;
//将数据存入xre,xim值均为0.0f
for (int b = 0; a < nSampleSize; b++)
{
xre[b] = pSample[a]; //实部
xim[b] = 0.0F; //虚部
a += wAps;
}
//////////////////////////////////////////////////////////////////////////
/// 以下代码为关键代码,将BUFFER中的数据,转换为频谱数据
float fCos;
float fSin;
//nu==10
int x = 0;
for (int nNuIndex = 1; nNuIndex <= nu; nNuIndex++)
{
//n2初始值为512
for (int nSampleIndex = 0; nSampleIndex < m_samplesize; nSampleIndex += n2)
{
//将当前x[n]与x[n+n2]
for (int nN2Index = 1; nN2Index <= n2; nN2Index++)
{
fCos = fftCos[x];
fSin = fftSin[x];
int kn2 = nSampleIndex + n2;
float tr = xre[kn2] * fCos + xim[kn2] * fSin;
float ti = xim[kn2] * fCos - xre[kn2] * fSin;
xre[kn2] = xre[nSampleIndex] - tr;
xim[kn2] = xim[nSampleIndex] - ti;
xre[nSampleIndex] += tr;
xim[nSampleIndex] += ti;
nSampleIndex++;
x++;
}
}
nu1--;
n2 >>= 1; // n2 = n2 /2
}
for (int k = 0; k < m_samplesize; 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) m_samplesize;
for (int nFrequencyIndex = 0; nFrequencyIndex < m_samplesize2; nFrequencyIndex++)
{
mag[nFrequencyIndex] = (2.0F * (float) sqrt(xre[nFrequencyIndex] * xre[nFrequencyIndex] + xim[nFrequencyIndex] * xim[nFrequencyIndex])) / (float) m_samplesize;
}
return mag;
}
private:
void prepareFFTTables()
{
int n2 = m_samplesize2;
int nu1 = nu - 1;
//初始大小为512*10
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 < m_samplesize)
{
for (int i = 1; i <= n2; i++)
{
float p = (float)bitrev(k >> nu1, nu);
float arg = (PI_2 * p) / (float) m_samplesize;
fftSin[x] = (float) sin(arg);
fftCos[x] = (float) cos(arg);
k++;
x++;
}
k += n2;
}
k = 0;
nu1--;
n2 >>= 1;
}
fftBr = new int[m_samplesize];
for (k = 0; k < m_samplesize; k++)
fftBr[k] = bitrev(k, nu);
}
int bitrev(int j, int nu) {
int j1 = j;
int k = 0;
for (int i = 1; i <= nu; i++)
{
int j2 = j1 >> 1; // j2 = j1/2
k = ((k << 1) + j1) - (j2 << 1); // k = k*2 + j1 - j2 *2
j1 = j2;
}
return k;
}
};
#endif
FFT.zip_fft visual
版权申诉
156 浏览量
2022-09-14
20:19:28
上传
评论
收藏 2KB ZIP 举报
JonSco
- 粉丝: 70
- 资源: 1万+