How to Read the Data in a Wav File to an Array

How to read the data in a wav file to an array

WAV files (at least, uncompressed ones) are fairly straightforward. There's a header, then the data follows it.

Here's a great reference: https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ (mirror)

reading wav/wave file into short[] array

Bring it in via an AudioInputStream as one normally does for sound.

With each buffer load you grab from the stream, iterate through it, two bytes at a time (if it is 16-bit encoding) and use your favorite algorithm to convert the two bytes to a single short int. (Depends if file is Big-Endian or Little-Endian.)

Then, save the results by appending to your preferred form of short array, instead of posting to a SourceDataLine like is done in the more usual playback situations.

Quote from Java Tutorials:

Because the Java Sound API gives you access to the audio data as an
array of bytes, you can alter these bytes in any way you choose.

You might check out the code in this Java sound tutorial: Using Files and Format Converters, the section "Reading Sound Files" and note the comment: "Here, do something useful with the audio data that's now in the audioBytes array..."

For example, that something useful might be:

    myShortArray[i] = (short)(( buffer[i*2] & 0xff )|( buffer[i*2 + 1] << 8 ));

buffer = byte buffer receiving the AudioInputStream.

i = index into the arrays.

What exactly is the data returned when reading a .wav file?

wavData is an array of numbers each representing a single sample of the audio signal. The samples are snapshots of the audio amplitude spaced evenly in time. So if your rate is returned as 48000 then the first 48000 elements of wavData would be 1 second worth of the audio signal. For more information read about PCM on wikipedia: https://en.wikipedia.org/wiki/Pulse-code_modulation.

How do I read my saved .wav file as byte or double array? I am using Java / Android Studio

I can't give you a full code since it's a long solution and I have other things to do. I can give you hints.

First, check this link as reference.

As you see, a .wav or a WAVE file does not only contain the audio samples but it also contains other metadata that describes the contents of the file. To correctly read the audio samples, you'll need the values of these metadata.

To do this, first instantiate a FileInputstream. You will need a File object representing your .wav file to do that.

Next, you'll need to read each field from top to bottom. As you see from the illustration, the number of bytes for each field is indicated. Use the following code when reading a field.

byte[] bytes = new byte[numOfBytes];
fileInputStream.read(bytes, 0, bytes.length);
// The value of current field is now stored in the bytes array

After each read, the fileInputStream will automatically point to the next field. Just repeat the above code until you have reached the start of the audio samples data.

To interpret the obtained values, you'll have to carefully read the description of each field.

To convert field from byte array to ASCII or String, use:

String value = new String(bytes);

To convert field from byte array to a number, use:

ByteBuffer buffer = ByteBuffer.allocate(numOfBytes);
buffer.order(BIG_ENDIAN); // Check the illustration. If it says little endian, use
// LITTLE_ENDIAN
buffer.put(bytes);
buffer.rewind();

If field consists of two bytes:

Short value = buffer.getShort();

If field consists of 4 bytes:

Int value = buffer.getInt();

To read the samples, just continue what you're doing above. But you'll also have to consider the number of bits per sample as given by the BitsPerSample field. For 8 bits, read 1 byte. For 16 bits, read 2 bytes, and so on and so forth. Just repeat to get each sample until you reach the end of file.
To check the end of file, get the returned value from read and check if it is -1:

int read = fileInputSream.read(bytes, 0, bytes.length);
// If read equals -1 then end of file


Related Topics



Leave a reply



Submit