user2850551
user2850551

Reputation: 1

Java audio Stream Closed error

I am trying to add sound to a game I am making, but every time I try to load the sound, I get a Stream Closed Exception. I don't understand why this is happening.

Loads the sound:

public class WavPlayer extends Thread {

/*
 * @param s The path of the wav file.
 * @return The sound data loaded into the WavSound object
 */
public static WavSound loadSound(String s){
    // Get an input stream
    InputStream is = WavPlayer.class.getClassLoader().getResourceAsStream(s);
    AudioInputStream audioStream;
    try {
        // Buffer the input stream
        BufferedInputStream bis = new BufferedInputStream(is);
        // Create the audio input stream and audio format
        audioStream = AudioSystem.getAudioInputStream(bis); //!Stream Closed Exception occurs here
        AudioFormat format = audioStream.getFormat();
        // The length of the audio file
        int length = (int) (audioStream.getFrameLength() * format.getFrameSize());
        // The array to store the samples in
        byte[] samples = new byte[length];
        // Read the samples into array to reduce disk access
        // (fast-execution)
        DataInputStream dis = new DataInputStream(audioStream);
        dis.readFully(samples);
        // Create a sound container
        WavSound sound = new WavSound(samples, format, (int) audioStream.getFrameLength());
        // Don't start the sound on load
        sound.setState(SoundState.STATE_STOPPED);
        // Create a new player for each sound
        new WavPlayer(sound);
        return sound;
    } catch (Exception e) {
        // An error. Mustn't happen
    }
    return null;
}

// Private variables
private WavSound sound = null;

/**
 * Constructs a new player with a sound and with an optional looping
 * 
 * @param s The WavSound object
 */
public WavPlayer(WavSound s) {
    sound = s;
    start();
}

/**
 * Runs the player in a separate thread
 */
@Override
public void run(){
    // Get the byte samples from the container
    byte[] data = sound.getData();
    InputStream is = new ByteArrayInputStream(data);
    try {
        // Create a line for the required audio format
        SourceDataLine line = null;
        AudioFormat format = sound.getAudioFormat();
        // Calculate the buffer size and create the buffer
        int bufferSize = sound.getLength();
        // System.out.println(bufferSize);
        byte[] buffer = new byte[bufferSize];
        // Create a new data line to write the samples onto
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
        line = (SourceDataLine) AudioSystem.getLine(info);
        // Open and start playing on the line
        try {
            if (!line.isOpen()) {
                line.open();
            }
            line.start();
        } catch (Exception e){}
        // The total bytes read
        int numBytesRead = 0;
        boolean running = true;
        while (running) {
            // Destroy this player if the sound is destroyed
            if (sound.getState() == SoundState.STATE_DESTROYED) {
                running = false;
                // Release the line and release any resources used
                line.drain();
                line.close();
            }
            // Write the data only if the sound is playing or looping
            if ((sound.getState() == SoundState.STATE_PLAYING)
                    || (sound.getState() == SoundState.STATE_LOOPING)) {
                numBytesRead = is.read(buffer, 0, buffer.length);
                if (numBytesRead != -1) {
                    line.write(buffer, 0, numBytesRead);
                } else {
                    // The samples are ended. So reset the position of the
                    // stream
                    is.reset();
                    // If the sound is not looping, stop it
                    if (sound.getState() == SoundState.STATE_PLAYING) {
                        sound.setState(SoundState.STATE_STOPPED);
                    }
                }
            } else {
                // Not playing. so wait for a few moments
                Thread.sleep(Math.min(1000 / Global.FRAMES_PER_SECOND, 10));
            }
        }
    } catch (Exception e) {
        // Do nothing
    }
}

The error message I get is: "Exception in thread "main" java.io.IOException: Stream closed at java.io.BufferedInputStream.getInIfOpen(BufferedInputStream.java:134) at java.io.BufferedInputStream.fill(BufferedInputStream.java:218) at java.io.BufferedInputStream.read(BufferedInputStream.java:237) at java.io.DataInputStream.readInt(DataInputStream.java:370) at com.sun.media.sound.WaveFileReader.getFMT(WaveFileReader.java:224) at com.sun.media.sound.WaveFileReader.getAudioInputStream(WaveFileReader.java:140) at javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:1094) at stm.sounds.WavPlayer.loadSound(WavPlayer.java:42) at stm.STM.(STM.java:265) at stm.STM.main(STM.java:363)"

Upvotes: 0

Views: 1570

Answers (2)

faradaj
faradaj

Reputation: 3689

Most probably the file path in this line is not correct:

WavPlayer sound1 = WavPlayer.loadSound("coin.wav");

You should pass the path of the 'coin.wav' file instead of just its name.

For instance if its under a folder named sounds, which let's say right under the root of project, that parameter should be 'sounds/coin.wav'.

Upvotes: 2

nachokk
nachokk

Reputation: 14413

The problem is in your static method loadSound. This method returns null when an exception is thrown. You catch it but you do nothing with it,

  • NEVER make empty catch.
  • Catch specific exceptions.

I would change your method signature loadSound as

public static WavSound loadSound(String s) throws Exception // rather than exception specific exception!!

And then your method without try-catch

Upvotes: 0

Related Questions