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
輸出數據