/*
* 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倍
*
*/