What exactly does AudioInputStream.read method return?

心不动则不痛 提交于 2020-01-03 03:13:11

问题


I have some problems finding out, what I actually read with the AudioInputStream. The program below just prints the byte-array I get but I actually don't even know, if the bytes are actually the samples, so the byte-array is the audio wave.

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");
    }

and in some other part, I read some bytes with this:

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

So first of all, this code is not from me. This is my first time, reading audio-files so I got some help from the inter-webs. (Found the link: Java - reading, manipulating and writing WAV files stackoverflow, who would have known.

The question is, what are the bytes in audioBytes representing? Since the source is a 44kHz, stereo, there have to be 2 waves hiding in there somewhere, am I right? so how do I filter the important informations out of these bytes?

// EDIT

So what I added is this function:

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;
}

where Read_Buffer() reads the next 1024 (or less) Bytes and loads them into audioBytes. sample[0] is used for the left side, sample[1] for the right side. But I'm still not sure since the waves i get from this look quite "noisy". (Edit: the used WAV actually used little-endian byte order so I had to change the calculation.)


回答1:


AudioInputStream read() method returns the raw audio data. You don't know what is the 'construction' of data before you read the audio format with getFormat() which returns AudioFormat. From AudioFormat you can getChannels() and getSampleSizeInBits() and more... This is because the AudioInputStream is made for known format.

If you calculate a sample value you have different possibilities with signes and endianness of the data (in case of 16-bit sample). To make a more generic code use your AudioFormat object returned from AudioInputStream to get more info about the data buffer:

  • encoding() : PCM_SIGNED, PCM_UNSIGNED ...
  • bigEndian() : true or false

As you already discovered the incorrect sample building may lead to some disturbed sound. If you work with various files it may case a problems in the future. If you won't provide a support for some formats just check what says AudioFormat and throw exception (e.g. javax.sound.sampled.UnsupportedAudioFileException). It will save your time.



来源:https://stackoverflow.com/questions/17370661/what-exactly-does-audioinputstream-read-method-return

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!