FFT公式如下:
用图表示整个过程:
/*
* test.cpp
*
* Created on: 2013-8-18
* Author: zhijian
*/
#include <stdio.h>
#include <math.h>
#define N 128 //N 点
#define RATE 128 //抽样频率
#define LEN 7 //1<<7=128
#define PI 3.141592653
float src[N]; //输入
float AFreal[N];//实部
float AFimg[N]; //虚部
int upset(int a,int len){
int sum = 0;
while(len--){
sum <<=1;
if(a&1)sum++;
a >>=1;
}
return sum;
}
/*
* 公式X(k) = F1(k) + WnkF2(k) k = 0,1,....N/2-1
* X(k+N/2) = F1(k) - WnkF2(k) k = 0,1,....N/2-1
* 我一开始老是认为,从Wnk中的n是不会变的,因为在上述递归方程中Wnk中的n并没有缩小
* 其实这个n也是递归函数的输入参数之一 形如F(n,k) = F(n/2,k) + Wnk;
* 换言之,Wnk中的n其实是要缩小的......
*
*
*/
void FFT(){
//
for(int i = 0;i<N;i++){
AFreal[i]= src[upset(i,LEN)];
AFimg[i] = 0;
}
float Wn = - PI;
float tempReal,tempImg;
for(int i = 1;i<N;i<<=1){
int offset = 0;
while(offset<N){
//two group
for(int j = 0;j<i;j++){
float tempSin = sin(Wn*j);
float tempCos = cos(Wn*j);
tempReal = tempCos * AFreal[offset+i+j]
- tempSin * AFimg[offset+i+j];
tempImg = tempCos * AFimg[offset+i+j]
+ tempSin * AFreal[offset+i+j];
AFreal[offset+i+j] = AFreal[offset+j] - tempReal;
AFimg[offset+i+j] = AFimg[offset+j] - tempImg;
AFreal[offset+j] = AFreal[offset+j] + tempReal;
AFimg[offset+j] = AFimg[offset+j] + tempImg;
}
offset += (i<<1);
}
Wn /= 2;
}
}
/*
* 生成单一频率序列点
* A位振幅
* f位频率
* derta为偏移
* dc为直流分量
*/
void F(float A,int f,int derta,float dc){
for(int i = 0;i<N;i++){
src[i] = A*sin(2*PI*f*(derta + i)/RATE) + dc;
}
printf("频率:%dHZ\n振幅:%f\n偏移:%d\n直流:%f\n",f,A,derta,dc);
FFT();
for(int i = 0;i<N>>1;i++) {
printf("%dHZ:",RATE*i/N);
if(i==0)printf("%f\n",sqrt(AFreal[i]*AFreal[i] + AFimg[i]*AFimg[i])/N);
else printf("%f\n",sqrt(AFreal[i]*AFreal[i] + AFimg[i]*AFimg[i])*2/N);
}
}
int main(){
F(23,29,14,4.5);
return 0;
}
频率:29HZ
振幅:23.000000
偏移:14
直流:4.500000
0HZ:4.500000
1HZ:0.000000
2HZ:0.000000
3HZ:0.000001
4HZ:0.000000
5HZ:0.000000
6HZ:0.000000
7HZ:0.000000
8HZ:0.000000
9HZ:0.000000
10HZ:0.000000
11HZ:0.000000
12HZ:0.000000
13HZ:0.000000
14HZ:0.000000
15HZ:0.000000
16HZ:0.000000
17HZ:0.000000
18HZ:0.000000
19HZ:0.000001
20HZ:0.000000
21HZ:0.000001
22HZ:0.000000
23HZ:0.000000
24HZ:0.000000
25HZ:0.000000
26HZ:0.000000
27HZ:0.000000
28HZ:0.000000
29HZ:23.000000 //几乎只有29HZ不为0
30HZ:0.000000
31HZ:0.000000
32HZ:0.000000
33HZ:0.000000
34HZ:0.000000
35HZ:0.000000
36HZ:0.000000
37HZ:0.000000
38HZ:0.000000
39HZ:0.000000
40HZ:0.000000
41HZ:0.000000
42HZ:0.000000
43HZ:0.000000
44HZ:0.000000
45HZ:0.000000
46HZ:0.000000
47HZ:0.000000
48HZ:0.000000
49HZ:0.000000
50HZ:0.000000
51HZ:0.000000
52HZ:0.000000
53HZ:0.000000
54HZ:0.000000
55HZ:0.000000
56HZ:0.000000
57HZ:0.000000
58HZ:0.000000
59HZ:0.000000
60HZ:0.000000
61HZ:0.000000
62HZ:0.000000
63HZ:0.000000
输出数据