我需要有关如何制作音频分析仪的建议

信息处理 fft 频率 窗函数
2021-12-26 12:04:49

我只需要对创建频率分析仪的一些非常基本的方面进行一些说明。我正在编写一个 c++ 程序,到目前为止它只是一个媒体播放器,带有一个自定义资源管理器。您可以制作播放列表、随机播放、重复播放等。

但我的目标是继续添加功能。到目前为止,我只有一个信号电平表,现在我正在尝试添加一个频率分析仪。

我正在使用fftReal。所以我正处于我有输出的阶段,我正在缩放到 dbfs,我认为这是正确的,但并不完全确定。

for (int i=0; i < fftsize/2; ++i)
    db[i]=20*log(sqrt(imaginary[i]*imaginary[i]+real[i]*real[i]));

所以我知道我应该在某处应用一个窗口函数,并且我试图了解如何做到这一点。但我也想知道这一点。如果我想将数据显示为上下弹出的矩形,而不是绘制点并用线连接,并且我想将矩形的数量限制在大约 50 个左右。我是否采用一个范围的平均分贝。

我注意到在许多应用中,频率范围是倾斜的,频率越高,单元之间的距离越小。使用什么样的比例尺,我怎样才能分解光谱以便我有一个很好的视觉效果?

很抱歉,如果这一切之前都讨论过,我已经在谷歌上搜索了一段时间,总的来说我被信息淹没了,但我需要先了解一些关键的事情。

谢谢

3个回答

这实际上取决于您想要获得的花哨。一个“好”的分析器通常会做以下事情。

  1. 将输入拆分为帧。这些帧通常重叠并且是窗口化的。好的选择是 50% 的重叠和汉宁窗。
  2. 做一个 FFT
  3. 选择频段的中心频率。对于音频好的选择是八度音阶或第三八度音阶(参见http://www.engineeringtoolbox.com/octave-bands-frequency-limits-d_1602.html
  4. 对于每个积分围绕中心频率的 FFT 能量。集成窗口有不同的选择。不错的选择是梯形或巴特沃斯窗。一个非常好的窗口选择将确保考虑所有能量,即带能量的总和等于所有 FFT 箱的总和。

如果频带的数量相对较少,则简单地使用一组并行带通滤波器和一个 RMS 检测器会更有效、更容易。这也允许很好地调整显示的时间行为。

正如 endolith 所说,您想使用对数规模的 bin。最简单的方法是在较高频率下组合多个 bin。要做到这一点,您需要在不同的垃圾箱中添加能量,而不是平均它们。

另外,您计算的 dB 不正确。"log" 做自然对数。你想要“log10”。此外,您不需要执行 sqrt。您可以去掉 sqrt 并将 20 乘数更改为 10。

db[i]=10*log10(imaginary[i]*imaginary[i]+real[i]*real[i]);

编辑:将各种箱中的能量加在一起时,将它们添加为线性值,而不是 dB。完成添加后,将其转换为 dB。

所以我知道我应该在某处应用一个窗口函数,并且我试图了解如何做到这一点。

在进行 FFT之前,将信号块乘以窗口函数。FFT 对信号进行操作,就好像它一直在循环和重复一样,所以如果开始和结束不对齐(而且它们几乎从不对齐),它会产生不连续性,从而在频率峰值上产生大的“裙边” . 窗口函数使信号从开始和结束逐渐变细(淡入和淡出),因此没有不连续性。

我想将矩形的数量限制在大约 50 个左右。我是否采用一个范围的平均分贝。

不要取dB的平均值。范围内的最大 bin 可能就是您想要的。

我注意到在许多应用中,频率范围是倾斜的,频率越高,单元之间的距离越小。使用什么样的比例尺,我怎样才能分解光谱以便我有一个很好的视觉效果?

这只是一个对数频率轴。由于 dB 是对数的,因此组合实际上是一个对数图

你打算做一个对数频率轴,然后把它分成等距的箱子吗?所以它们实际上是对数间隔的箱子?FFT bin 是线性间隔的,因此每个对数间隔 bin 将包含不同数量的 FFT bin。