如何计算 DFT 中每个 bin 的能量?

How to calculate the energy per bin in a DFT?

我正在测试我对离散傅立叶变换的了解。

我现在正在测试的是如何使用DFT计算波的中心频率。

为此,我使用以下代码创建了一个正弦数据:

// create a 100 Hz wave with a sampling rate of 512 samples per second
var data : [Double] = []
for i in 0...511 {
  let t = Double(i) * 100/256
  let f = 10 * sin(2 * Double.pi * t)
  data.append(f)
}

然后我在 data 上进行 DWT 并得到两个向量,一个包含实部,一个包含虚部。

我知道在每个向量里面我会有这个:

  1. 数据有 512 个样本
  2. 因此,从 0 到 256 的项目将是正频率
  3. 以及从 257 到 511 的项目,负频率
  4. 我可以丢弃负频率并保留正频率,从 bin 0 到 255。
  5. Bin 0 是直流电。我可以丢弃它。
  6. Bin 255 将为 256Hz,因为它是采样率的一半。

为了看看我是否做对了,我检查了 256 个 bin 并寻找最高级。根据以下公式,具有最高幅度的 bin 将是 K,我可以找到信号频率:

freq = (K + 1) * fps / N

K+1 因为我的第一个索引是 0 并且我已经从数组中丢弃了 DC,其中 N 是样本数。

最大的问题是:如何计算每箱的能量?

E[i] = sqrt(realPart[i] * realPart[i] + imaginaryPart[i] * imaginaryPart[i])

????

你上面的大纲看起来很重要......计算给定 bin 的大小

mag = 2.0 * math.Sqrt(real*real+imag*imag) / number_of_samples

其中 number_of_samples 是馈入 fft 调用的数组的长度...进行 fft 的美妙之处在于,您可以在该组上应用傅立叶逆变换 ( 频率、幅度、相移) return 返回您的源时域信号...这样做是验证您的过程是否正确的好方法

傅里叶变换和傅里叶逆变换的魔力——一个例子:

你从一个浮点数组开始,它表示像音频、股票市场指数或任何时间序列这样的东西......这是时域表示,因为它是曲线上的一组点,时间就是你的时间从左到右的 X 轴和上下 Y 轴是曲线的高度...然后将此数组输入 fft api 调用,该调用将 return 返回给您相同的信息频域表示...它的相同信息只是在不同的表示中...在频域中,您将拥有一个数组,其中元素 0 始终是每秒 0 个周期的频率(DC 偏移),然后当您遍历该数组时,您使用公式

增加频率
incr_freq := sample_rate / number_of_samples

所以在 fft 调用生成的复数数组中,每个元素都是给定频率的数据,其中每个元素只是一个复数...简单来说,这个频域表示只是一组频率,每个由复数 (A + Bi) 体现的频率,可用于计算该频率的幅度和相移

现在是有趣的部分...如果您将此频域数组发送到逆傅立叶变换中,您将取回以时域表示的原始数据

myAudio_TD ( time domain ) --> send to fft --> myAudio_FD ( freq domain )

然后你可以像

那样自由地做相反的事情

myAudio_FD ( freq domain ) --> send to inverse fft --> myAudio_TD ( time domain )

请注意,在该进程中,您从一个数组 myAudio_TD 开始,它被发送到一个 fft 调用,然后进入一个反向 fft 调用,它神奇地 return 返回给您原来的 myAudio_TD

要查看复杂数组的完整解析 return 来自 fft 调用,其中包括奈奎斯特极限的概念,请参阅 Get frequency with highest amplitude from FFT