解释Web Audio API FFT结果

New*_*wmu 26 javascript html5 webkit fft html5-audio

Web Audio API有一个分析器节点,允许您在正在使用的音频上获取FFT数据,并具有获取数据的字节和浮点数.字节版本有点意义,返回看起来像标准化(取决于最小和最大分贝值)强度频谱,其中0不是特定频率仓的音频分量而255是最大值.

但是我想要比8位更多的细节,但使用float版本会产生奇怪的结果.

freqData = new Float32Array(analyser.frequencyBinCount);
analyser.getFloatFrequencyData(freqData);
Run Code Online (Sandbox Code Playgroud)

这给了我介于-891.048828125和0. -891之间的值对应于静音,因此它在某种程度上是最小值,而我猜0是等于最大值.

这是怎么回事?为什么-891.048828125显着?为什么一个大的负面是沉默,零是最大的?我使用错误的FloatArray还是存在配置错误?Float64给出0值.

sha*_*her 33

由于似乎没有关于数据实际代表的文档,我查看了webkit的相关源代码:RealtimeAnalyser.cpp

简短回答:从Float32Array的每个值中减去analyser.minDecibels以获得正数并乘以(analyser.maxDecibels - analyser.minDecibels)以获得与getByteFrequencyData类似的表示,只需更多分辨率.

答案很长:

getByteFrequencyData和getFloatFrequencyData都以分贝为单位给出了幅度.它的缩放比例不同,对于getByteFrequencyData,减去minDecibels常量:

webkit中getByteFrequencyData的相关代码:

const double rangeScaleFactor = m_maxDecibels == m_minDecibels ? 1 : 1 / (m_maxDecibels - m_minDecibels);
float linearValue = source[i];
double dbMag = !linearValue ? minDecibels : AudioUtilities::linearToDecibels(linearValue);

// The range m_minDecibels to m_maxDecibels will be scaled to byte values from 0 to UCHAR_MAX.
double scaledValue = UCHAR_MAX * (dbMag - minDecibels) * rangeScaleFactor;
Run Code Online (Sandbox Code Playgroud)

webkit中getFloatFrequencyData的相关代码:

float linearValue = source[i];
double dbMag = !linearValue ? minDecibels : AudioUtilities::linearToDecibels(linearValue);
destination[i] = float(dbMag);
Run Code Online (Sandbox Code Playgroud)

因此,要获得正值,您可以自己简单地减去minDecibels,它在分析器节点中公开:

 //The minimum power value in the scaling range for the FFT analysis data for conversion to unsigned byte values.
 attribute double minDecibels;
Run Code Online (Sandbox Code Playgroud)

另一个细节是,默认情况下,分析器节点进行时间平滑,可以通过将smoothingTimeConstant设置为零来禁用.

webkit中的默认值为:

const double RealtimeAnalyser::DefaultSmoothingTimeConstant  = 0.8;
const double RealtimeAnalyser::DefaultMinDecibels = -100;
const double RealtimeAnalyser::DefaultMaxDecibels = -30;
Run Code Online (Sandbox Code Playgroud)

遗憾的是,即使分析器节点计算复杂的fft,它也不能访问复杂的表示,只能访问它的大小.

  • 通过从浮点值中减去 minDecibels,有时我不会得到正数。在我的情况下,设置 minDecibels 值实际上不会限制任何内容,我不断获得更小的值。有什么想法吗? (2认同)