diff options
Diffstat (limited to 'src/tetris/audio')
-rw-r--r-- | src/tetris/audio/SoundPlayer.java | 323 | ||||
-rw-r--r-- | src/tetris/audio/TetrisSounds.java | 73 | ||||
-rw-r--r-- | src/tetris/audio/papercrumple.wav | bin | 0 -> 369638 bytes | |||
-rw-r--r-- | src/tetris/audio/pencileraser.wav | bin | 0 -> 474152 bytes | |||
-rw-r--r-- | src/tetris/audio/pencilsharpen.aif | bin | 0 -> 1303926 bytes |
5 files changed, 396 insertions, 0 deletions
diff --git a/src/tetris/audio/SoundPlayer.java b/src/tetris/audio/SoundPlayer.java new file mode 100644 index 0000000..6e2cf8f --- /dev/null +++ b/src/tetris/audio/SoundPlayer.java @@ -0,0 +1,323 @@ +/* + * Audio Clip Player TCSS 305 - Autumn 2008 (Zimmerman) + */ + +package tetris.audio; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Clip; +import javax.sound.sampled.Line; +import javax.sound.sampled.LineEvent; +import javax.sound.sampled.LineListener; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.UnsupportedAudioFileException; + +/** + * A class to play audio clips. Caches previously-played clips, allowing fast + * re-playback of previously played sounds. + * + * @author Marty Stepp + * @author Daniel M. Zimmerman (code cleanup) + * @version 1.0 + */ + +public class SoundPlayer { + /** + * A cache of previously-played audio clips. + */ + + private final Map<String, Clip> my_clips = new HashMap<String, Clip>(); + + /** + * Plays the audio file with the given file name. This method returns + * instantly, without waiting for the clip to finish playing. + * + * @param the_filename The name of the file (relative to the current working + * directory) to play. + * @return a Clip object representing the sound played. (for convenience; this + * result need not be used/stored). + * @exception IllegalArgumentException if there is a problem reading from the + * sound file. + */ + + public Clip play(final String the_filename) throws IllegalArgumentException { + final Clip clip = getClip(the_filename); + + if (clip != null) { + clip.start(); + } + + return clip; + } + + /** + * Plays the audio file with the given file name, waiting until the clip is + * done playing before returning. + * + * @param the_filename The name of the file (relative to the current working + * directory) to play. + * @return a Clip object representing the sound played. (for convenience; this + * result need not be used/stored). + * @exception IllegalArgumentException if there is a problem reading from the + * sound file. + */ + + public Clip playAndWait(final String the_filename) throws IllegalArgumentException { + final Clip clip = getClip(the_filename); + + if (clip != null) { + clip.start(); + try { + synchronized (clip) { + while (clip.isRunning()) { + clip.wait(); // wait for clip to finish + } + } + } catch (final InterruptedException ie) { + // ignored + return clip; + } + } + + return clip; + } + + /** + * Plays the clip with the given file name in a continuous loop. The clip + * keeps looping until it is later stopped by calling the stop() method. This + * function returns instantly + * + * @param the_filename The name of the file (relative to the current working + * directory) to play. + * @return a Clip object representing the sound played. (for convenience; this + * result need not be used/stored). + * @exception IllegalArgumentException if there is a problem reading from the + * sound file. + */ + + public Clip loop(final String the_filename) throws IllegalArgumentException { + return loop(the_filename, Clip.LOOP_CONTINUOUSLY); + } + + /** + * Plays the clip with the given file name in a loop. The clip loops until it + * has played the specified number of times, or until it is later stopped by + * calling the stop() method. This function returns instantly, without waiting + * for the clip to finish looping. + * + * @param the_filename The name of the file (relative to the current working + * directory) to play. + * @param the_number_of_times The number of times to loop the clip. + * @return a Clip object representing the sound played. (for convenience; this + * result need not be used/stored). + * @exception IllegalArgumentException if there is a problem reading from the + * sound file. + */ + + public Clip loop(final String the_filename, final int the_number_of_times) + throws IllegalArgumentException { + final Clip clip = getClip(the_filename); + + if (clip != null) { + clip.loop(the_number_of_times); + } + + return clip; + } + + /** + * Plays the clip with the given file name in a loop. The clip loops + * continuously until it is stopped by calling the stop() method. This method + * waits until the clip is done looping before returning. Note that since the + * clip loops continuously, this method will not return unless some other + * thread stops the clip. + * + * @param the_filename The name of the file (relative to the current working + * directory) to play. + * @return a Clip object representing the sound played. (for convenience; this + * result need not be used/stored). + * @exception IllegalArgumentException if there is a problem reading from the + * sound file. + */ + + public Clip loopAndWait(final String the_filename) throws IllegalArgumentException { + return loopAndWait(the_filename, Clip.LOOP_CONTINUOUSLY); + } + + /** + * Plays the clip with the given file name in a loop. The clip loops until it + * has played the specified number of times, or until it is stopped by calling + * the stop() method. This method waits until the clip is done looping before + * returning. + * + * @param the_filename The name of the file (relative to the current working + * directory) to play. + * @param the_number_of_times The number of times to loop the clip. + * @return a Clip object representing the sound played. (for convenience; this + * result need not be used/stored). + * @exception IllegalArgumentException if there is a problem reading from the + * sound file. + */ + + public Clip loopAndWait(final String the_filename, final int the_number_of_times) + throws IllegalArgumentException { + final Clip clip = getClip(the_filename); + + if (clip != null) { + clip.loop(the_number_of_times); + try { + while (clip.isRunning()) { + clip.wait(); // wait for clip to finish + } + } catch (final InterruptedException ie) { + return clip; + } + } + + return clip; + } + + /** + * Pauses the clip with the given file name. If the clip is later played, it + * will resume from where it was paused. Calling this method does not resume a + * thread that is suspended on a playAndWait() or a loopAndWait(). + * + * If stop() is called on a paused clip, it will reset to the beginning of the + * clip for the next play. + * + * @param the_filename The name of the file (relative to the current working + * directory) to pause. + * @exception IllegalArgumentException if there is a problem reading from or + * playing the sound file. + */ + + public void pause(final String the_filename) throws IllegalArgumentException { + final Clip clip = getClip(the_filename); + + if (clip != null) { + final int pos = clip.getFramePosition(); + clip.stop(); + clip.setFramePosition(pos); + } + } + + /** + * Stops the clip with the specified filename (and wakes up any threads + * waiting for it to finish playing). + * + * @param the_filename The name of the file (relative to the current working + * directory) to stop. + * @return a Clip object representing the sound stopped. + * @exception IllegalArgumentException if there is a problem reading from the + * sound file. + */ + + public Clip stop(final String the_filename) throws IllegalArgumentException { + final Clip clip = getClip(the_filename); + stopClip(clip); + + return clip; + } + + /** + * Stops all currently playing sound clips (and wakes up the threads waiting + * for them to finish playing). + */ + + public void stopAll() { + for (Clip clip : my_clips.values()) { + stopClip(clip); + } + } + + /** + * Preloads the clip at the given file name. This means the clip will be + * available faster, when requested for playing the first time. + * + * @param the_filename The name of the file (relative to the current working + * directory) to preload. + * @return a Clip object representing the preloaded sound. + * @exception IllegalArgumentException if there is a problem reading from the + * sound file. + */ + + public Clip preLoad(final String the_filename) throws IllegalArgumentException { + return getClip(the_filename); + } + + /** + * Returns a Clip object for a filename, either by creating a new one or + * loading it from the cache. + * + * @param the_filename The name of the file (relative to the current working + * directory) to load. + * @return a Clip object, or null if one is not found. + * @exception IllegalArgumentException if there is a problem reading from the + * sound file. + */ + + private Clip getClip(final String the_filename) throws IllegalArgumentException { + Clip clip = null; + AudioInputStream ais = null; + + if (my_clips.containsKey(the_filename)) { + clip = my_clips.get(the_filename); + } else { + // read audio file from disk + try { + ais = AudioSystem.getAudioInputStream(ClassLoader.getSystemResource(the_filename)); + clip = (Clip) AudioSystem.getLine(new Line.Info(Clip.class)); + clip.open(ais); + clip.addLineListener(new LineListener() { + /** + * Responds to audio events generated by clips. + * + * @param the_event The event generated. + */ + + public void update(final LineEvent the_event) { + if (the_event.getType() == LineEvent.Type.STOP) { + // clip is done playing + stopClip((Clip) the_event.getSource()); + } + } + }); + my_clips.put(the_filename, clip); + } catch (final UnsupportedAudioFileException uafe) { + throw new IllegalArgumentException("Not a valid supported audio file: \"" + + the_filename + "\""); + } catch (final LineUnavailableException lue) { + throw new IllegalArgumentException("Line is not available to play sound \"" + + the_filename + "\""); + } catch (final IOException ioe) { + throw new IllegalArgumentException("I/O error while reading file: \"" + the_filename + + "\""); + } + } + + return clip; + } + + /** + * Stops the playing of the specified clip. + * + * @param the_clip The clip. + */ + + private void stopClip(final Clip the_clip) { + if (the_clip != null) { + synchronized (the_clip) { + the_clip.stop(); + the_clip.setFramePosition(0); + the_clip.notifyAll(); // awaken threads waiting for this Clip + } + } + } +} + +// end of class SoundPlayer diff --git a/src/tetris/audio/TetrisSounds.java b/src/tetris/audio/TetrisSounds.java new file mode 100644 index 0000000..b28e49a --- /dev/null +++ b/src/tetris/audio/TetrisSounds.java @@ -0,0 +1,73 @@ +/* + * Jesse Morgan <jesterpm@u.washington.edu> + * + * TCSS 305 - Autumn 2009 + * Tetris Project + * 17 November 2009 + */ + +package tetris.audio; + +import java.util.Observable; +import java.util.Observer; + +import tetris.board.TetrisBoardEvent; + + +/** + * Class to play sounds for a tetris game. + * + * @author Jesse Morgan <jesterpm@u.washington.edu> + * @version 1.0 23 November 2009 + */ +public class TetrisSounds implements Observer { + // Private fields. + /** + * The SoundPlayer. + */ + private final SoundPlayer my_soundplayer; + + /** + * Create a Tetris Sound Effects player. + */ + public TetrisSounds() { + my_soundplayer = new SoundPlayer(); + } + + /** + * Handle notifications. + * + * @param the_observable The TetrisBoard. + * @param the_arg The Event. + */ + public void update(final Observable the_observable, final Object the_arg) { + if (the_arg instanceof TetrisBoardEvent) { + final TetrisBoardEvent event = (TetrisBoardEvent) the_arg; + + try { + switch (event.getType()) { + case NEW_GAME: + my_soundplayer.play("tetris/audio/pencilsharpen.aif"); + break; + + case LINES_CLEARED: + my_soundplayer.play("tetris/audio/pencileraser.wav"); + break; + + case GAME_OVER: + my_soundplayer.play("tetris/audio/papercrumple.wav"); + break; + + default: + } + + } catch (final IllegalArgumentException the_exception) { + // Couldn't play for some reason... + // Sounds aren't important anyways, gracefully ignore + return; + } + } + } + + +} diff --git a/src/tetris/audio/papercrumple.wav b/src/tetris/audio/papercrumple.wav Binary files differnew file mode 100644 index 0000000..ed8e759 --- /dev/null +++ b/src/tetris/audio/papercrumple.wav diff --git a/src/tetris/audio/pencileraser.wav b/src/tetris/audio/pencileraser.wav Binary files differnew file mode 100644 index 0000000..ca371ec --- /dev/null +++ b/src/tetris/audio/pencileraser.wav diff --git a/src/tetris/audio/pencilsharpen.aif b/src/tetris/audio/pencilsharpen.aif Binary files differnew file mode 100644 index 0000000..a7344b5 --- /dev/null +++ b/src/tetris/audio/pencilsharpen.aif |