3

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

来自 KissFFT 的自述文件:

真正的(即不复杂的)优化代码只适用于偶数长度的ffts。它并行执行两个半长 FFT(打包成 real&imag),然后通过 twiddling 组合它们。结果是从 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] 是第二个,依此类推。是这样吗?

4

2 回答 2

4

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

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

提示:如果您使用 float 作为数据类型(默认),您可以将输出数组转换为 float complex* (c99) 或 std::complex* (c++)。Kiss_fft_cpx 结构的包装是兼容的。它默认不使用这些的原因是因为kiss_fft 可以与除浮点和双精度之外的其他类型以及缺少这些功能的旧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;
}
于 2011-11-02T11:15:57.840 回答
0

fftr 结果的 r[1] 和 i[1] 构成一个复向量。它们一起为您提供了第一个频率区间的幅度(2 个分量的平方和的平方和)和相位(通过 atan2())。

于 2011-11-01T23:09:11.643 回答