Mor*_*ten 3 javascript audio fft node.js
我在Raspberry Pi上使用node.js来控制一些乐器.我想要一个麦克风听一个特定的信号,比如一个500赫兹的音调,并在听到它时触发一个事件.
在查看了多个node.js库之后,node-core-audio(https://www.npmjs.com/package/node-core-audio)是最接近的库,但在编译时失败了.
任何人都可以推荐一个好方法吗?
只需使用傅里叶变换的某些部分即可获得您感兴趣的频率.
标量将输入信号乘以四个波长四分之一的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);
}
Run Code Online (Sandbox Code Playgroud)
标量将信号输入与两个向量相乘.
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);
}
Run Code Online (Sandbox Code Playgroud)
您可能希望将此值与信号的总振幅进行比较(获取区间中所有采样的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);
}
Run Code Online (Sandbox Code Playgroud)
因此,您想要的检测可能是配额findTone(inputSamples)/ noiseLevel(inputSamples)的最小值.
如果您使用太多样本,则算法将非常精确,并且如果您具有偏置或嘈杂的500 Hz输入信号,则可能比您希望的更精确.然后带通滤波器是另一种选择.
如果您只需要频谱的一个或几个部分,并且FFT既不允许任意频率也不允许任意采样集,则使用FFT会浪费CPU周期.
| 归档时间: |
|
| 查看次数: |
4680 次 |
| 最近记录: |