Using javax.sound.sampled.Clip to play, loop, and stop multiple sounds in a game. Unexpected Errors

T. Thomas picture T. Thomas · Aug 12, 2012 · Viewed 33.7k times · Source

I'm trying to play two wav sounds at once during a game (Background Music and an effect). I first constructed this chunk of code using another audio handler in java which would handle the playing, stopping, and looping of the sound. This construct would play the background music or effect but only one at a time. I looked around the internet and was told to use javax.sound.sampled.Clip to handle the sounds so reused the same construct(play, stop, loop) but switched it to use javax.sound.sampled.Clip. Now I'm completely lost. From what I have read so far I've done everything correct and get no errors in the eclipse editor, but when I run it I get one of two errors. In eclipse (running on Linux) a LineUnavailableException is thrown. In eclipse (running on windows 7) I get a java.lang.NullPointerException in the loop() section of this code. If you could show me what I'm doing wrong or point me to some relevant documentation I'd appreciate it. I'm assuming its something with my code that handles Exceptions but I'm not sure. If you see any other hideous code missteps please let me know I'm striving the be the best programmer I can and really appreciate constructive criticism. Thank you for your time.

    import java.io.File;
    import java.io.IOException;
    import java.net.MalformedURLException;
    import javax.sound.sampled.AudioInputStream;
    import javax.sound.sampled.AudioSystem;
    import javax.sound.sampled.Clip;
    import javax.sound.sampled.LineUnavailableException;
    import javax.sound.sampled.UnsupportedAudioFileException;

    /**
     * Handles play, pause, and looping of sounds for the game.
     * @author Tyler Thomas
     *
     */
    public class Sound {
        private Clip myClip;
        public Sound(String fileName) {
                try {
                    File file = new File(fileName);
                    if (file.exists()) {
                        Clip myClip = AudioSystem.getClip();
                        AudioInputStream ais = AudioSystem.getAudioInputStream(file.toURI().toURL());
                        myClip.open(ais);
                    }
                    else {
                        throw new RuntimeException("Sound: file not found: " + fileName);
                    }
                }
                catch (MalformedURLException e) {
                    throw new RuntimeException("Sound: Malformed URL: " + e);
                }
                catch (UnsupportedAudioFileException e) {
                    throw new RuntimeException("Sound: Unsupported Audio File: " + e);
                }
                catch (IOException e) {
                    throw new RuntimeException("Sound: Input/Output Error: " + e);
                }
                catch (LineUnavailableException e) {
                    throw new RuntimeException("Sound: Line Unavailable: " + e);
                }
        }
        public void play(){
            myClip.setFramePosition(0);  // Must always rewind!
            myClip.loop(0);
            myClip.start();
        }
        public void loop(){
            myClip.loop(Clip.LOOP_CONTINUOUSLY);
        }
        public void stop(){
            myClip.stop();
        }
    }

Answer

T. Thomas picture T. Thomas · Aug 16, 2012

I was able to get the code working and now have a better understanding of Clips. The page that helped me the most was http://www3.ntu.edu.sg/home/ehchua/programming/java/J8c_PlayingSound.html it breaks everything down and helped me see where I made mistakes. Here is my final working code. As before if you see any horrible errors or over sights in logic or style let me know.

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;

/**
 * Handles playing, stoping, and looping of sounds for the game.
 * @author Tyler Thomas
 *
 */
public class Sound {
    private Clip clip;
    public Sound(String fileName) {
        // specify the sound to play
        // (assuming the sound can be played by the audio system)
        // from a wave File
        try {
            File file = new File(fileName);
            if (file.exists()) {
                AudioInputStream sound = AudioSystem.getAudioInputStream(file);
             // load the sound into memory (a Clip)
                clip = AudioSystem.getClip();
                clip.open(sound);
            }
            else {
                throw new RuntimeException("Sound: file not found: " + fileName);
            }
        }
        catch (MalformedURLException e) {
            e.printStackTrace();
            throw new RuntimeException("Sound: Malformed URL: " + e);
        }
        catch (UnsupportedAudioFileException e) {
            e.printStackTrace();
            throw new RuntimeException("Sound: Unsupported Audio File: " + e);
        }
        catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("Sound: Input/Output Error: " + e);
        }
        catch (LineUnavailableException e) {
            e.printStackTrace();
            throw new RuntimeException("Sound: Line Unavailable Exception Error: " + e);
        }

    // play, stop, loop the sound clip
    }
    public void play(){
        clip.setFramePosition(0);  // Must always rewind!
        clip.start();
    }
    public void loop(){
        clip.loop(Clip.LOOP_CONTINUOUSLY);
    }
    public void stop(){
            clip.stop();
        }
    }