FFTW:经过 IFFT 后的信号由噪声组成
完成 FFT 和 IFFT 后,我只能听到耳机中的噪音...这是代码:
double* spectrum = new double[n];
fftw_plan plan;
plan = fftw_plan_r2r_1d(n, data, spectrum, FFTW_REDFT10, FFTW_ESTIMATE);
fftw_execute(plan);
fftw_destroy_plan(plan);
plan = fftw_plan_r2r_1d(n, spectrum, data, FFTW_REDFT01, FFTW_ESTIMATE);
fftw_execute(plan);
fftw_destroy_plan(plan);
也许我选择了错误的 FFT 类型?
PS数据是初始信号
更新
好的,所以现在的代码是
fftw_complex* spectrum = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n);
fftw_plan plan;
plan = fftw_plan_dft_r2c_1d(n, data, spectrum, FFTW_ESTIMATE);
fftw_execute(plan);
fftw_destroy_plan(plan);
plan = fftw_plan_dft_c2r_1d(n, spectrum, data, FFTW_ESTIMATE);
fftw_execute(plan);
fftw_destroy_plan(plan);
问题仍然相同,我的数据数组已损坏。
更新 #2
所以,问题出在我的变换大小和标准化上。如果我使用实数到实数 FFTW_REDFT10 和 FFTW_REDFT01 变换,我需要使用哪些变换大小? 2*n?还是别的什么?然后我需要通过将每个元素除以 2*n 来标准化我的输出信号?
感谢大家的回复。
更新 #3
感谢大家的再次回复。在你的帮助下我已经解决了这个问题。这是工作代码:
// FFT
fftw_complex* spectrum = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n);
fftw_plan plan;
plan = fftw_plan_dft_r2c_1d(n, data, spectrum, FFTW_ESTIMATE);
fftw_execute(plan);
fftw_destroy_plan(plan);
// some filtering here
// IFFT
plan = fftw_plan_dft_c2r_1d(n, spectrum, data, FFTW_ESTIMATE);
fftw_execute(plan);
fftw_destroy_plan(plan);
// normalizing
for (int i = 0; i < n; i++) {
data[i] = data[i] / n;
}
After doing FFT and IFFT I can hear only noise in my headphones... Here is the code:
double* spectrum = new double[n];
fftw_plan plan;
plan = fftw_plan_r2r_1d(n, data, spectrum, FFTW_REDFT10, FFTW_ESTIMATE);
fftw_execute(plan);
fftw_destroy_plan(plan);
plan = fftw_plan_r2r_1d(n, spectrum, data, FFTW_REDFT01, FFTW_ESTIMATE);
fftw_execute(plan);
fftw_destroy_plan(plan);
Maybe I've chosen wrong FFT type?
P.S. data is the initial signal
UPDATE
Ok, so now the code is
fftw_complex* spectrum = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n);
fftw_plan plan;
plan = fftw_plan_dft_r2c_1d(n, data, spectrum, FFTW_ESTIMATE);
fftw_execute(plan);
fftw_destroy_plan(plan);
plan = fftw_plan_dft_c2r_1d(n, spectrum, data, FFTW_ESTIMATE);
fftw_execute(plan);
fftw_destroy_plan(plan);
The problem remains the same, my data array is corrupted.
UPDATE #2
So, the problem is in my transform size and normalizing. If I user real-to-real FFTW_REDFT10 and FFTW_REDFT01 transforms which transform sizes i need to use? 2*n? Or something else? And then I need to normalize my output signal by dividing each element by 2*n?
Thank to all for replying.
UPDATE #3
Thanks to all for replying again. I've solved the problem with your help. Here is the working code:
// FFT
fftw_complex* spectrum = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n);
fftw_plan plan;
plan = fftw_plan_dft_r2c_1d(n, data, spectrum, FFTW_ESTIMATE);
fftw_execute(plan);
fftw_destroy_plan(plan);
// some filtering here
// IFFT
plan = fftw_plan_dft_c2r_1d(n, spectrum, data, FFTW_ESTIMATE);
fftw_execute(plan);
fftw_destroy_plan(plan);
// normalizing
for (int i = 0; i < n; i++) {
data[i] = data[i] / n;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不明白你在哪里标准化你的输出。您必须将输出值除以数据数组中的元素数量,以将数据标准化回原始值范围。
请参阅 FFTW 手册 4.8.2,最后一段(我有 V3.2 手册)。
I don't see where you are normalizing your output. You must divide your output values by the number of elements in the data array to normalize the data back to original range of values.
See the FFTW Manual 4.8.2, last paragraph (I have V3.2 manual).
您正在执行实数到实数的 FFT(实际上,FFTW 正在内部计算 DCT 或离散余弦变换,但它会产生相同的结果)。请注意输出频谱数组中计算的点数。实数到实数变换仅将 n/2+1 个实际值放入数组中。
正如您所指出的,如果您计算实数到复数变换,您将生成频谱的两侧(它们是彼此的复共轭),但您的输出数组需要调整大小以容纳复数加上 DC 结果。
You're performing a real-to-real FFT (actually, FFTW is computing a DCT, or discrete cosine transform, internally, but it results in the same thing). Be careful about the number of points that are computed in the output spectrum array. A real-to-real transform only has n/2+1 actual values placed into the array.
If, as you indicated, you compute a real-to-complex transform, you will generate both sides of the spectrum (they are complex conjugates of each other) but your output array will need to be resized to accommodate complex values plus the DC result.