按音量规范化来自 getByteFrequencyData 的音频数据

Normalize audio data from getByteFrequencyData by volume

我在网络音频 API 的分析器节点上使用 getByteFrequencyData 方法创建了一个 getSpectrum 方法。返回的音频数据数组是相对于音频源的(el 或 Audio() 实例)volume,一个从 0 到 1 的值。

我试图使用音频源的音量对从 getByteFrequencyData 接收到的每个值进行标准化,以便 getSpectrum 的用户在可视化音频数据时不必担心音量。

这是 getSpectrum 的精简版

var audioData = new Uint8Array(analyser.binCount);
var spectrum = [];

analyser.getByteFrequencyData(audioData);

for (var i = 0; i < audioData.length; i++) {
  var value = audioData[i];

  //Where I'm trying to calculate the value independent of volume
  value = ((value / audioEl.volume) / 255);

  spectrum.push(value);
}

return spectrum;

W3C spec 引用了用于计算给定 maxDecibels 和 minDecibels 的返回值的方程式。根据我的基本理解,我试图对数学进行逆运算,以便得到一个归一化值,但我无法让它完全正确地工作。我无法使用 0 到 1 之间的音量值来完成此操作。

如有任何建议,将不胜感激!这是问题的 working example。更改音量滑块将说明问题。

2016 年 7 月 22 日更新:感谢@raymond-toy 的回答,我想出了如何将 0 到 1 的音量值转换为分贝。

volumeDB = Math.abs((Math.log(volume)/Math.LN10)*20);

拿到DB后,我把W3C规范中的方程倒过来,

value = ((audioDataValue * volumeDB) / 255) - volumeDB

不幸的是,value 仍然以某种方式相对于 volume 结束。有人看到我遗漏了什么吗?

getByteFrequencyData returns 值(以 dB 为单位)。您不想将这些值除以 audioE1.volume。您想要(以某种方式!)audioE1.volume 转换为 dB 值,并从 getByteFrequencyData

的值中添加(或减去)该值

如果您先使用 getFloatFrequencyData 看看发生了什么,可能会更容易理解。

显然我是在做傻事。正如 @raymond-toy 指出的那样,频谱值与音量隐含相关。规范化意味着丢失一部分数据 "off the bottom of the spectrum",这不是我的目标。

如果有人好奇,我最后只是将 audioDataValue 除以 255,得到从 0 到 1 的浮点数。