fft - 如何解释 KissFFT 的 kiss_fftr(真实信号的 FFT)函数的结果

标签 fft kissfft

我正在使用 KissFFT 的真实函数来转换一些真实的音频信号。我很困惑,因为我输入了带有 nfft 样本的真实信号,但结果是 nfft/2+1 复杂 频率仓。

来自 KissFFT 的自述文件:

真正的(即不复杂的)优化代码只适用于偶数长度的 ffts。它并行执行两个半长 FFT(打包成 real&imag),然后通过旋转将它们组合起来。结果是从 DC 到 Nyquist 的 nfft/2+1 复频率区间。

所以我对如何解释结果没有具体的了解。我的假设是数据被打包成 r[0]i[0]r[1]i[1]...r[nfft/2]i[nfft/2],其中 r[ 0] 将是 DC,i[0] 是第一个频率仓,r[1] 第二个,依此类推。是这样吗?

最佳答案

是的。 kiss_fftr 只生成 Nfft/2+1 个 bin 的原因是因为实数信号的 DFT 是共轭对称的。对应于负频率的系数( -pi:0 或 pi:2pi ,无论哪种方式都喜欢考虑它),是来自 [0:pi 的共轭系数。

请注意 out[0] 和 out[Nfft/2] bin(DC 和 Nyquist)的虚部为零。我已经看到一些库将这两个真实部分打包在第一个复合体中,但我认为这是违反契约(Contract)的行为,会导致难以诊断、几乎是正确的错误。

提示:如果您使用 float 作为数据类型(默认),您可以将输出数组转换为 float complex* (c99) 或 std::complex* (c++)。 kiss_fft_cpx 结构的封装是兼容的。它默认不使用这些的原因是因为 kiss_fft 与 float 和 double 之外的其他类型一起工作,以及在缺少这些功能的旧 ANSI C 编译器上工作。

这是一个人为的例子(假设 c99 编译器和 type==float)

float get_nth_bin_phase(const float * in, int nfft, int whichbin )
{
  kiss_fftr_cfg st = kiss_fftr_alloc(1024,0,0,0);
  float complex * out = malloc(sizeof(float complex)*(nfft/2+1));
  kiss_fftr(st,in,(kiss_fft_cpx*)out);

  whichbin %= nfft;
  if ( whichbin <= nfft/2 ) 
    ph = cargf(out[whichbin]);
  else
    ph = cargf( conjf( out[nfft-whichbin] ) );
  free(out);
  kiss_fft_free(st);
  return ph;
}

关于fft - 如何解释 KissFFT 的 kiss_fftr(真实信号的 FFT)函数的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7972952/

相关文章:

python - 使用傅里叶变换做卷积?

c++ - kissfft - 逆实数 FFT 给出 NaN

opencv - 等效于FFTW_REDFT01的FFTW fftwf_plan_r2r_2d()

c++ - 反转 FFT 时没有得到准确的数据

android - 使用原生 C Kiss_fft.c 在 android 中计算 fft

ios - FFT的大小实际上意味着什么

matlab - 使用 fft 和 ifft 改变频率不使用整数

在倍频程上绘制 FFT

arm - ARM CMSIS DSP fft 函数的正确 FFT 长度

fft - KissFFT 与 DSPIC - 舍入误差