解释Web Audio API FFT结果

时间:2013-01-05 06:29:09

标签: javascript html5 webkit fft html5-audio

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

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

freqData = new Float32Array(analyser.frequencyBinCount);
analyser.getFloatFrequencyData(freqData);

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

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

3 个答案:

答案 0 :(得分:31)

由于似乎没有关于数据实际代表的文档,我查看了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;

webkit中getFloatFrequencyData的相关代码:

float linearValue = source[i];
double dbMag = !linearValue ? minDecibels : AudioUtilities::linearToDecibels(linearValue);
destination[i] = float(dbMag);

因此,要获得正值,您可以自己简单地减去minDecibels,这在analyzer node中公开:

 //The minimum power value in the scaling range for the FFT analysis data for conversion to unsigned byte values.
 attribute double minDecibels;

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

webkit中的默认值为:

const double RealtimeAnalyser::DefaultSmoothingTimeConstant  = 0.8;
const double RealtimeAnalyser::DefaultMinDecibels = -100;
const double RealtimeAnalyser::DefaultMaxDecibels = -30;

可悲的是,即使分析器节点计算复杂的fft,它也无法访问复杂的表示,只能访问它的大小。

答案 1 :(得分:2)

使用Float32Array是正确的。我找到了一个关于使用音频数据API的有趣教程,虽然它与Web音频API不同,但我给了我一些有用的见解,告诉我你要做什么here。我快速查看了为什么数字是负数,并没有注意到任何明显的数字,但我想知道这些数字是否可能是分贝dB,通常以负数给出,零是峰值。该理论唯一的问题是-891对于dB来说似乎是一个非常小的数字。

答案 2 :(得分:2)

纠正上一个答案和评论中的两个点 - 数字以分贝为单位,因此0表示最大值,-infinity表示最小值(绝对静音)。 -891.0 ...我相信,只是一个浮点转换奇怪。