Mercurial > hg > ristipolku
diff game/SoundElement.java @ 22:afde253ec705
More work.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 31 Jan 2011 21:28:59 +0200 |
parents | |
children | 0741dc117808 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/game/SoundElement.java Mon Jan 31 21:28:59 2011 +0200 @@ -0,0 +1,189 @@ +/* + * Ristipolku Game Engine + * (C) Copyright 2011 Matti 'ccr' Hämäläinen <ccr@tnsp.org> + */ +package game; + +import java.util.*; +import java.io.*; +import game.*; +import javax.sound.sampled.*; + + +class SoundElement implements Runnable +{ + private final String name; + + private AudioInputStream stream; + private AudioFormat format; + private SourceDataLine line; + private Thread playThread; + private int loopCount; + private boolean playing, streaming; + private int volume = 100; + + byte[] buffer; + int length; + + + SoundElement(String filename, boolean streaming) throws IOException + { + this.name = filename; + this.streaming = streaming; + + ResourceLoader res = new ResourceLoader(name); + if (res == null || res.getStream() == null) + { + throw new IOException("Could not load audio resource '"+name+"'.\n"); + } + + + try { + stream = AudioSystem.getAudioInputStream(res.getStream()); + format = stream.getFormat(); + } + catch (UnsupportedAudioFileException e) { + throw new IOException("Unsupported audio file format for '"+name+"'.\n"); + } + catch (IOException e) + { + throw new IOException("Could not load audio resource '"+name+"'.\n"); + } + + + if (streaming) { + System.out.print("Loading '"+name+"' as a clip\n"); + try { + clip = AudioSystem.getClip(); + clip.open(stream); + } + catch (LineUnavailableException e) + { + throw new IOException("Line unavailable for '"+name+"'.\n"); + } + finally { + stream.close(); + } + } + else + { + clip = null; + System.out.print("Loading '"+name+"' as stream\n"); + + try { + SourceDataLine.Info info = new DataLine.Info(SourceDataLine.class, format); + System.out.print("info: "+stream.getFrameLength() + ", " + format.getFrameSize() + "\n"); + line = (SourceDataLine) AudioSystem.getLine(info); + line.open(format); + } + catch (LineUnavailableException e) { + throw new IOException("Line unavailable for '"+name+"'.\n"); + } + } + } + + public void play() + { + System.out.print("Sound("+name+").play()\n"); + if (streaming) + { + clip.setFramePosition(0); + clip.start(); + } + else + { + if (playThread == null) + { + doPlay = true; + loopCount = 1; + playThread = new Thread(this); + playThread.start(); + } + } + } + + public void loop(int n) + { + System.out.print("Sound("+name+").loop("+n+")\n"); + if (isClip()) + { + clip.setFramePosition(0); + if (n < 0) + clip.loop(Clip.LOOP_CONTINUOUSLY); + else + clip.loop(n); + } + else + { + if (playThread == null) + { + doPlay = true; + loopCount = n; + playThread = new Thread(this); + playThread.start(); + } + } + } + + public void stop() + { + if (isClip()) + { + if (clip.isRunning()) + clip.stop(); + } + else + { + if (playThread != null) + { + playThread.interrupt(); + doPlay = false; + playThread = null; + } + } + } + + public boolean isPlaying() + { + if (isClip()) + return clip.isRunning(); + else + return (playThread != null && line.isRunning()); + } + + public void run() + { + line.start(); + byte[] buf = new byte[line.getBufferSize()]; + + while (doPlay && (loopCount > 0 || loopCount == -1)) + { + try { + int numRead = 0; + while ((numRead = stream.read(buf, 0, buf.length)) >= 0 && doPlay) + { + int offset = 0; + while (offset < numRead) + { + System.out.print("audioThread: offs="+offset+", numread="+numRead+"\n"); + offset += line.write(buf, offset, numRead - offset); + } + } + line.drain(); + + System.out.print("audioThread: stream.reset()\n"); + stream.reset(); + } + catch (IOException e) { + } + + if (loopCount > 0) + loopCount--; + } + + line.stop(); + doPlay = false; + } +} + +