JavaScript - WebAudio API ScriptProcessorNode InputBuffer getChannelData 精度

Posted

技术标签:

【中文标题】JavaScript - WebAudio API ScriptProcessorNode InputBuffer getChannelData 精度【英文标题】:JavaScript - WebAudio API ScriptProcessorNode InputBuffer getChannelData precision 【发布时间】:2014-06-08 07:52:11 【问题描述】:

我正在尝试使用 javascript 的 WebAudio API 以及其他一些 SO 文章(How to get frequency from fft result?、How do I obtain the frequencies of each value in an FFT?)来确定输入信号(来自音调发生器,或者可能是乐器)的基频,但是我似乎只能确定大约 5-10Hz 的频率。

我正在一个安静的房间里使用一个放置在高质量麦克风旁边的 iPad 信号发生器应用程序进行测试。

对于 500Hz,它始终返回 506;对于 600Hz,我得到 592。1kHz 是 1001Hz,但 2kHz 是 1991。我还注意到,在看到 FFT 数据的任何变化之前,我可以将频率调制 5Hz(以 1Hz 为增量)。而且我只能通过将两个最高的 bin 平均起来才能得到准确的结果。

这是否意味着 FFT 数据中没有足够的分辨率来准确确定 1Hz 以内的基频,还是我的方法有误?

我已经尝试使用两个原生 FFT 库(例如,像这样):

var fFrequencyData = new Float32Array(analyser.frequencyBinCount);
analyser.getFloatFrequencyData(fFrequencyData);

(你可以假设我已经正确初始化并连接了一个 Analyzer 节点),它只显示了大约

的灵敏度/分辨率

还使用 DSP.js 的 FFT 库,如下所示:

var fft = new FFT();
fft.forward(e.inputBuffer.getChannelData(0));
fFrequencyData = fft.spectrum;

其中e 是传递给onaudioprocess 的事件对象。

FFT 数据(如 FFT::spectrum)为空时似乎存在问题 - 这正常吗?除非我通过 analyser.getFloatFrequencyData 运行 fft.spectrum 中的数据,否则我认为它会用本机 FFT 中的内容覆盖数据,完全违背了目的?

希望有人可以帮助我朝着正确的方向前进 - 谢谢! :)

【问题讨论】:

【参考方案1】:

您需要非常大的 FFT 才能通过这种方式获得高质量的音高检测。例如,要获得 1Hz 的分辨率,采样率为 44,100kHz,您需要 64k(-ish) FFT 大小。你最好使用自相关来进行单音音高检测。

【讨论】:

我在考虑一个大得离谱的 FFT,但 InputBuffer::getChannelData() 结果只有 2048 个索引,所以我无能为力,对吧?您能否对单声道音高检测的自相关有所了解?有没有一个不错的 JS 库可以让这变得更容易一些(没有那么多时髦的数学)? 事实证明,我写了一个音高检测器:github.com/cwilso/PitchDetect。 :)

以上是关于JavaScript - WebAudio API ScriptProcessorNode InputBuffer getChannelData 精度的主要内容,如果未能解决你的问题,请参考以下文章

使用 NodeJs 中的 WebAudio API

使用 WebAudio API 计算 Live Mic Audio 频率的简单代码

如何正确缓存 webaudio 对象?

来自WebSocket的WebAudio AAC流媒体播放

WebAudio - 振荡器 setPeridiocWave

使用 WebAudio 合并/混合两个音频流