我在查找readAudioInputStream时实际遇到了一些问题。下面的程序只是打印我得到的字节数组,但实际上我什至不知道,如果字节实际上是样本,那么字节数组就是音频波。

File fileIn;
AudioInputStream audio_in;
byte[] audioBytes;
int numBytesRead;
int numFramesRead;
int numBytes;
int totalFramesRead;
int bytesPerFrame;

try {
        audio_in = AudioSystem.getAudioInputStream(fileIn);
        bytesPerFrame = audio_in.getFormat().getFrameSize();


        if (bytesPerFrame == AudioSystem.NOT_SPECIFIED) {
            bytesPerFrame = 1;
        }

        numBytes = 1024 * bytesPerFrame;
        audioBytes = new byte[numBytes];
        try {
            numBytesRead = 0;
            numFramesRead = 0;
        } catch (Exception ex) {
            System.out.println("Something went completely wrong");
        }
    } catch (Exception e) {
        System.out.println("Something went completely wrong");
    }

在另一部分中,我以此读取了一些字节:

try {
        if ((numBytesRead = audio_in.read(audioBytes)) != -1) {
              numFramesRead = numBytesRead / bytesPerFrame;
              totalFramesRead += numFramesRead;
        }
    } catch (Exception e) {
        System.out.println("Had problems reading new content");
    }

因此,首先,此代码不是我提供的。这是我第一次阅读音频文件,因此我从网络间获得了一些帮助。 (找到了链接:
Java - reading, manipulating and writing WAV files
stackoverflow,谁知道呢。

问题是,audioBytes中的字节代表什么?由于源是44kHz立体声,因此必须在某处藏有2个波,对吗?那么如何从这些字节中过滤掉重要信息?

//编辑

所以我添加的是这个功能:

public short[] Get_Sample() {
    if(samplesRead == 1024) {
        Read_Buffer();
        samplesRead = 4;
    } else {
        samplesRead = samplesRead + 4;
    }
    short sample[] = new short[2];
    sample[0] = (short)(audioBytes[samplesRead-4] + 256*audioBytes[samplesRead-3]);
    sample[1] = (short)(audioBytes[samplesRead-2] + 256*audioBytes[samplesRead-1]);
    return sample;
}

其中,Read_Buffer()读取接下来的1024个(或更少)字节,并将其加载到audioBytes中。 sample [0]用于左侧,sample [1]用于右侧。但是我仍然不确定,因为我从中得到的波浪看起来“很吵”。 (编辑:使用的WAV实际上使用了小尾数字节顺序,因此我不得不更改计算。)

最佳答案

AudioInputStream read()方法返回原始音频数据。在使用getFormat()返回返回AudioFormat的音频格式之前,您不知道数据的“构造”是什么。从AudioFormat中,您可以获取getChannels()和getSampleSizeInBits()以及更多...这是因为AudioInputStream是为已知格式制作的。

如果您计算样本值,则符号和
数据的字节序(在16位样本的情况下)。制作更通用的代码
使用从AudioInputStream返回的AudioFormat对象获取更多信息
关于数据缓冲区:

  • encoding():PCM_SIGNED,PCM_UNSIGNED ...
  • bigEndian():对或错

  • 正如您已经发现的那样,错误的样本构建可能会导致某些声音受干扰。如果使用各种文件,将来可能会遇到问题。如果您不提供某些格式的支持,请检查AudioFormat并抛出异常(例如javax.sound.sampled.UnsupportedAudioFileException)。这样可以节省您的时间。

    10-08 01:21