Reputation:
Basically I am trying to use this SoundEffect class in a simple java game I'm working on for my assignment.
import java.io.*;
import java.net.URL;
import javax.sound.sampled.*;
/**
* This enum encapsulates all the sound effects of a game, so as to separate the sound playing
* codes from the game codes.
* 1. Define all your sound effect names and the associated wave file.
* 2. To play a specific sound, simply invoke SoundEffect.SOUND_NAME.play().
* 3. You might optionally invoke the static method SoundEffect.init() to pre-load all the
* sound files, so that the play is not paused while loading the file for the first time.
* 4. You can use the static variable SoundEffect.volume to mute the sound.
*/
public enum SoundEffect {
EAT("eat.wav"), // explosion
GONG("gong.wav"), // gong
SHOOT("shoot.wav"); // bullet
// Nested class for specifying volume
public static enum Volume {
MUTE, LOW, MEDIUM, HIGH
}
public static Volume volume = Volume.LOW;
// Each sound effect has its own clip, loaded with its own sound file.
private Clip clip;
// Constructor to construct each element of the enum with its own sound file.
SoundEffect(String soundFileName) {
try {
// Use URL (instead of File) to read from disk and JAR.
URL url = this.getClass().getClassLoader().getResource(soundFileName);
// Set up an audio input stream piped from the sound file.
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(url);
// Get a clip resource.
clip = AudioSystem.getClip();
// Open audio clip and load samples from the audio input stream.
clip.open(audioInputStream);
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}
// Play or Re-play the sound effect from the beginning, by rewinding.
public void play() {
if (volume != Volume.MUTE) {
if (clip.isRunning())
clip.stop(); // Stop the player if it is still running
clip.setFramePosition(0); // rewind to the beginning
clip.start(); // Start playing
}
}
// Optional static method to pre-load all the sound files.
static void init() {
values(); // calls the constructor for all the elements
}
}
Here is an implementation of the EAT sound in my game's Reward class-
public void react(CollisionEvent e)
{
Player player = game.getPlayer();
if (e.contact.involves(player)) {
player.changePlayerImageEAT();
SoundEffect.EAT.play();
player.addPoint();
System.out.println("Player now has: "+player.getPoints()+ " points.");
game.getCurrentLevel().getWorld().remove(this);
}
}
This should play the EAT sound when player comes in contact with a reward in my game.
However, when my player collides with a reward, I get the following errors in the terminal-
javax.sound.sampled.LineUnavailableException: line with format ALAW 8000.0 Hz, 8 bit, stereo, 2 bytes/frame, not supported. at com.sun.media.sound.DirectAudioDevice$DirectDL.implOpen(DirectAudioDevice.java:494) at com.sun.media.sound.DirectAudioDevice$DirectClip.implOpen(DirectAudioDevice.java:1280) at com.sun.media.sound.AbstractDataLine.open(AbstractDataLine.java:107) at com.sun.media.sound.DirectAudioDevice$DirectClip.open(DirectAudioDevice.java:1061) at com.sun.media.sound.DirectAudioDevice$DirectClip.open(DirectAudioDevice.java:1151) at SoundEffect.(SoundEffect.java:39) at SoundEffect.(SoundEffect.java:15) at Reward.react(Reward.java:41) at city.soi.platform.World.despatchCollisionEvents(World.java:425) at city.soi.platform.World.step(World.java:608) at city.soi.platform.World.access$000(World.java:42) at city.soi.platform.World$1.actionPerformed(World.java:756) at javax.swing.Timer.fireActionPerformed(Timer.java:271) at javax.swing.Timer$DoPostEvent.run(Timer.java:201) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) at java.awt.EventQueue.dispatchEvent(EventQueue.java:597) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) at java.awt.EventDispatchThread.run(EventDispatchThread.java:122) Exception in thread "AWT-EventQueue-0" java.lang.ExceptionInInitializerError at Reward.react(Reward.java:41) at city.soi.platform.World.despatchCollisionEvents(World.java:425) at city.soi.platform.World.step(World.java:608) at city.soi.platform.World.access$000(World.java:42) at city.soi.platform.World$1.actionPerformed(World.java:756) at javax.swing.Timer.fireActionPerformed(Timer.java:271) at javax.swing.Timer$DoPostEvent.run(Timer.java:201) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) at java.awt.EventQueue.dispatchEvent(EventQueue.java:597) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) at java.awt.EventDispatchThread.run(EventDispatchThread.java:122) Caused by: java.lang.NullPointerException at com.sun.media.sound.WaveFileReader.getAudioInputStream(WaveFileReader.java:180) at javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:1128) at SoundEffect.(SoundEffect.java:35) at SoundEffect.(SoundEffect.java:16) ... 15 more
I can't figure out what wrong. I'm guessing it has something to do with my audio files (WAV) being unsupported. However, no matter how many ways I convert them they still don't work.
It would be really helpful if someone can kindly enlighten me on what might be wrong and how I can resolve this.
Sample code and any modifications you can offer to help make this code work will be greatly appreciated.
Thank you.
Upvotes: 3
Views: 14729
Reputation: 54421
Your root cause Exception is
javax.sound.sampled.LineUnavailableException:
line with format ALAW 8000.0 Hz, 8 bit, stereo, 2 bytes/frame, not supported
This occurs because not all sound drivers support all bit rates or encodings, or because the machine just doesn't have a sound card. Sound can be encoded in A law or mu law (or others, such as MP3) and can be encoded at different bit rates and sample sizes. Java does not always support all possible sound formats, depending on what is supported by the base system.
You probably want to do the following:
Upvotes: 5