繁体   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