使用 node.js 检测麦克风的音频频率
Posted
技术标签:
【中文标题】使用 node.js 检测麦克风的音频频率【英文标题】:Detect audio frequency from microphone with node.js 【发布时间】:2015-03-23 16:34:45 【问题描述】:我在 Raspberry Pi 上使用 node.js 来控制一些仪器。我想让一个麦克风监听一个特定的信号,说出一个 500 Hz 的音调,并在听到它时触发一个事件。
查看了多个 node.js 库后,node-core-audio (https://www.npmjs.com/package/node-core-audio) 是最接近的一个,但编译失败。
有人能推荐一个好方法吗?
【问题讨论】:
您的问题是如何访问音频流,或者如何检测流中给定频率的音调?这是两个完全不同的东西。 如何访问流。最坏的情况是我自己实现一个简单的 FFT。但就目前而言,找到合适的音频库简直是一场噩梦。 有a project to add the full Web Audio API to node.js。它看起来还不足以支持您的用例,但也许您可以为它做出贡献。 使用 FFT 来检测单音是多余的 - 只需使用 Goertzel。 【参考方案1】:只需将傅里叶变换的某些部分用于您感兴趣的频率。
标量将您的输入信号与偏移四分之一波长的两个 500 Hz 音调相乘,总均方根 (RMS) 为 1,这意味着您可以使用 n^-½ 缩放矢量。
var sampleSize = 2000;
var sampleRate = 44100; // Or whatever in use (Hz)
var tone = 500; // tone to detect in Hz
var sin500Hz = Array(sampleSize);
var cos500Hz = Array(sampleSize);
for (var i = 0; i < sampleSize; i++)
sin500Hz[i] = Math.sin(2*Math.PI*tone/sampleRate*i)/Math.sqrt(sampleSize);
cos500Hz[i] = Math.cos(2*Math.PI*tone/sampleRate*i)/Math.sqrt(sampleSize);
标量将信号输入与两个向量相乘。
function findTone(inputSamples)
var amplitudeSin = 0;
var amplitudeCos = 0;
for (var i = 0; i < sampleSize; i++)
amplitudeSin += inputSamples[i]*sin500Hz[i];
amplitudeCos += inputSamples[i]*cos500Hz[i];
return Math.sqrt(amplitudeSin*amplitudeSin + amplitudeCos*amplitudeCos);
您可能希望将此值与信号的总幅度进行比较(取区间内所有样本的 RMS),否则也可以使用 findTone() 检测到噪声。
function noiseLevel(inputSamples)
var power = 0;
var average = 0;
for (var i = 0; i < sampleSize; i++)
average += inputSamples[i];
average /= sampleSize;
for (var i = 0; i < sampleSize; i++)
power += Math.pow(inputSamples[i] - average, 2);
return Math.sqrt(power);
所以您想要的检测可能是配额 findTone(inputSamples)/noiseLevel(inputSamples) 的某个最小值。
如果您使用太多样本,算法将非常精确,并且如果您有一个有偏差或有噪声的 500 Hz 输入信号,可能会比您希望的更精确。那么带通滤波器是一种替代方案。
如果您只需要频谱的一个或几个部分并且 FFT 既不允许任意频率也不允许任意采样集,则使用 FFT 会浪费 CPU 周期。
【讨论】:
【参考方案2】:请注意,我也遇到过这个问题,但找不到答案。我继续制作了 2 个 NPM 模块,1 个包装了“sndpeek”(一个开源音频分析库),另一个使用该包装的模块检测音调; https://www.npmjs.com/package/whistle-detection
我无法让 sndpeek 应用程序在我的树莓派上运行,这太糟糕了,但这些节点应用程序在我的 Linux (ubuntu 15.04) 和 Windows 7 机器上运行良好。
【讨论】:
以上是关于使用 node.js 检测麦克风的音频频率的主要内容,如果未能解决你的问题,请参考以下文章