2011-04-25 406 views
38

我目前正試圖執行一些代碼使用Android來檢測通過手機的麥克風播放大量的特定音頻範圍。Android音頻FFT檢索使用audiorecord特定頻率幅度

int channel_config = AudioFormat.CHANNEL_CONFIGURATION_MONO; 
int format = AudioFormat.ENCODING_PCM_16BIT; 
int sampleSize = 8000; 
int bufferSize = AudioRecord.getMinBufferSize(sampleSize, channel_config, format); 
AudioRecord audioInput = new AudioRecord(AudioSource.MIC, sampleSize, channel_config, format, bufferSize); 

的音頻然後閱讀:

short[] audioBuffer = new short[bufferSize]; 
audioInput.startRecording(); 
audioInput.read(audioBuffer, 0, bufferSize); 

執行FFT是我被卡住,因爲我有這方面的經驗非常少我已經使用AudioRecord類設置類。我一直在嘗試使用這個類:

FFT in JavaComplex class to go with it

我然後發送以下值:

Complex[] fftTempArray = new Complex[bufferSize]; 
for (int i=0; i<bufferSize; i++) 
{ 
    fftTempArray[i] = new Complex(audio[i], 0); 
} 
Complex[] fftArray = fft(fftTempArray); 

這很容易被我誤解這個類是如何打算工作,但這些數值會在整個地方跳回來,即使在沉默中也不能代表一致的頻率。是否有人意識到執行此任務的方法,或者我是否過度複雜,試圖只抓取少量頻率範圍,而不是將其繪製爲圖形表示?

+10

嘿,如果你想通了,你能不能請張貼代碼的最終版本? thx – 2013-07-10 14:19:57

回答

33

首先你需要確保你所得到的結果被正確地轉換爲float/double。我不確定short []版本是如何工作的,但byte []版本只返回原始字節版本。這個字節數組然後需要被正確地轉換爲一個浮點數。轉換代碼應該如下所示:

double[] micBufferData = new double[<insert-proper-size>]; 
    final int bytesPerSample = 2; // As it is 16bit PCM 
    final double amplification = 100.0; // choose a number as you like 
    for (int index = 0, floatIndex = 0; index < bytesRecorded - bytesPerSample + 1; index += bytesPerSample, floatIndex++) { 
     double sample = 0; 
     for (int b = 0; b < bytesPerSample; b++) { 
      int v = bufferData[index + b]; 
      if (b < bytesPerSample - 1 || bytesPerSample == 1) { 
       v &= 0xFF; 
      } 
      sample += v << (b * 8); 
     } 
     double sample32 = amplification * (sample/32768.0); 
     micBufferData[floatIndex] = sample32; 
    } 

然後,您使用micBufferData []創建您的輸入複數組。

一旦得到結果,使用結果中複數的大小。除了具有實際值的頻率外,大多數幅度應接近於零。

您需要的採樣頻率的數組索引轉換成這樣的幅度,以頻率:

private double ComputeFrequency(int arrayIndex) { 
    return ((1.0 * sampleRate)/(1.0 * fftOutWindowSize)) * arrayIndex; 
} 
+2

非常感謝您的回覆,但我仍然有幾個問題。 在運行'ComputeFrequency'方法之前,我是否仍然能夠從返回的複數數組中提取值?同樣的問題似乎仍然允許零星的數字出現在從10到大約3000的範圍內,而房間卻處於沉默狀態 – user723060 2011-04-25 13:49:58

+0

是的,你仍然應該能夠從複雜數組中提取數值,你想要使用複數(即sqrt(re * re + im * im))。即使房間處於完全靜音狀態,也可能會出現麥克風引入的背景噪音,它會顯示在FFT上。將數組索引轉換爲頻率以查看顯示的確切頻率。這些頻率的值可能有助於瞭解它們是否是背景噪音。 – shams 2011-04-25 16:33:14

+0

我很好奇,如果我正確地調用複數組關於虛數。現在我已經實現它的方式與我在原始示例中執行的方式非常相似,但是現在循環遍歷新的micBufferData數組並將每個值分配給複數組,作爲具有虛數的實數,這可能是我錯誤的地方,但我讀過的先前的例子似乎表明這是正確的方法。任何想法,如果有別的東西想要去那裏?再次感謝! – user723060 2011-04-25 16:52:52