FFT和IFFT的长度

Length of FFT and IFFT

我将一些信号加起来形成一个更大的信号,其中每个信号都位于不同的频率区域。 现在,我用 FFTW 对大信号进行 FFT 运算,并切出具体的 FFT bin(信号所在的位置)。

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

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

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

例如我得到的第一个信号被切掉了 16 个 bin。 现在,我再次使用 FFTW 进行 IFFT 变换并取回 16 个复数值(因为我为 16 个 bin 保留了向量)。

但是当我在 MATLAB 中将提取的信号与原始小信号进行比较时,我可以看到原始信号(是一个 wav 文件)有 xxxxx 数据和我的信号(我保存为原始二进制文件)只有 16 个复数值。

那么如何获取IFFT运算的长度才能正确变换呢?这里有什么问题?

编辑 逻辑本身分为 3 个程序,每行都在多线程环境中。出于这个原因,我 post 这里有一些伪代码:

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中分析数据(目前正在工作中)

FT的输出长度等于输入长度。我不知道你是怎么得到 16 个垃圾箱的; 1024 个输入的 FT 是 1024 个 bin。现在对于实际输入(不复杂),1024 个箱子将在 512/513 左右镜像相同,因此您的 FFT 库可能 return 只有较低的 512 个箱子用于实际输入。尽管如此,还是超过了 16 个箱子。

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

如果您有一个由 1024 个样本组成的真实信号,则可以通过将频谱乘以矩形 window 然后进行 IFFT 来获得 16 个感兴趣的频率仓的贡献。这基本上相当于:

  1. 在感兴趣的频率区间前后用零填充缓冲区
  2. 在该缓冲区的相同位置复制感兴趣的频率仓
  3. 如果使用全谱表示(如果您使用 fftw_plan_dft_1d(..., FFTW_BACKWARD,... 进行逆变换),计算上半部分频谱的厄米特对称性(或者简单地使用半谱表示并执行通过 fftw_plan_dft_c2r_1d 的逆变换)。

也就是说,通过使用专门设计的滤波器而不是仅在频域中使用矩形 window,您将获得更好的频率分解。