我正在测试我对离散傅立叶变换的了解。
我现在正在测试的是如何使用 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 并得到两个向量,一个包含实部,一个包含虚部。我知道在每个向量里面我都会有这个:
为了看看我是否正确,我检查了 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])
???
最佳答案
你上面的大纲看起来很重要......计算给定垃圾箱的大小
mag = 2.0 * math.Sqrt(real*real+imag*imag) / number_of_samples
其中 number_of_samples 是馈入 fft 调用的数组的长度……执行 fft 的美妙之处在于,您可以对那组(频率、幅度、相移)应用逆傅立叶变换以返回源时域信号...这样做是验证您的流程正确的好方法傅立叶变换和逆傅立叶变换的魔法 - 一个例子:
你从一个浮点数组开始,它代表了一些像音频、股票市场指数或任何时间序列这样摆动的东西……这是时域表示,因为它是曲线上的一组点,其中时间是你从左到右的 X 轴并且上下 Y 轴是曲线的高度......然后你把这个数组输入到一个 fft api 调用中,它会在它的频域表示中返回给你相同的信息......它的相同信息只是在一个不同的表示......在频率域中,您将拥有一个数组,其中元素 0 始终是每秒 0 个周期的频率(DC 偏移),然后当您遍历数组时,您会使用公式增加 freq
incr_freq := sample_rate / number_of_samples
所以在 fft 调用生成的复数数组中,每个元素都是给定频率的数据,其中每个元素只是一个复数……简单来说,这个频率域表示只是一组频率,每个频率由一个复数体现数字 (A + Bi) 可用于计算该频率的幅度和相移现在是有趣的部分……如果您将此频率域数组发送到逆傅立叶变换中,您将获得时域表示的原始数据
然后你可以自由地做相反的事情
请注意,在该进程中,您从数组 myAudio_TD 开始,该数组被发送到 fft 调用中,然后进入反向 fft 调用,该调用神奇地返回给您原始的 myAudio_TD
要查看从 fft 调用返回的复杂数组的完整解析,其中包括奈奎斯特极限的概念,请参见 Get frequency with highest amplitude from FFT
关于swift - 如何计算 DFT 中每个 bin 的能量?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55430065/