【发布时间】:2014-09-11 10:26:51
【问题描述】:
我正在尝试计算 20hz 的正弦波的 DFT。
首先我用 20 赫兹的正弦函数的 10 个周期填充一个 std::vector:
std::vector<double> sinx;
double samplerate = 1000.0;
double frequency = 20.0;
double num_cycles = 10.0;
for (int i=0; i<samplerate/frequency*num_cycles; i++){
sinx.push_back(sin(2.0*M_PI*((double)i)*frequency/samplerate));
}
double N = sinx.size();
然后我启动 FFTW 输入和输出数组以及 FFTW 计划:
fftw_complex *in, *out;
fftw_plan p;
in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)* N);
out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
然后我用正弦波函数值填充输入数组:
for (int i=0; i<N; i++){
in[i][0] = sinx[i];
}
然后我计算 FFT:
fftw_execute(p);
计算 FFT 后,我检查结果并清理。
double hz_per_index = samplerate/2.0/N*num_cycles;
for (int i=0; i<N/num_cycles; i++){
std::cout<<"hz: "<<hz_per_index*i<<" out: "<<fabs(out[i][0])<<" "<<out[i][1]<<" in: "<<in[i][0]<<std::endl;
}
我预计会在 20hz 左右出现尖峰,但根本没有尖峰。所有返回的值总是接近零、无穷大或负无穷大。我的第一个想法是输入覆盖了自己,但是在计算后检查输入,它是正确的。我试过在不同的模式下运行 FFTW,FFTW_FORWARD、FFTW_BACKWARD、FFTW_ESTIMATE、FFTW_RELATIVE,没有任何帮助。我尝试在不同的频率、采样率、周期数下计算不同的正弦函数。
可悲的是,我能够让它工作一次。然后我继续工作,发现它不起作用,然后重新打开可以工作的文件,现在它不再工作了!
还有其他人遇到过这个吗?
编辑:根据建议的新代码
它仍然无法正常工作。我尝试将复数的虚部初始化为 0,但我仍然遇到同样的问题,所以这里是利用 fftw 库的实数输入/复数输出函数的代码。
我基本上得到了 0 的一切。 这是输入的所有 5 个周期的完整输出,显示了输入、输出和 hz 值:
https://gist.github.com/anonymous/ed419f4cfb43887c810e
double *in;
fftw_complex* out;
fftw_plan p;
std::vector<double> sinx;
double samplerate = 1000.0;
double frequency = 20.0;
double num_cycles = 5.0;
for (int i=0; i<samplerate/frequency*num_cycles; i++){
sinx.push_back(sin(2.0*M_PI*((double)i)*frequency/samplerate));
}
int N = sinx.size();
in = (double*) fftw_malloc(sizeof(double)* N);
out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
p = fftw_plan_dft_r2c_1d(N, in, out, FFTW_ESTIMATE);
for (int i=0; i<N; i++){
in[i] = sinx[i];
}
fftw_execute(p);
double hz_per_index = samplerate/2.0/N*num_cycles;
for (int i=0; i<N; i++){
std::cout<<"hz: "<<hz_per_index * (i % (int)(N/num_cycles))<<" out: "<<out[i][0]<<" in: "<<in[i]<<std::endl;
}
fftw_destroy_plan(p);
fftw_free(in); fftw_free(out);
return 0;
}
【问题讨论】:
-
您的输出函数只输出 500 个结果中的前 50 个。似乎您正试图输出每 5 个结果或其他内容。
-
请将
N设为整数类型。 -
我只输出了输入的第一个完整周期。现在代码输出所有周期,我创建了一个输出要点,显示了周期的输入、输出和相应的 hz 值。
标签: c++ signal-processing fft fftw dft