4

I am trying to read data of a .wav file both in java and matlab and save as an array of bytes.

In java the code looks as follows:

 public byte[] readWav2(File file) throws UnsupportedAudioFileException, IOException {

     AudioFormat audioFormat;

     AudioInputStream inputAIS = AudioSystem.getAudioInputStream(file);
     audioFormat = inputAIS.getFormat();
     ByteArrayOutputStream baos = new ByteArrayOutputStream();

     // Read the audio data into a memory buffer.
     int nBufferSize = BUFFER_LENGTH * audioFormat.getFrameSize();


        byte[] abBuffer = new byte[nBufferSize];
        while (true) {

            int nBytesRead = inputAIS.read(abBuffer);

            if (nBytesRead == -1) {
                break;
            }
            baos.write(abBuffer, 0, nBytesRead);
        }

        byte[] abAudioData = baos.toByteArray();


        return abAudioData;
    }

In matlab I am using the wavread function:

[Y, FS] = wavread('sound.wav', 'native');

But the results I am getting are different.

In java the first 20 bytes:

53, 0, 19, 0, -71, -1, -80, -1, -99, -1, 10, 0, 87, 0, -69, -1, 123, -1, -77, -1

In matlab:

53, 19, -71, -80, -99, 10, 87, -69, -133, -77, 38, 143, 13, -100, 39, 45, -52, -83, -82, 56

Why every second byte in java is 0 or -1 where in matlab there isn't? Even though I skip the 0's and -1's where in java there is 123 for matlab there is -133? Why is it different?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Radek
  • 1,403
  • 3
  • 25
  • 54
  • Is the file stereo? What results do you get for the `leftright.wav` available at this [media page](http://pscode.org/media/#sound)? For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Feb 08 '12 at 16:28

1 Answers1

5

Java is returning you 16-bit signed PCM data. Since each sample is 16 bits and a byte holds 8 bits, each sample spans two bytes in Java. What Matlab returns you is an array of the 16-bit samples directly.

Basically, the data is the same. It's just laid out differently in memory.

To access the samples in an easier way from Java you could do some bitwise arithmetic, like this:

int firstSample = (abAudioData[0]&0xFF) | (abAudioData[1]<<8);

Another way to read the samples is with the java.nio buffers:

ByteBuffer bb = ByteBuffer.wrap(abAudioData);
bb.order(ByteOrder.LITTLE_ENDIAN);
ShortBuffer sb = bb.asShortBuffer();

int firstSample = sb.get();
Joni
  • 108,737
  • 14
  • 143
  • 193
  • That is getting the same results as the matlab code - perfect. But now I would need to convert this data to have it stored as an array of double for FFT processing. How to do that since the bytes are stored as short? – Radek Feb 08 '12 at 17:28
  • 1
    I think you need an old-fashioned loop where you go through each `short` and cast them to `double`... – Joni Feb 08 '12 at 17:35
  • But if u convert byte to double u won't get the same results as when u convert byte saved as short to double – Radek Feb 08 '12 at 23:41
  • 1
    No, of course you don't. For FFT you want to convert each 16-bit sample (in Java: `short`) to `double`. – Joni Feb 09 '12 at 06:23