簡體   English   中英

如何將從 WAV 文件讀取的數據轉換為 java 中的簽名 16 位原始音頻數據數組?

[英]How do I convert data read from a WAV file to an array of signed 16-bit raw audio data in java?

我不知道該怎么做。 我已經閱讀了幾個類似問題的答案以及一些可能在某處有答案的網站,但要么我無法理解它們,要么它們不是我想要做的。 也有可能有些人確實有答案,但我無法集中注意力來解釋它。 我想要一種將 WAV 文件簽名的 16 位原始音頻數據中的數據轉換並將其放入 short[] 的方法。 我更喜歡簡短且易於理解的答案,因為我更容易專注於這些答案。

編輯:有人說這可能是 stackoverflow.com/questions/5210147/reading-wav-file-in-java 的副本。 我對這個問題或其答案的理解不夠好,甚至無法說出它是否不同,或者為什么或如何改變我的問題,所以它不會為那個問題感到困惑。

另一個編輯:我曾嘗試使用 Phil Freihofner 的答案,但在嘗試償還音頻進行測試時,我只聽到了很多咔嗒聲。 我不確定我是否正確實施了它。 這是讀取文件的方法:

static void loadAudioDataTest(String filepath){
        int totalFramesRead = 0;
        File fileIn = new File(filepath);
        try {
          AudioInputStream audioInputStream = 
            AudioSystem.getAudioInputStream(fileIn);
          int bytesPerFrame = 
            audioInputStream.getFormat().getFrameSize();
            if (bytesPerFrame == AudioSystem.NOT_SPECIFIED) {
            bytesPerFrame = 1;
          } 
          int numBytes = 1024 * bytesPerFrame; 
          byte[] audioBytes = new byte[numBytes];
          audioArray=new short[numBytes/2];
          try{
            int numBytesRead = 0;
            int numFramesRead = 0;
            while ((numBytesRead = 
              audioInputStream.read(audioBytes)) != -1) {
              numFramesRead = numBytesRead / bytesPerFrame;
              totalFramesRead += numFramesRead;
            }for(int a=0;a<audioArray.length;a++){
                  audioArray[acc]=(short)((audioBytes[a*2]&0xff)|(audioBytes[acc*2+1]<<8));
            }
          } catch (Exception ex) { 
            // Handle the error...
          }
        } catch (Exception e) {
          // Handle the error...
        }
    }

該位播放聲音並位於由計時器重復激活的 actionPerformed(ActionEvent) void 內,以防出現問題

byte[]buf=new byte[2];
        AudioFormat af=new AudioFormat(44100,16,1,true,false);
        SourceDataLine sdl;
        try{
            sdl=AudioSystem.getSourceDataLine(af);
            sdl.open();
            sdl.start();
                buf[1]=(byte) (audioArray[t%audioArray.length]&0xFF); 
                buf[0]=(byte) (audioArray[t%audioArray.length]>>8);
                sdl.write(buf,0,2);
            sdl.drain();
            sdl.stop();
        }catch(LineUnavailableException e1){
            e1.printStackTrace();
        }t++;

當前常用的將數據加載到字節數組中的核心 java class 是AudioInputStream (javax.sound.sampled.AudioInputStream)。 可以在 Oracle 教程Using Files and Format Converters中找到其使用示例和說明。 示例代碼位於標題為“讀取聲音文件”的部分中。 請注意最里面的 while 循環中的點,其中包含以下行: // Here, do something useful with the audio data 那時,您會將數據加載到您的數組中。

取兩個字節並將它們轉換為短字節已被多次回答,但我沒有方便的鏈接。 發布一些我使用過的代碼會更容易。

audioArray[i] = ( buffer[bufferIdx] & 0xff )
                        | ( buffer[bufferIdx + 1] << 8 ) ;

...其中audioArray 可能是一個短[]。 (在我的代碼中,我使用 float[] 並執行另一個步驟將值縮放到 -1 到 1 的范圍。)

這是從 github 庫AudioCue中稍作修改的片段,引用第 391-393 行。

暫無
暫無

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

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