ArrayIndexOutOfBoundsException when trying to read bytes from Mixer (Stereo Mix)

274 Views Asked by At

I'm trying to read the audio bytes from a given Mixer, in this case, the Stereo Mix from a Windows system. The project consists of 2 parts. One sends the AudioFormat and Mixer ID to the second one via a Socket (the one that throws the exception) that opens the given line from the Mixer so it can read the audio bytes and send them to a third party software.

The code that performs this task is the following one...

        try {
        line = (TargetDataLine) mixer.getLine(info);
        line.open(format);

        int bytesRead, CHUNK_SIZE = 4096;
        byte[] data = new byte[line.getBufferSize() / 5];

        line.start();

        while (true) {
            bytesRead = line.read(data, 0, CHUNK_SIZE); // Exception thrown in here.
            stdout.write(data, 0, bytesRead);
            stdout.flush();
        }

    } catch (LineUnavailableException ex) {
        System.out.println("Line is unavailable.");
        ex.printStackTrace();
    }

And the concrete error message is the following one...

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 800
      at com.sun.media.sound.DirectAudioDevice$DirectTDL.read(Unknown Source)
      at org.Main.main(Main.java:69)

This error is surprising me as the exact same code was tested months ago and worked flawlessly sending bytes through the stdout.

UPDATE: The index 800 range is for 8 bit AudioFormat, if I select a 16 bit one the out of range exception will say 1600.

1

There are 1 best solutions below

4
On

Your problem is the infinite loop due to the while(true) section. You read infinitely the line object which is an array, which means that has a specific length. So after 800 loops you reach the bounds of the array and there is no other object to read. This is why you get that type of Exception.

The solution to this problem is to check for the array length inside your while loop condition.

Of course you can perform this job with Stream feature of Java 8.

Forgive me for the lack of code samples. I am writing this answer through my phone.