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

时间:2011-11-01 21:09:22

标签: fft kissfft

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

来自KissFFT的自述文件:

真实(即非复杂)优化代码仅适用于偶数长度的fft。它并行执行两个半长FFT(打包成实时和图像),然后通过twiddling组合它们。结果是从DC到奈奎斯特的nfft / 2 + 1复频率区间。

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

2 个答案:

答案 0 :(得分:4)

是。 kiss_fftr仅产生Nfft / 2 + 1区间的原因是因为实信号的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与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;
}

答案 1 :(得分:0)

r [1]和fftr结果的i [1]构成复数向量。它们一起给你一个幅度(2个分量的平方和的sqrt)和第一个频率仓的相位(通过atan2())。