试图理解fft(快速傅里叶变换)常我用(偷盗)(回收)

输入一系列的512个数据点是一样的波形。测试数据的产生是进入这个阵列。fft将此列入频域。试图理解关系之间的频率、周期、采样率和位置在fft阵列。我要说明与实施:

========================================

采样率是1000个样本。生成的一套样本在10赫兹.

输入排列的峰值在arr(28),arr(128),arr(228所)...期=100个采样点

峰值在fft阵列是在指数6(不包括一个巨大的价值在0)

========================================

采样率是8000样品/s 产生设置的样品在440Hz

输入阵列峰值包括arr(7),arr(25),arr(43),arr(61)...期=18样点

峰值在fft阵列是在指数29(不包括一个巨大的价值在0)

========================================

我怎么相关指数的高峰期在fft阵列的频率?

有帮助吗?

解决方案

如果忽略虚部,频率分布在二进制位上是线性的:

频率@i =(采样率/ 2)*(i / Nbins)。

因此,对于您的第一个示例,假设您有256个分档,最大分档对应的频率为1000/2 * 6/256 = 11.7 Hz。 由于您的输入为10Hz,我猜测箱5(9.7Hz)也有一个很大的组件。 为了获得更好的准确性,您需要采取更多样本,以获得更小的容器。

你的第二个例子给出了8000/2 * 29/256 = 453Hz。再次,关闭,但你需要更多的垃圾箱。 你的分辨率只有4000/256 = 15.6Hz。

其他提示

如果您要提供样本数据集,将会很有帮助。

我的猜测是你有所谓的抽样工件。 DC(频率0)处的强信号表明情况就是这样。

您应该始终确保输入数据中的平均值为零 - 找到平均值并在调用fft之前从每个采样点中减去它是好的做法。

同样,您必须小心采样窗口工件。重要的是第一个和最后一个数据点接近于零,否则“步骤”是“步骤”。从采样窗口的外部到内部具有以不同频率注入大量能量的效果。

最重要的是,进行fft分析需要更多的关注,而不仅仅是回收某处发现的fft例程。

以下是问题中描述的10Hz信号的前100个采样点,按摩以避免采样伪像

> sinx[1:100]
  [1]  0.000000e+00  6.279052e-02  1.253332e-01  1.873813e-01  2.486899e-01  3.090170e-01  3.681246e-01  4.257793e-01  4.817537e-01  5.358268e-01
 [11]  5.877853e-01  6.374240e-01  6.845471e-01  7.289686e-01  7.705132e-01  8.090170e-01  8.443279e-01  8.763067e-01  9.048271e-01  9.297765e-01
 [21]  9.510565e-01  9.685832e-01  9.822873e-01  9.921147e-01  9.980267e-01  1.000000e+00  9.980267e-01  9.921147e-01  9.822873e-01  9.685832e-01
 [31]  9.510565e-01  9.297765e-01  9.048271e-01  8.763067e-01  8.443279e-01  8.090170e-01  7.705132e-01  7.289686e-01  6.845471e-01  6.374240e-01
 [41]  5.877853e-01  5.358268e-01  4.817537e-01  4.257793e-01  3.681246e-01  3.090170e-01  2.486899e-01  1.873813e-01  1.253332e-01  6.279052e-02
 [51] -2.542075e-15 -6.279052e-02 -1.253332e-01 -1.873813e-01 -2.486899e-01 -3.090170e-01 -3.681246e-01 -4.257793e-01 -4.817537e-01 -5.358268e-01
 [61] -5.877853e-01 -6.374240e-01 -6.845471e-01 -7.289686e-01 -7.705132e-01 -8.090170e-01 -8.443279e-01 -8.763067e-01 -9.048271e-01 -9.297765e-01
 [71] -9.510565e-01 -9.685832e-01 -9.822873e-01 -9.921147e-01 -9.980267e-01 -1.000000e+00 -9.980267e-01 -9.921147e-01 -9.822873e-01 -9.685832e-01
 [81] -9.510565e-01 -9.297765e-01 -9.048271e-01 -8.763067e-01 -8.443279e-01 -8.090170e-01 -7.705132e-01 -7.289686e-01 -6.845471e-01 -6.374240e-01
 [91] -5.877853e-01 -5.358268e-01 -4.817537e-01 -4.257793e-01 -3.681246e-01 -3.090170e-01 -2.486899e-01 -1.873813e-01 -1.253332e-01 -6.279052e-02

这是fft频域的绝对值

 [1] 7.160038e-13 1.008741e-01 2.080408e-01 3.291725e-01 4.753899e-01 6.653660e-01 9.352601e-01 1.368212e+00 2.211653e+00 4.691243e+00 5.001674e+02
