具有 2 个 cosf() 周期的信号的 FFT 输出

FFT outptut for a signal with 2 cosf() cycles

我正在使用 ZeroFFT 库转换信号。我从中得到的结果不是我直觉上期望的结果。

作为测试,我为 FFT 算法提供了一个缓冲区,其中包含两个完整的余弦循环:

其中采样超过 512 个样本。

作为 int16_t 值提供。我期望得到的是 256 个振幅,其值为 [ 0, 4095, 0, 0, ..., 0 ].

相反,这是结果: 2 2052 4086 2053 0 2 2 2 1 2 2 2 4 4 3 4...

而且它变得更奇怪了!如果我给它输入 相同的信号,但移动 (所以 sinf() 超过 0 .. 4*pi 而不是 cosf() 函数)我得到一个完全不同的结果: 4 10 2 16 2 4 4 4 2 2 2 3 2 4 3 4

这引发了问题:

1。周期相同的正弦信号和余弦信号不是包含完全相同的频率吗?

2。如果我给它一个恰好有 2 个余弦周期的缓冲区,除了 1 个频率之外,傅立叶变换不会导致全为零吗?

我将测试信号生成为:

static void setup_reference(void)
{
  for (int i=0; i<CAPTURESZ; ++i)
  {
    const float phase = 2 * 3.14159f * i / (256.0f);
    reference_wave[i] = (int16_t) (cosf(phase) * 0x7fff);
  }
}

并将 ZeroFFT function 称为:

ZeroFFT(reference_Wave, CAPTURESZ);

注意:ZeroFFT 文档声明应用了 Hanning window。

开窗会导致一些频谱泄漏。包括 window 函数,波浪现在看起来像这样:

If I feed it a buffer with exactly 2 cycles of cosine, wouldn't the Fourier transform result in all zeros, except for 1 frequency?

是的,如果您没有 windowing 就这样做。实际上是两个频率:您期望的正频率和等效的负频率,尽管并非所有 FFT 函数都会在其输出中包含负频率(对于实数输入,结果为 Hermitian-symmetric,没有额外信息在负频率)。出于实际原因,由于输入信号和 FFT 计算都不准确,因此您可能不会在其他任何地方得到准确的 zero,但它应该接近 - 这主要是浮点输出的问题.

顺便说一句,我并不是说 windowing 不好,但在这种特殊情况下(完美的周期性输入)它对你不利。

至于正弦波,结果的幅度应该是相似的(在合理范围内-不应期望准确),但是对您使用的 FFT 函数的评论提到

The complex portion is discarded, and the real values are returned.

虽然相移不会改变幅度,但会改变结果的相位,因此也会改变它们的实数分量。