2014-09-03 49 views
2

我完成了從音頻文件中查找PCM數據的代碼。我應該如何將這些數據應用於快速傅里葉變換算法?在將字節數組應用到FFT算法之前是否還有更多的事情需要考慮。將WAVE PCM字節數組傳遞給FFT以進行音高檢測

public static void main(String[] args) throws FileNotFoundException, IOException { 
    ByteArrayOutputStream out = new ByteArrayOutputStream(); 
    BufferedInputStream in = new BufferedInputStream(new FileInputStream("adios.wav")); 

    int read; 
    byte[] buff = new byte[1024]; 
     while ((read = in.read(buff)) > 0) 
     { 
      out.write(buff, 0, read); 
     } 
     out.flush(); 
     byte[] audioBytes = out.toByteArray(); 

     for(int i=0; i<audioBytes.length;i++){ 
      System.out.println(audioBytes[i]); 
     } 
} 
+0

第一:使用該代碼,您剛剛將adios.wav的內容存儲到數組中,但這並不意味着您已成功將該文件轉換爲數組數組。要做到這一點,您需要先讀取文件頭,然後使用頭數據類型(int,float,8 -16位)和最終壓縮來相應地解碼文件內容。其次,你想使用哪個FFT類?嘗試先使用它,然後告訴我們它是如何出錯的(如果是的話)。 – lCapp 2014-09-03 10:29:59

回答

3

您需要跳過WAV頭和變換PCM樣本爲-1和1之間的值浮動例如,對於一個字節數組PCM WAV每個樣品和小端排序是需要下面的轉換16個比特(從com.sun.media.sound.AudioFloatConverter):

public float[] toFloatArray(byte[] in_buff, int in_offset, 
    float[] out_buff, int out_offset, int out_len) { 
     int ix = in_offset; 
     int len = out_offset + out_len; 
     for (int ox = out_offset; ox < len; ox++) { 
      out_buff[ox] = ((short) ((in_buff[ix++] & 0xFF) | 
         (in_buff[ix++] << 8))) * (1.0f/32767.0f); 
     } 
     return out_buff; 
    } 

這個電話後,你最終可以使用一個FFT分析float[]

爲了使這更容易,JVM包括AudioSystemAudioInputStream類。

源代碼TarsosDSP,一個Java音頻處理庫,是很多的例子。 TarosDSP manual解釋了PCM數據和可處理樣本之間的關係。

+0

我應該傳遞給這個方法的值是什麼?我手中唯一的值是'in_buff',它是字節數組。我應該傳遞給'int in_offset,float [] out_buff,int out_offset,int out_len'? – user3805160 2014-09-06 05:39:17