我正在测试有关离散傅立叶变换的知识。
我现在正在测试的是如何使用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将为K
,我可以找到信号频率:
freq = (K + 1) * fps / N
K+1
,因为我的第一个索引是0
,并且我已经从数组中丢弃了DC,其中N
是样本数。
最大的问题是:如何计算每个仓的能量?
E[i] = sqrt(realPart[i] * realPart[i] + imaginaryPart[i] * imaginaryPart[i])
????
答案 0 :(得分:4)
上面的轮廓着眼于点...以计算给定bin的大小
mag = 2.0 * math.Sqrt(real*real+imag*imag) / number_of_samples
其中number_of_samples是输入到fft调用中的数组的长度...进行fft的美丽之处在于,您可以对那组(频率,幅度,相移)应用傅立叶逆变换以返回源时域信号...这样做是验证您的过程是否正确的好方法
傅立叶变换和傅立叶逆变换的魔术-示例:
您从一个浮点数组开始,该数组代表诸如音频,股市指数或任何时间序列之类的摆动……这是时域表示,因为它是曲线上的一组点,您可以在其中留下时间右X轴和上,下Y轴是曲线的高度...然后将此数组输入到fft api调用中,该调用将在频域表示中返回相同的信息...其相同的信息只是以不同的表示形式...在freq域中,您将拥有一个数组,其中元素0始终为每秒0个周期的频率(DC偏移),然后在数组中进行迭代时,您可以使用公式
来增加freqincr_freq := sample_rate / number_of_samples
因此,在fft调用生成的复数数组中,每个元素都是给定频率的数据,其中每个元素只是一个复数...简单来说,该频率域表示只是一组频率,每个频率都体现了复数(A + Bi)可以用来计算频率的幅度和相移
现在是有趣的部分...如果将此freq域数组发送到逆傅立叶变换,您将获得时域表示形式的原始数据
myAudio_TD(时域)->发送到fft-> myAudio_FD(频率域)
然后您可以自由地按照相反的方式进行操作
myAudio_FD(频率域)->发送到逆fft-> myAudio_TD(时域)
请注意,在此过程中,您先从数组myAudio_TD开始,然后将其发送到fft调用中,然后发送到fft反向调用中,该魔术神奇地返回给您原始的myAudio_TD
要查看从fft调用返回的复杂数组的完整解析,其中包括奈奎斯特限制的概念,请参见Get frequency with highest amplitude from FFT