簡體   English   中英

使用node.js從麥克風檢測音頻

[英]Detect audio frequency from microphone with 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); 
}

標量將信號輸入與兩個向量相乘。

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個NPM模塊,1個包裝“sndpeek”(一個開源音頻分析庫)和另一個用該包裝模塊檢測音調的模塊; https://www.npmjs.com/package/whistle-detection

太糟糕了,我無法讓sndpeek應用程序在我的覆盆子pi上工作,但這些節點應用程序在我的Linux(ubuntu 15.04)和Windows 7機器上運行良好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM