FFT和IFFT的长度

4

我有一些信号,它们位于不同的频率区域,我把它们相加成一个更大的信号。接下来,我使用FFTW对大信号执行FFT操作,并从中截取具体的FFT频段(信号所在的频率区域)。

例如:将1024个采样点的大信号进行FFT变换,信号的采样率为fs=200000

我按照以下方式计算给定起始和终止频率所在的具体频段位置:

tIndex.iStartPos = (int64_t) ((tFreqs.i64fstart) / (mSampleRate / uFFTLen));

例如,我得到了第一个信号被切断的16个频率箱。

现在我再次使用FFTW进行IFFT转换,并获得了16个复杂值(因为我为16个频率箱保留了向量)。

但是当我将提取的信号与MATLAB中的原始小信号进行比较时,我发现原始信号(是一个wav文件)具有xxxxx数据,而我的信号(我保存为原始二进制文件)仅具有16个复杂值。

那么我如何正确获得IFFT操作的长度以进行正确的转换?这里出了什么问题?

编辑 逻辑本身分为3个程序,每行在多线程环境中。因此,我在此发布一些伪代码:

ReadWavFile(); //returns the signal data and the RIFF/FMT header information
CalculateFFT_using_CUFFTW(); //calculates FFT with user given parameters, like FFT length, polyphase factor, and applies polyphased window to reduce leakage effect
GetFFTData(); //copy/get FFT data from CUDA device
SendDataToSignalDetector(); //detects signals and returns center frequency and bandwith for each sigal
Freq2Index(); // calculates positions with the returned data from the signal detector
CutConcreteBins(position);
AddPaddingZeroToConcreteBins(); // adds zeros till next power of 2
ApplyPolyphaseAndWindow(); //appends the signal itself polyphase-factor times and applies polyphased window
PerformIFFT_using_FFTW();
NormalizeFFTData();
Save2BinaryFile();

-->然后在MATLAB中分析数据(目前正在工作中)。


请问您能否发布您的代码?这样可以使您的描述更清晰,也有可能是代码没有正确地遵循您的描述。 - buzjwa
1
你有什么采样率为200000的wav文件?太疯狂了。 - dmedine
2
输入到逆傅里叶变换(IFFT)的长度必须与您想要获得的输出长度相同(例如,1024,与您放入第一个傅里叶变换的数据长度相同),不能更短(例如16而不是1024)。如果您希望获得实数结果,输入到逆傅里叶变换(IFFT)也必须是共轭对称的。 - hotpaw2
2个回答

2
如果您有一个由1024个样本组成的真实信号,那么可以通过将频谱乘以矩形窗口然后进行IFFT来获得16个感兴趣的频率bin的贡献。这基本上相当于:
  1. 在感兴趣的频率bin之前和之后用零填充缓冲区
  2. 将感兴趣的频率bin复制到相同位置的缓冲区中
  3. 如果使用全频谱表示(如果您正在使用fftw_plan_dft_1d(..., FFTW_BACKWARD,...进行逆变换),则计算上半部分频谱的共轭对称性(或者只需使用半频谱表示并通过fftw_plan_dft_c2r_1d执行逆变换)。
话虽如此,与仅在频域中使用矩形窗口相比,使用专门设计的滤波器可以获得更好的频率分解。

我是否正确理解: 创建一个大小为FFT长度的零初始化复杂缓冲区(我使用的信号是复杂信号),然后将具体的频率线复制到与原始缓冲区相同的位置。 对于窗函数,我已经按照用户要求使用了多相滤波器组技术(https://casper.berkeley.edu/wiki/The_Polyphase_Filter_Bank_Technique),使用DPSS或Kaiser。 - mbed_dev
如果您已经隔离了感兴趣的频率内容(通过显著衰减其他频率),那么就没有必要削减那些频率。具有正确参数的多相滤波器可以为您完成这项工作。 - SleuthEye

1
FT的输出长度等于输入长度。我不知道你是如何得到16个bin的,1024个输入的FT有1024个bin。对于实数输入(非复数),1024个bin将在512/513周围对称相同,因此您的FFT库可能仅返回实数输入的较低512个bin。但这仍然比16个bin多。

进行IFFT时,您可能需要填充所有1024个bin,因为它通常不会假设其输出将成为实信号。但这只是镜像下面的512个bin的问题。


这16个箱子是从完整频谱中剪切/提取出来的具体箱子,以获取检测到的信号。但感谢您提示用完整FFT长度填充缓冲区。 - mbed_dev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接