/*
* test2.cpp
*
* Created on: 2013年8月12日
* Author: zhijian
*/
#include <stdio.h>
#include <math.h>
#define RATE 20 //採樣頻率
#define N 20 //採樣點數
#define PI 3.1415926535
double src[N]; //輸入序列
double real[N]; //輸出序列實部
double image[N]; //輸出序列虛部
void DFT(){
double W = PI * 2 / N;
for(int i = 0;i<N;i++){
real[i] = 0;
image[i] = 0;
double temp = W * i;
for(int j = 0;j<N;j++){
real[i] += src[j] * cos(temp * j);
image[i] += src[j] * sin(temp * j);
}
}
}
/*
* 模擬波形(單一頻率)
*
* derta爲相位差
* f爲頻率
* dc爲直流分量
* A爲幅值
*/
void F(int derta,int f,double dc,double A){
//模擬波形
for(int i = 0;i<N;i++)
src[i] = A * sin((derta + i)*2*f*PI/RATE) + dc;
DFT();
printf("單一頻率輸入:\n頻率:%dHZ\n相位差:%d\n直流分量:%lf\n幅值:%lf------------\n",f,derta,dc,A);
printf("DFT---------------\n");
for(int i = 0;i<N/2;i++){
//i = 0 沒有鏡像,爲1 / N * |X[n]|
if(i==0)
printf("%dHZ 幅值:%lf\n",i*RATE/N,sqrt(real[i]*real[i] + image[i]*image[i])/N);
//i != 0 就有鏡像(i和N-i互爲鏡像)爲 2 / N * |X[n]|
else
printf("%dHZ 幅值:%lf\n",i*RATE/N,2*sqrt(real[i]*real[i] + image[i]*image[i])/N);
}
printf("鏡像頻率---------------\n");
for(int i = N/2;i<N;i++){
printf("%dHZ 幅值:%lf\n",i*RATE/N,2*sqrt(real[i]*real[i] + image[i]*image[i])/N);
}
printf("---------------\n\n");
}
int main(){
F(0,1,3,1);
F(10,1,3,1);
F(0,8,4,10);
F(10,8,4,10);
F(10,9,4,10);
//以下是採樣頻率過低的情況:
F(10,10,4,10);
F(10,11,4,10);
return 0;
}
/*
* 結論:1、某一頻率分量的幅值
* = 2/N * |X[n]|
* = 2/N * sqrt(real[n] * real[n] + image[n]*image[n])
*
* 之所以是2/N * |X[n]| 而不是公式上的 1/N *|X[n]|
* 是因爲頻譜的後半部分是前半部分的鏡像,各分一半,我們只取前面一半
*
* 2、頻率和下標的關係:
* 2/N * |X[n]|代表的頻率分量的頻率是 RATE * n / N (n最大爲N的一半,後一半爲鏡像)
*
* 3、採樣頻率須大於源最高頻率的2倍
*
*/