[12] 5.293086e+00 2.742218e+00 1.891330e+00 1.462830e+00 1.203175e+00 1.028079e+00 9.014559e-01 8.052577e-01 7.294489e-01

我在数学和信号处理方面也有点生疏,但附加信息我可以试一试。

如果您想知道每个箱的信号能量,您需要复杂输出的幅度。所以只看实际输出是不够的。即使输入只是实数。对于每个bin,输出的幅度是sqrt(real ^ 2 + imag ^ 2),就像毕达哥拉斯一样: - )

bins 0到449是从0 Hz到500 Hz的正频率。箱500到1000是负频率,应该与实信号的正值相同。如果您处理一个缓冲区,则每隔一个频率和数组索引排列很好。因此,指数6处的峰值对应于6Hz,因此有点奇怪。这可能是因为您只查看实际输出数据,并将实数和虚数数据组合在一起,得到索引10处的预期峰值。频率应线性映射到二进制位。

0处的峰值表示DC偏移。

它已经有一段时间,因为我已经做了FFT的但是这里我记得

FFT通常需要复杂的数字为输入和输出。所以我真的不知道该如何真正和想象的一部分输入和输出地图的阵列。

我真的不明白你在做什么。在第一个例子你说你过程中样本的缓冲区在10赫兹一样速率1000赫兹?所以你应该有10缓冲区每秒有100个样品中的每一个。我不明白怎么你的输入阵列可以至少228样长。

通常第一半的缓冲器的输出是频率从0频率(=dc偏)至1/2的采样率。和第2次半是负面的频率。如果你输入是唯一真实的数据与0的假想的信号正面和负面的频率是相同的。的关系的现实/想象上的信号出包含阶段的信息输入您的信号。

bin i的频率为i *(samplerate / n),其中n是FFT输入窗口中的采样数。

如果您正在处理音频,由于音高与频率对数成正比,音频的音高分辨率会随着频率的增加而增加 - 很难准确地解析低频信号。为此,您需要使用更大的FFT窗口,这会降低时间分辨率。对于给定的采样率,存在频率与时间分辨率的权衡。

你提到一个大值为0的bin - 这是频率为0的bin,即DC组件。如果这个很大,那么大概你的价值观通常是正面的。 Bin n / 2(在你的情况下为256)是奈奎斯特频率,是采样率的一半,这是在此速率下采样信号中可以分辨的最高频率。

如果信号是真实的,则区间n / 2 + 1到n-1将分别包含区间n / 2-1到1的复共轭。 DC值仅出现一次。

正如其他人所说,样本在频域中间隔相等(不是对数)。

例如1,你应该得到这个:

alt text http://home.comcast.net/~kootsoop/images /SINE1.jpg

对于另一个例子,你应该得到

alt text http://home.comcast.net/~kootsoop/images /SINE2.jpg

因此,关于峰值位置,您的答案似乎都是正确的。

我没有得到的是大型DC组件。您确定要生成正弦波作为输入吗?输入是否为负数?对于正弦波,如果您获得足够的周期,DC应该接近于零。

另一种途径是制作您正在寻找的每个音符中心频率的 Goertzel算法

一旦算法的一个实现工作,你可以使它需要参数来设置它的中心频率。有了这个,您可以轻松地运行其中的88个或您在集合中需要的内容并扫描峰值。

Goertzel算法基本上是单个bin FFT。使用这种方法,你可以按照音符自然地放置你的箱子。

来自维基百科的一些伪代码:

s_prev = 0
s_prev2 = 0
coeff = 2*cos(2*PI*normalized_frequency);
for each sample, x[n],
  s = x[n] + coeff*s_prev - s_prev2;
  s_prev2 = s_prev;
  s_prev = s;
end
power = s_prev2*s_prev2 + s_prev*s_prev - coeff*s_prev2*s_prev;

表示前两个样本的两个变量将保留用于下一次迭代。然后,这可以在流应用程序中使用。我想也许功率计算也应该在循环内部。 (但是在Wiki文章中没有这样描述。)

在音调检测情况下,将有88个不同的系数,88对先前的样本,并将产生88个功率输出样本,指示该频率仓中的相对水平。

WaveyDavey说,他正在通过计算机的音频硬件从麦克风中捕获声音,但他的结果并非以零为中心。这听起来像是硬件问题。它应该以零为中心。

当房间安静时,来自声音API的值流应非常接近0幅度,环境噪声略有+ - 变化。如果房间中存在振动声音(例如钢琴,长笛,声音),则数据流应该显示基本上基于正弦波的正波和负波,并且平均值接近零。如果不是这种情况,系统会有一些恐惧!

-Rick

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top