I have just implemented my very first sound "engine" for my game and did it probably very messily because I don't know a whole lot about sounds and Java. Anyways, I have this class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| package Engine;
import java.io.File; import java.io.IOException;
import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.SourceDataLine;
public class SoundEngine {
private static final int BUFFER_SIZE = 128000; private static File soundFile; public static boolean isLoop = false; private static AudioInputStream audioStream; private static AudioFormat audioFormat; private static SourceDataLine sourceLine;
public static void play(String filename) {
String strFilename = filename;
try { soundFile = new File(Frame.class.getResource("imgs/" + strFilename).getFile()); } catch (Exception e) { e.printStackTrace(); System.exit(1); }
try { audioStream = AudioSystem.getAudioInputStream(soundFile); } catch (Exception e) { e.printStackTrace(); System.exit(1); }
audioFormat = audioStream.getFormat();
DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat); try { sourceLine = (SourceDataLine) AudioSystem.getLine(info); sourceLine.open(audioFormat); } catch (LineUnavailableException e) { e.printStackTrace(); System.exit(1); } catch (Exception e) { e.printStackTrace(); System.exit(1); }
sourceLine.start();
int nBytesRead = 0; byte[] abData = new byte[BUFFER_SIZE]; while (nBytesRead != -1 && isLoop != false) { try { nBytesRead = audioStream.read(abData, 0, abData.length); } catch (IOException e) { e.printStackTrace(); } if (nBytesRead >= 0) { @SuppressWarnings("unused") int nBytesWritten = sourceLine.write(abData, 0, nBytesRead); } }
sourceLine.drain(); sourceLine.close(); }
public static void playSound(final String fileName, final boolean isLoopw) { isLoop = isLoopw; Thread t = new Thread(new Runnable() { public void run() { play(fileName); } });
t.setDaemon(true); t.start(); }
public static void playSound(final String fileName) { Thread t = new Thread(new Runnable() { public void run() { play(fileName); } });
t.setDaemon(true); t.start(); } } |
and this class:
1 2 3 4 5 6 7 8
| package Engine;
public class Sounds {
public static String explosion = "explosion.wav"; public static String inGameMusic = "inGameMusic.wav";
} |
which holds all the names for my game. My problem is, whenever I call a sound, namely the explosion because that's the only one I have right now, the game freezes for the duration of the sound, and then continues when the sound is done. I think this definitely has something to do with Threads, but I am not confident in that area at all either so should I multi-thread, one for the game, and one for the sounds and if so, how?
Thanks,
-cMp