【问题标题】:How to scale FFT output of wave file?如何缩放波形文件的 FFT 输出?
【发布时间】:2011-10-03 18:05:24
【问题描述】:

波形文件:44100 Hz,16 位,双通道。

我使用 FFT 计算每个输出频率区间的幅度。但我不知道缩放它以绘制(实时)光谱。

谁能帮帮我?

【问题讨论】:

  • 上述链接上的Scale方法仅转换为db。因为我不知道使用 FFT 算法后复杂输出的最大值。我只知道一个实例输出的最大值,但每 N 毫秒,我就有另一个输出。请帮帮我!
  • 我无法计算所有输出并找到它们的最大值,这太难了。

标签: audio signal-processing wav fft spectrum


【解决方案1】:

很好;有很多方法可以做到这一点...

例如:如果你想要一个 dB 标度,对于每个假想样本,计算

ymag = (x.real^2 + x.imag^2)

你只想要通过一半的数组,因为你想要正频率;后半部分将只是前半部分的重复,将真实数据馈送到 FFT。

在结果值中搜索最小值和最大值并存储它们。如果您的最小值为零,请选择一些非常小的值作为您的最小值。 (0.000001 或其他东西)。然后,将您的最小 dB 值设置为 mindB = 10 * log10(minimum)。

现在,返回的第一个值 (sample[0]) 将是您的 DC 偏移量,您可能希望将其设置为零。

然后,对于每个样本,计算:ydB = 10 * log10(ymag / 最大值)。

这应该为您提供一个数组,该数组表示从每个样本箱的最大值向下的 dB。您可以将其扩展到您需要的任何内容;如果您的绘图区域从 y=5 变为 y=200,您可以使用以下内容:

yscaled = ((ydB / -mindB) * (200 - 5) + 200)

如果出现 FP 舍入误差,我还将确保缩放值符合边界。

yscaled = min(max(yscaled, 5),200)

自从我这样做以来已经有一段时间了,所以如果有任何数学错误,我深表歉意。 :)

【讨论】:

  • @cobazet 我在上面看到了你的 cmets;我认为这给了你你想要的。我记得它的比例从 -inf dB 到 0 dB 近似......如果这对你不起作用,请告诉我,我会进一步研究。
  • 在这种情况下,您只需找到刚刚 FFT 处理的任何内容的最小值和最大值,而不是整个数据集。 (换句话说:如果您使用 32768 点 FFT,您只能找到正在使用的 16384 点中的最大值......)
  • 虽然,是的,如果需要一个 0 dB 参考来表示整个数据块的所有实时 FFT 的绝对最大值的 0 dB,那么您必须知道提前那个点。如果你需要这个,你唯一的选择是提前选择一个值作为最大值,可能来自试验并找到一个合适的值。您还可以选择与您的输入数据最大可能值相关的实际最大可能值,但这可能会在顶部留下很多额外空间......
  • 没有;结果应
  • 因此,在我给出的示例中,您的绘图区域的 ay=5 到 y=200,在我们尝试接近负无穷 dB 时,您应该在缩放值上得到 5,您应该得到 200对于代表 0 dB 的缩放值。 (我本可以在某个地方不正确地缩放某些东西,但这就是我的想法。)
【解决方案2】:

不同的 FFT 实现具有不同的比例因子,可能相差 N、1/N 或 1/sqrt(N),其中 N 是 FFT 的长度。对于至少一种有符号整数输入 FFT,最大比例约为 sqrt(2) * N * 2^(b - 1),其中 b 是小数点左侧的位数(在您的情况下为 16,如果您在 FFT 之前将通道加总为更大的数据类型,则可能为 17)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-23
    • 2018-12-12
    • 2013-02-03
    • 1970-01-01
    • 2020-11-11
    • 2013-01-02
    相关资源
    最近更新 更多