我想获取音频PCM数据并在其中找到峰值。具体来说,我想返回峰值出现的频率和时间。
我对此的理解是我必须将PCM数据转储并放入一个数组中,将其设置为实数值,将复杂的部分设置为0.然后进行FFT,我得到一个数组。如果数组中的每个数字都是一个幅度值,我如何获得与每个数字相关的频率?另外,我是否考虑了真实和实际的幅度。复杂的部分还是只丢弃复杂的值?
最后,如果我想在一首歌中找到峰值,我是否只需设置一个小窗口进行FFT并将其滑过所有音频?关于该窗口应该有多大的任何建议?
答案 0 :(得分:15)
如果PCM数据的采样率为F,则FFT中的最高频率分量为F / 2。假设您的PCM数据以44100Hz采样,那么您的FFT值将从0Hz(DC)运行到22050Hz。如果从N个样本开始(N是2的幂),则FFT可以返回表示从0到F / 2的所有正频率的N / 2个值,或者它可以返回N个值,这些值也包括来自的负频率 - F / 2到0.您应该检查FFT算法的规范,以找出每个数组项映射到的频率。
要查找峰值,您需要查看FFT值的大小。因此,您需要添加每个复数值的平方实部和虚部。
假设您的N个PCM样本的FFT返回表示正频率的N / 2个复数值。然后,2个复合样本之间的距离为F / 2N Hz。当F = 44100Hz且N = 1024个样本时,这将是21.5Hz。这是您的频率分辨率。如果您需要找到较低频率的节拍,则需要扩展FFT窗口。
答案 1 :(得分:4)
阱, 一个大小为512的复数表示输入波的原始数组,当用FFT处理时,我们将用零(根据预期用途)替换虚部,留下实部,然后将数组传递到FFT,采样率:8192赫兹。
现在我们有一个512个FFT实数值数组,每个值都是一个无理数,每个无理数表示几个有用的值。
要获得基频,我们必须将采样率除以缓冲区大小:
8192/512 = 32;
32是FFT值的分辨率意味着我们已经知道接近32的倍数的高振幅频率。
就像我们有一波
频率:3 48 23 128 幅度:10 5 12 8 dB(ref = 1)
在FFT之后我们得到:频率:0 32 64 128 幅度:9 8 2 8
FFT是频域意味着它根据频率排列 另一方面的时域意味着我们会按时间安排听音乐从第二个零到第二个N.
FFT只能在频率从频率0到频率N排列时进行监听。
因此它按升序排列频率,因为它没有从音频中获取所有实际样本(接近无限),就像每纳秒一样。对于FFT来说,幸运的是,这不会发生FFT从音频中取样,每次采样(1 /采样率)秒。这个样本得到缓冲(在我们的例子中:512),每个512个样本缓冲到FFT中,输出为512个FFT值。
由于FFT排列频率,因此它与时间样本混淆,现在根据频率排列样本。
常规基数上显示的频率是基频,即采样率除以缓冲区大小,在我们的情况下为8192/512 = 32.
因此,频率功率每32个频率显示一次,最近频率的功率根据功率频率接近指数的数量显示。
使用更高的采样率可以实现高分辨率。
为了显示频率,我们以与幅度相对应的升序打印索引。
幅度= 20log10(输出/参考)
每个索引旁边印刷的振幅显示频率和功率。根据分辨率的精确度获得更准确。
结论,FFT产生幅度指数,每个幅度表示其相应指数(频率)的功率。
答案 2 :(得分:3)
您实际上可能正在寻找 spectrogram ,它基本上是沿着时间轴滑动的小窗口中的数据的FFT。如果您有实现此功能的软件,它可能会为您节省一些成本。它是分析时变声学信号的常用方法,也是观察声音的一种非常有用的方法。此外,还有一些技巧,例如,用于FFT的窗口数据,频谱图可能会正确,但是你要做得更好(尽管不是很难)。