Java/Development Class/Sound

Материал из Java эксперт
Перейти к: навигация, поиск

Содержание

An example of loading and playing a sound using a Clip

   <source lang="java">

      /*

DEVELOPING GAME IN JAVA Caracteristiques Editeur : NEW RIDERS Auteur : BRACKEEN Parution : 09 2003 Pages : 972 Isbn : 1-59273-005-1 Reliure : Paperback Disponibilite : Disponible a la librairie

  • /

import java.io.File; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; import javax.sound.sampled.DataLine; import javax.sound.sampled.LineEvent; import javax.sound.sampled.LineListener; /**

* An example of loading and playing a sound using a Clip. This complete class
* isn"t in the book ;)
*/

public class ClipTest {

 public static void main(String[] args) throws Exception {
   // specify the sound to play
   // (assuming the sound can be played by the audio system)
   File soundFile = new File("../sounds/voice.wav");
   AudioInputStream sound = AudioSystem.getAudioInputStream(soundFile);
   // load the sound into memory (a Clip)
   DataLine.Info info = new DataLine.Info(Clip.class, sound.getFormat());
   Clip clip = (Clip) AudioSystem.getLine(info);
   clip.open(sound);
   // due to bug in Java Sound, explicitly exit the VM when
   // the sound has stopped.
   clip.addLineListener(new LineListener() {
     public void update(LineEvent event) {
       if (event.getType() == LineEvent.Type.STOP) {
         event.getLine().close();
         System.exit(0);
       }
     }
   });
   // play the sound clip
   clip.start();
 }

}


 </source>
   
  
 
  



An example of playing a sound with an echo filter

   <source lang="java">

      /*

DEVELOPING GAME IN JAVA Caracteristiques Editeur : NEW RIDERS Auteur : BRACKEEN Parution : 09 2003 Pages : 972 Isbn : 1-59273-005-1 Reliure : Paperback Disponibilite : Disponible a la librairie

  • /

import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.File; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; 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; import javax.sound.sampled.UnsupportedAudioFileException; /**

* An example of playing a sound with an echo filter.
* 
* @see EchoFilter
* @see SimpleSoundPlayer
*/

public class EchoFilterTest {

 public static void main(String[] args) {
   // load the sound
   SimpleSoundPlayer sound = new SimpleSoundPlayer("../sounds/voice.wav");
   // create the sound stream
   InputStream is = new ByteArrayInputStream(sound.getSamples());
   // create an echo with a 11025-sample buffer
   // (1/4 sec for 44100Hz sound) and a 60% decay
   EchoFilter filter = new EchoFilter(11025, .6f);
   // create the filtered sound stream
   is = new FilteredSoundStream(is, filter);
   // play the sound
   sound.play(is);
   // due to bug in Java Sound, explicitly exit the VM.
   System.exit(0);
 }

} /**

* The SimpleSoundPlayer encapsulates a sound that can be opened from the file
* system and later played.
*/

class SimpleSoundPlayer {

 public static void main(String[] args) {
   // load a sound
   SimpleSoundPlayer sound = new SimpleSoundPlayer("../sounds/voice.wav");
   // create the stream to play
   InputStream stream = new ByteArrayInputStream(sound.getSamples());
   // play the sound
   sound.play(stream);
   // exit
   System.exit(0);
 }
 private AudioFormat format;
 private byte[] samples;
 /**
  * Opens a sound from a file.
  */
 public SimpleSoundPlayer(String filename) {
   try {
     // open the audio input stream
     AudioInputStream stream = AudioSystem.getAudioInputStream(new File(
         filename));
     format = stream.getFormat();
     // get the audio samples
     samples = getSamples(stream);
   } catch (UnsupportedAudioFileException ex) {
     ex.printStackTrace();
   } catch (IOException ex) {
     ex.printStackTrace();
   }
 }
 /**
  * Gets the samples of this sound as a byte array.
  */
 public byte[] getSamples() {
   return samples;
 }
 /**
  * Gets the samples from an AudioInputStream as an array of bytes.
  */
 private byte[] getSamples(AudioInputStream audioStream) {
   // get the number of bytes to read
   int length = (int) (audioStream.getFrameLength() * format
       .getFrameSize());
   // read the entire stream
   byte[] samples = new byte[length];
   DataInputStream is = new DataInputStream(audioStream);
   try {
     is.readFully(samples);
   } catch (IOException ex) {
     ex.printStackTrace();
   }
   // return the samples
   return samples;
 }
 /**
  * Plays a stream. This method blocks (doesn"t return) until the sound is
  * finished playing.
  */
 public void play(InputStream source) {
   // use a short, 100ms (1/10th sec) buffer for real-time
   // change to the sound stream
   int bufferSize = format.getFrameSize()
       * Math.round(format.getSampleRate() / 10);
   byte[] buffer = new byte[bufferSize];
   // create a line to play to
   SourceDataLine line;
   try {
     DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
     line = (SourceDataLine) AudioSystem.getLine(info);
     line.open(format, bufferSize);
   } catch (LineUnavailableException ex) {
     ex.printStackTrace();
     return;
   }
   // start the line
   line.start();
   // copy data to the line
   try {
     int numBytesRead = 0;
     while (numBytesRead != -1) {
       numBytesRead = source.read(buffer, 0, buffer.length);
       if (numBytesRead != -1) {
         line.write(buffer, 0, numBytesRead);
       }
     }
   } catch (IOException ex) {
     ex.printStackTrace();
   }
   // wait until all data is played, then close the line
   line.drain();
   line.close();
 }

} /**

* The EchoFilter class is a SoundFilter that emulates an echo.
* 
* @see FilteredSoundStream
*/

class EchoFilter extends SoundFilter {

 private short[] delayBuffer;
 private int delayBufferPos;
 private float decay;
 /**
  * Creates an EchoFilter with the specified number of delay samples and the
  * specified decay rate.
*

* The number of delay samples specifies how long before the echo is * initially heard. For a 1 second echo with mono, 44100Hz sound, use 44100 * delay samples. * <p> * The decay value is how much the echo has decayed from the source. A decay * value of .5 means the echo heard is half as loud as the source. */ public EchoFilter(int numDelaySamples, float decay) { delayBuffer = new short[numDelaySamples]; this.decay = decay; } /** * Gets the remaining size, in bytes, of samples that this filter can echo * after the sound is done playing. Ensures that the sound will have decayed * to below 1% of maximum volume (amplitude). */ public int getRemainingSize() { float finalDecay = 0.01f; // derived from Math.pow(decay,x) <= finalDecay int numRemainingBuffers = (int) Math.ceil(Math.log(finalDecay) / Math.log(decay)); int bufferSize = delayBuffer.length * 2; return bufferSize * numRemainingBuffers; } /** * Clears this EchoFilter"s internal delay buffer. */ public void reset() { for (int i = 0; i < delayBuffer.length; i++) { delayBuffer[i] = 0; } delayBufferPos = 0; } /** * Filters the sound samples to add an echo. The samples played are added to * the sound in the delay buffer multipied by the decay rate. The result is * then stored in the delay buffer, so multiple echoes are heard. */ public void filter(byte[] samples, int offset, int length) { for (int i = offset; i < offset + length; i += 2) { // update the sample short oldSample = getSample(samples, i); short newSample = (short) (oldSample + decay * delayBuffer[delayBufferPos]); setSample(samples, i, newSample); // update the delay buffer delayBuffer[delayBufferPos] = newSample; delayBufferPos++; if (delayBufferPos == delayBuffer.length) { delayBufferPos = 0; } } } } /** * The FilteredSoundStream class is a FilterInputStream that applies a * SoundFilter to the underlying input stream. * * @see SoundFilter */ class FilteredSoundStream extends FilterInputStream { private static final int REMAINING_SIZE_UNKNOWN = -1; private SoundFilter soundFilter; private int remainingSize; /** * Creates a new FilteredSoundStream object with the specified InputStream * and SoundFilter. */ public FilteredSoundStream(InputStream in, SoundFilter soundFilter) { super(in); this.soundFilter = soundFilter; remainingSize = REMAINING_SIZE_UNKNOWN; } /** * Overrides the FilterInputStream method to apply this filter whenever * bytes are read */ public int read(byte[] samples, int offset, int length) throws IOException { // read and filter the sound samples in the stream int bytesRead = super.read(samples, offset, length); if (bytesRead > 0) { soundFilter.filter(samples, offset, bytesRead); return bytesRead; } // if there are no remaining bytes in the sound stream, // check if the filter has any remaining bytes ("echoes"). if (remainingSize == REMAINING_SIZE_UNKNOWN) { remainingSize = soundFilter.getRemainingSize(); // round down to nearest multiple of 4 // (typical frame size) remainingSize = remainingSize / 4 * 4; } if (remainingSize > 0) { length = Math.min(length, remainingSize); // clear the buffer for (int i = offset; i < offset + length; i++) { samples[i] = 0; } // filter the remaining bytes soundFilter.filter(samples, offset, length); remainingSize -= length; // return return length; } else { // end of stream return -1; } } } /** * A abstract class designed to filter sound samples. Since SoundFilters may use * internal buffering of samples, a new SoundFilter object should be created for * every sound played. However, SoundFilters can be reused after they are * finished by called the reset() method. * <p> * Assumes all samples are 16-bit, signed, little-endian format. * * @see FilteredSoundStream */ abstract class SoundFilter { /** * Resets this SoundFilter. Does nothing by default. */ public void reset() { // do nothing } /** * Gets the remaining size, in bytes, that this filter plays after the sound * is finished. An example would be an echo that plays longer than it"s * original sound. This method returns 0 by default. */ public int getRemainingSize() { return 0; } /** * Filters an array of samples. Samples should be in 16-bit, signed, * little-endian format. */ public void filter(byte[] samples) { filter(samples, 0, samples.length); } /** * Filters an array of samples. Samples should be in 16-bit, signed, * little-endian format. This method should be implemented by subclasses. */ public abstract void filter(byte[] samples, int offset, int length); /** * Convenience method for getting a 16-bit sample from a byte array. Samples * should be in 16-bit, signed, little-endian format. */ public static short getSample(byte[] buffer, int position) { return (short) (((buffer[position + 1] & 0xff) << 8) | (buffer[position] & 0xff)); } /** * Convenience method for setting a 16-bit sample in a byte array. Samples * should be in 16-bit, signed, little-endian format. */ public static void setSample(byte[] buffer, int position, short sample) { buffer[position] = (byte) (sample & 0xff); buffer[position + 1] = (byte) ((sample >> 8) & 0xff); } } </source>

An example that plays a Midi sequence

   <source lang="java">

      /*

DEVELOPING GAME IN JAVA Caracteristiques Editeur : NEW RIDERS Auteur : BRACKEEN Parution : 09 2003 Pages : 972 Isbn : 1-59273-005-1 Reliure : Paperback Disponibilite : Disponible a la librairie

  • /

import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import javax.sound.midi.InvalidMidiDataException; import javax.sound.midi.MetaEventListener; import javax.sound.midi.MetaMessage; import javax.sound.midi.MidiSystem; import javax.sound.midi.MidiUnavailableException; import javax.sound.midi.Sequence; import javax.sound.midi.Sequencer; /**

* An example that plays a Midi sequence. First, the sequence is played once
* with track 1 turned off. Then the sequence is played once with track 1 turned
* on. Track 1 is the drum track in the example midi file.
*/

public class MidiTest implements MetaEventListener {

 // The drum track in the example Midi file
 private static final int DRUM_TRACK = 1;
 public static void main(String[] args) {
   new MidiTest().run();
 }
 private MidiPlayer player;
 public void run() {
   player = new MidiPlayer();
   // load a sequence
   Sequence sequence = player.getSequence("../sounds/music.midi");
   // play the sequence
   player.play(sequence, true);
   // turn off the drums
   System.out.println("Playing (without drums)...");
   Sequencer sequencer = player.getSequencer();
   sequencer.setTrackMute(DRUM_TRACK, true);
   sequencer.addMetaEventListener(this);
 }
 /**
  * This method is called by the sound system when a meta event occurs. In
  * this case, when the end-of-track meta event is received, the drum track
  * is turned on.
  */
 public void meta(MetaMessage event) {
   if (event.getType() == MidiPlayer.END_OF_TRACK_MESSAGE) {
     Sequencer sequencer = player.getSequencer();
     if (sequencer.getTrackMute(DRUM_TRACK)) {
       // turn on the drum track
       System.out.println("Turning on drums...");
       sequencer.setTrackMute(DRUM_TRACK, false);
     } else {
       // close the sequencer and exit
       System.out.println("Exiting...");
       player.close();
       System.exit(0);
     }
   }
 }

} class MidiPlayer implements MetaEventListener {

 // Midi meta event
 public static final int END_OF_TRACK_MESSAGE = 47;
 private Sequencer sequencer;
 private boolean loop;
 private boolean paused;
 /**
  * Creates a new MidiPlayer object.
  */
 public MidiPlayer() {
   try {
     sequencer = MidiSystem.getSequencer();
     sequencer.open();
     sequencer.addMetaEventListener(this);
   } catch (MidiUnavailableException ex) {
     sequencer = null;
   }
 }
 /**
  * Loads a sequence from the file system. Returns null if an error occurs.
  */
 public Sequence getSequence(String filename) {
   try {
     return getSequence(new FileInputStream(filename));
   } catch (IOException ex) {
     ex.printStackTrace();
     return null;
   }
 }
 /**
  * Loads a sequence from an input stream. Returns null if an error occurs.
  */
 public Sequence getSequence(InputStream is) {
   try {
     if (!is.markSupported()) {
       is = new BufferedInputStream(is);
     }
     Sequence s = MidiSystem.getSequence(is);
     is.close();
     return s;
   } catch (InvalidMidiDataException ex) {
     ex.printStackTrace();
     return null;
   } catch (IOException ex) {
     ex.printStackTrace();
     return null;
   }
 }
 /**
  * Plays a sequence, optionally looping. This method returns immediately.
  * The sequence is not played if it is invalid.
  */
 public void play(Sequence sequence, boolean loop) {
   if (sequencer != null && sequence != null && sequencer.isOpen()) {
     try {
       sequencer.setSequence(sequence);
       sequencer.start();
       this.loop = loop;
     } catch (InvalidMidiDataException ex) {
       ex.printStackTrace();
     }
   }
 }
 /**
  * This method is called by the sound system when a meta event occurs. In
  * this case, when the end-of-track meta event is received, the sequence is
  * restarted if looping is on.
  */
 public void meta(MetaMessage event) {
   if (event.getType() == END_OF_TRACK_MESSAGE) {
     if (sequencer != null && sequencer.isOpen() && loop) {
       sequencer.start();
     }
   }
 }
 /**
  * Stops the sequencer and resets its position to 0.
  */
 public void stop() {
   if (sequencer != null && sequencer.isOpen()) {
     sequencer.stop();
     sequencer.setMicrosecondPosition(0);
   }
 }
 /**
  * Closes the sequencer.
  */
 public void close() {
   if (sequencer != null && sequencer.isOpen()) {
     sequencer.close();
   }
 }
 /**
  * Gets the sequencer.
  */
 public Sequencer getSequencer() {
   return sequencer;
 }
 /**
  * Sets the paused state. Music may not immediately pause.
  */
 public void setPaused(boolean paused) {
   if (this.paused != paused && sequencer != null && sequencer.isOpen()) {
     this.paused = paused;
     if (paused) {
       sequencer.stop();
     } else {
       sequencer.start();
     }
   }
 }
 /**
  * Returns the paused state.
  */
 public boolean isPaused() {
   return paused;
 }

}


 </source>
   
  
 
  



A simple player for sampled sound files.

   <source lang="java">

/*

*
* Copyright (c) 1999 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free,
* license to use, modify and redistribute this software in 
* source and binary code form, provided that i) this copyright
* notice and license appear on all copies of the software; and 
* ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty
* of any kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS
* AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE 
* HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR 
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT
* WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT
* OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, 
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS
* OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY
* TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGES.
This software is not designed or intended for use in on-line
control of aircraft, air traffic, aircraft navigation or
aircraft communications; or in the design, construction,
operation or maintenance of any nuclear facility. Licensee 
represents and warrants that it will not use or redistribute 
the Software for such purposes.
*/

/* The above copyright statement is included because this

* program uses several methods from the JavaSoundDemo
* distributed by SUN. In some cases, the sound processing methods
* unmodified or only slightly modified.
* All other methods copyright Steve Potts, 2002
*/

import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.util.Vector; import javax.sound.midi.InvalidMidiDataException; import javax.sound.midi.MetaEventListener; import javax.sound.midi.MetaMessage; import javax.sound.midi.MidiChannel; import javax.sound.midi.MidiSystem; import javax.sound.midi.Sequence; import javax.sound.midi.Sequencer; import javax.sound.midi.Synthesizer; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; import javax.sound.sampled.DataLine; import javax.sound.sampled.LineEvent; import javax.sound.sampled.LineListener; /**

* A simple player for sampled sound files.
* 
* 
* @author Steve Potts
*/

public class SimpleSoundPlayer implements Runnable, LineListener, MetaEventListener {

 final int bufSize = 16384;
 Vector sounds = new Vector();
 Thread thread;
 Sequencer sequencer;
 boolean midiEOM, audioEOM;
 Synthesizer synthesizer;
 MidiChannel channels[];
 Object currentSound;
 String currentName;
 double duration;
 int num;
 boolean bump;
 boolean paused = false;
 String errStr;
 public void open() {
   try {
     sequencer = MidiSystem.getSequencer();
     if (sequencer instanceof Synthesizer) {
       synthesizer = (Synthesizer) sequencer;
       channels = synthesizer.getChannels();
     }
   } catch (Exception ex) {
     ex.printStackTrace();
     return;
   }
   sequencer.addMetaEventListener(this);
 }
 public void close() {
   if (sequencer != null) {
     sequencer.close();
   }
 }
 private void addSound(File file) {
   sounds.add(file);
 }
 public boolean loadSound(Object object) {
   duration = 0.0;
   currentName = ((File) object).getName();
   try {
     currentSound = AudioSystem.getAudioInputStream((File) object);
   } catch (Exception e1) {
     try {
       FileInputStream is = new FileInputStream((File) object);
       currentSound = new BufferedInputStream(is, 1024);
     } catch (Exception e3) {
       e3.printStackTrace();
       currentSound = null;
       return false;
     }
     // }
   }
   // user pressed stop or changed tabs while loading
   if (sequencer == null) {
     currentSound = null;
     return false;
   }
   if (currentSound instanceof AudioInputStream) {
     try {
       AudioInputStream stream = (AudioInputStream) currentSound;
       AudioFormat format = stream.getFormat();
       /**
        * we can"t yet open the device for ALAW/ULAW playback, convert
        * ALAW/ULAW to PCM
        */
       if ((format.getEncoding() == AudioFormat.Encoding.ULAW)
           || (format.getEncoding() == AudioFormat.Encoding.ALAW)) {
         AudioFormat tmp = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
             format.getSampleRate(), format.getSampleSizeInBits() * 2, format.getChannels(),
             format.getFrameSize() * 2, format.getFrameRate(), true);
         stream = AudioSystem.getAudioInputStream(tmp, stream);
         format = tmp;
       }
       DataLine.Info info = new DataLine.Info(Clip.class, stream.getFormat(), ((int) stream
           .getFrameLength() * format.getFrameSize()));
       Clip clip = (Clip) AudioSystem.getLine(info);
       clip.addLineListener(this);
       clip.open(stream);
       currentSound = clip;
       // seekSlider.setMaximum((int) stream.getFrameLength());
     } catch (Exception ex) {
       ex.printStackTrace();
       currentSound = null;
       return false;
     }
   } else if (currentSound instanceof Sequence || currentSound instanceof BufferedInputStream) {
     try {
       sequencer.open();
       if (currentSound instanceof Sequence) {
         sequencer.setSequence((Sequence) currentSound);
       } else {
         sequencer.setSequence((BufferedInputStream) currentSound);
       }
     } catch (InvalidMidiDataException imde) {
       System.out.println("Unsupported audio file.");
       currentSound = null;
       return false;
     } catch (Exception ex) {
       ex.printStackTrace();
       currentSound = null;
       return false;
     }
   }
   duration = getDuration();
   return true;
 }
 public void playSound() {
   midiEOM = audioEOM = bump = false;
   if (currentSound instanceof Sequence || currentSound instanceof BufferedInputStream
       && thread != null) {
     sequencer.start();
     while (!midiEOM && thread != null && !bump) {
       try {
         thread.sleep(99);
       } catch (Exception e) {
         break;
       }
     }
     sequencer.stop();
     sequencer.close();
   } else if (currentSound instanceof Clip) {
     Clip clip = (Clip) currentSound;
     clip.start();
     try {
       thread.sleep(99);
     } catch (Exception e) {
     }
     while ((paused || clip.isActive()) && thread != null && !bump) {
       try {
         thread.sleep(99);
       } catch (Exception e) {
         break;
       }
     }
     clip.stop();
     clip.close();
   }
   currentSound = null;
 }
 public double getDuration() {
   double duration = 0.0;
   if (currentSound instanceof Sequence) {
     duration = ((Sequence) currentSound).getMicrosecondLength() / 1000000.0;
   } else if (currentSound instanceof BufferedInputStream) {
     duration = sequencer.getMicrosecondLength() / 1000000.0;
   } else if (currentSound instanceof Clip) {
     Clip clip = (Clip) currentSound;
     duration = clip.getBufferSize()
         / (clip.getFormat().getFrameSize() * clip.getFormat().getFrameRate());
   }
   return duration;
 }
 public void update(LineEvent event) {
   if (event.getType() == LineEvent.Type.STOP && !paused) {
     audioEOM = true;
   }
 }
 public void meta(MetaMessage message) {
   if (message.getType() == 47) { // 47 is end of track
     midiEOM = true;
   }
 }
 private void reportStatus(String msg) {
   if ((errStr = msg) != null) {
     System.out.println(errStr);
   }
 }
 public Thread getThread() {
   return thread;
 }
 public void start() {
   thread = new Thread(this);
   thread.setName("SimpleSamplePlayer");
   thread.start();
 }
 public void stop() {
   if (thread != null) {
     thread.interrupt();
   }
   thread = null;
 }
 public void run() {
   for (; num < sounds.size() && thread != null; num++) {
     if (loadSound(sounds.get(num)) == true) {
       playSound();
     }
     // take a little break between sounds
     try {
       thread.sleep(222);
     } catch (Exception e) {
       break;
     }
   }
   num = 0;
   thread = null;
   currentName = null;
   currentSound = null;
   System.out.println("Press <ctrl-c> to exit");
 }
 public void loadSounds(String name) {
   try {
     File file = new File(name);
     if (file != null && file.isDirectory()) {
       String files[] = file.list();
       for (int i = 0; i < files.length; i++) {
         File leafFile = new File(file.getAbsolutePath(), files[i]);
         addSound(leafFile);
       }
     }
   } catch (Exception e) {
     System.out.println("Exception " + e);
   }
 }
 public static void main(String args[]) {
   // every file in this directory will be played
   String media = "c:/unleashed/ch18/sounds";
   final SimpleSoundPlayer ssp = new SimpleSoundPlayer();
   ssp.open();
   // we first load the sound file names in a vector
   ssp.loadSounds(media);
   // Then we start a thread to play the sounds
   ssp.start();
   // We have to wait for a while so that the process doesn"t
   // terminate, killing the playing thread
   try {
     Thread.sleep(500000);
   } catch (Exception e) {
     System.out.println("Interrupted");
   }
   // close and exit
   ssp.close();
   System.exit(0);
 }

}

 </source>
   
  
 
  



audio sound: implements java.applet.AudioClip

   <source lang="java">

// This example is from the book _Java AWT Reference_ by John Zukowski. // Written by John Zukowski. Copyright (c) 1997 O"Reilly & Associates. // You may study, use, modify, and distribute this example for any purpose. // This example is provided WITHOUT WARRANTY either expressed or import java.io.FileInputStream; import java.net.URL; import sun.audio.AudioData; import sun.audio.AudioDataStream; import sun.audio.AudioPlayer; import sun.audio.AudioStream; import sun.audio.ContinuousAudioDataStream; public class SunAudioClip implements java.applet.AudioClip {

 private AudioData audiodata;
 private AudioDataStream audiostream;
 private ContinuousAudioDataStream continuousaudiostream;
 static int length;
 public SunAudioClip(URL url) throws java.io.IOException {
   audiodata = new AudioStream(url.openStream()).getData();
   audiostream = null;
   continuousaudiostream = null;
 }
 public SunAudioClip(String filename) throws java.io.IOException {
   FileInputStream fis = new FileInputStream(filename);
   AudioStream audioStream = new AudioStream(fis);
   audiodata = audioStream.getData();
   audiostream = null;
   continuousaudiostream = null;
 }
 public void play() {
   audiostream = new AudioDataStream(audiodata);
   AudioPlayer.player.start(audiostream);
 }
 public void loop() {
   continuousaudiostream = new ContinuousAudioDataStream(audiodata);
   AudioPlayer.player.start(continuousaudiostream);
 }
 public void stop() {
   if (audiostream != null)
     AudioPlayer.player.stop(audiostream);
   if (continuousaudiostream != null)
     AudioPlayer.player.stop(continuousaudiostream);
 }
 public static void main(String args[]) throws Exception {
   URL url1 = new URL("http://localhost:8080/audio/1.au");
   URL url2 = new URL("http://localhost:8080/audio/2.au");
   SunAudioClip sac1 = new SunAudioClip(url1);
   SunAudioClip sac2 = new SunAudioClip(url2);
   SunAudioClip sac3 = new SunAudioClip("1.au");
   sac1.play();
   sac2.loop();
   sac3.play();
   try { // Delay for loop
     Thread.sleep(2000);
   } catch (InterruptedException ie) {
   }
   sac2.stop();
 }

}

 </source>
   
  
 
  



Capturing Audio with Java Sound API

   <source lang="java">


import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine; import javax.sound.sampled.SourceDataLine; import javax.sound.sampled.TargetDataLine; public class Main {

 public static void main(String args[]) throws Exception {
   final ByteArrayOutputStream out = new ByteArrayOutputStream();
   float sampleRate = 8000;
   int sampleSizeInBits = 8;
   int channels = 1;
   boolean signed = true;
   boolean bigEndian = true;
   final AudioFormat format = new AudioFormat(sampleRate, sampleSizeInBits, channels, signed,
       bigEndian);
   DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
   final TargetDataLine line = (TargetDataLine) AudioSystem.getLine(info);
   line.open(format);
   line.start();
   Runnable runner = new Runnable() {
     int bufferSize = (int) format.getSampleRate() * format.getFrameSize();
     byte buffer[] = new byte[bufferSize];
     public void run() {
       try {
         int count = line.read(buffer, 0, buffer.length);
         if (count > 0) {
           out.write(buffer, 0, count);
         }
         out.close();
       } catch (IOException e) {
         System.err.println("I/O problems: " + e);
         System.exit(-1);
       }
     }
   };
   Thread captureThread = new Thread(runner);
   captureThread.start();
   byte audio[] = out.toByteArray();
   InputStream input = new ByteArrayInputStream(audio);
   final SourceDataLine line1 = (SourceDataLine) AudioSystem.getLine(info);
   final AudioInputStream ais = new AudioInputStream(input, format, audio.length
       / format.getFrameSize());
   line1.open(format);
   line1.start();
   runner = new Runnable() {
     int bufferSize = (int) format.getSampleRate() * format.getFrameSize();
     byte buffer[] = new byte[bufferSize];
     public void run() {
       try {
         int count;
         while ((count = ais.read(buffer, 0, buffer.length)) != -1) {
           if (count > 0) {
             line1.write(buffer, 0, count);
           }
         }
         line1.drain();
         line1.close();
       } catch (IOException e) {
         System.err.println("I/O problems: " + e);
         System.exit(-3);
       }
     }
   };
   Thread playThread = new Thread(runner);
   playThread.start();
 }

}

 </source>
   
  
 
  



Continuously Playing a Sampled Audio File

   <source lang="java">

import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; import javax.sound.sampled.DataLine; public class Main {

 public static void main(String[] argv) throws Exception {
   DataLine.Info info = null;
   Clip clip = (Clip) AudioSystem.getLine(info);
   clip.start();
   clip.loop(Clip.LOOP_CONTINUOUSLY);
   int numberOfPlays = 3;
   clip.loop(numberOfPlays - 1);
 }

}

 </source>
   
  
 
  



Determine the duration of a Midi audio file

   <source lang="java">

import java.io.File; import java.net.URL; import javax.sound.midi.MidiSystem; import javax.sound.midi.Sequence; import javax.sound.midi.Sequencer; public class Main {

 public static void main(String[] argv) throws Exception {
   Sequence sequence = MidiSystem.getSequence(new File("midiaudiofile"));
   sequence = MidiSystem.getSequence(new URL("http://hostname/midiaudiofile"));
   // Create a sequencer for the sequence
   Sequencer sequencer = MidiSystem.getSequencer();
   sequencer.open();
   sequencer.setSequence(sequence);
   double durationInSecs = sequencer.getMicrosecondLength() / 1000000.0;
 }

}

 </source>
   
  
 
  



Determining the Duration of a Midi Audio File

   <source lang="java">

import javax.sound.midi.MidiSystem; import javax.sound.midi.Sequencer; public class Main {

 public static void main(String[] argv) throws Exception {
   Sequencer sequencer = MidiSystem.getSequencer();
   sequencer.open();
   double durationInSecs = sequencer.getMicrosecondLength() / 1000000.0;
 }

}

 </source>
   
  
 
  



Determining the Duration of a Sampled Audio File

   <source lang="java">

import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; import javax.sound.sampled.DataLine; public class Main {

 public static void main(String[] argv) throws Exception {
   DataLine.Info info = null;
   Clip clip = (Clip) AudioSystem.getLine(info);
   double durationInSecs = clip.getBufferSize()
       / (clip.getFormat().getFrameSize() * clip.getFormat().getFrameRate());
 }

}

 </source>
   
  
 
  



Determining the Encoding of a Sampled Audio File

   <source lang="java">

import java.io.File; import java.net.URL; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; public class Main {

 public static void main(String[] argv) throws Exception {
   AudioInputStream stream = AudioSystem.getAudioInputStream(new File(
       "audiofile"));
 }

}

 </source>
   
  
 
  



Determining the File Format of a Midi Audio File

   <source lang="java">

import java.io.File; import java.net.URL; import javax.sound.midi.MidiFileFormat; import javax.sound.midi.MidiSystem; public class Main {

 public static void main(String[] argv) throws Exception {
   // From file
   MidiFileFormat fformat = MidiSystem.getMidiFileFormat(new File("midifile"));
   // From URL
//   fformat = MidiSystem.getMidiFileFormat(new URL("http://hostname/midifile"));
   // Get file format
   switch (fformat.getType()) {
   case 0:
     // mid
     break;
   case 1:
     // rmf
     break;
   }
 }

}

 </source>
   
  
 
  



Determining the File Format of a Sampled Audio File

   <source lang="java">

import java.io.File; import java.net.URL; import javax.sound.sampled.AudioFileFormat; import javax.sound.sampled.AudioSystem; public class Main {

 public static void main(String[] argv) throws Exception {
   AudioFileFormat fformat = AudioSystem.getAudioFileFormat(new File(
       "audiofile"));
   fformat = AudioSystem.getAudioFileFormat(new URL(
       "http://hostname/audiofile"));
   if (fformat.getType() == AudioFileFormat.Type.AIFC) {
   } else if (fformat.getType() == AudioFileFormat.Type.AIFF) {
   } else if (fformat.getType() == AudioFileFormat.Type.AU) {
   } else if (fformat.getType() == AudioFileFormat.Type.WAVE) {
   }
 }

}

 </source>
   
  
 
  



Determining the Position of a Midi Sequencer

   <source lang="java">

import javax.sound.midi.MidiSystem; import javax.sound.midi.Sequencer; public class Main {

 public static void main(String[] argv) throws Exception {
   Sequencer sequencer = MidiSystem.getSequencer();
   sequencer.open();
   double seconds = sequencer.getMicrosecondPosition() / 1000000.0;
 }

}

 </source>
   
  
 
  



Determining the Position of a Sampled Audio Player

   <source lang="java">

import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; import javax.sound.sampled.DataLine; public class Main {

 public static void main(String[] argv) throws Exception {
   DataLine.Info info = null;
   Clip clip = (Clip) AudioSystem.getLine(info);
   double timeInSeconds = clip.getMicrosecondPosition() / 1000000.0d;
 }

}

 </source>
   
  
 
  



Determining When a Midi Audio Player Has Finished Playing

   <source lang="java">

import javax.sound.midi.MetaEventListener; import javax.sound.midi.MetaMessage; import javax.sound.midi.MidiSystem; import javax.sound.midi.Sequencer; public class Main {

 public static void main(String[] argv) throws Exception {
   Sequencer sequencer = MidiSystem.getSequencer();
   sequencer.open();
   sequencer.addMetaEventListener(new MetaEventListener() {
     public void meta(MetaMessage event) {
       if (event.getType() == 47) {
         // Sequencer is done playing
       }
     }
   });
 }

}

 </source>
   
  
 
  



Determining When a Sampled Audio Player Has Finished Playing

   <source lang="java">

import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; import javax.sound.sampled.DataLine; import javax.sound.sampled.LineEvent; import javax.sound.sampled.LineListener; public class Main {

 public static void main(String[] argv) throws Exception {
   DataLine.Info info = null;
   Clip clip = (Clip) AudioSystem.getLine(info);
   clip.addLineListener(new LineListener() {
     public void update(LineEvent evt) {
       if (evt.getType() == LineEvent.Type.STOP) {
       }
     }
   });
 }

}

 </source>
   
  
 
  



Duke Speaks

Duke Speaks Test

Float Control Component

   <source lang="java">


import javax.sound.sampled.FloatControl; public class Main {

 FloatControl control;
 public Main(FloatControl c) {
   control = c;
   control.setValue(3);
 }

}

 </source>
   
  
 
  



Load and play Midi audio

   <source lang="java">

import java.io.File; import javax.sound.midi.MidiSystem; import javax.sound.midi.Sequence; import javax.sound.midi.Sequencer; public class Main {

 public static void main(String[] argv) throws Exception {
   // From file
   Sequence sequence = MidiSystem.getSequence(new File("midiaudiofile"));
   // From URL
   // sequence = MidiSystem.getSequence(new
   // URL("http://hostname/midiaudiofile"));
   // Create a sequencer for the sequence
   Sequencer sequencer = MidiSystem.getSequencer();
   sequencer.open();
   sequencer.setSequence(sequence);
   // Start playing
   sequencer.start();
 }

}

 </source>
   
  
 
  



Load audio file From URL

   <source lang="java">

import java.io.File; import java.net.URL; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem;

   AudioSystem stream = AudioSystem.getAudioInputStream(new URL(
       "http://hostname/audiofile"));
   AudioFormat format = stream.getFormat();
   if (format.getEncoding() == AudioFormat.Encoding.ULAW) {
   } else if (format.getEncoding() == AudioFormat.Encoding.ULAW) {
   }
 }

}

 </source>
   
  
 
  



Load image and sound from Jar file

   <source lang="java">

import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.net.URL; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; import javax.sound.sampled.Line; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; public class Main extends JFrame {

 JButton button;
 ImageIcon buttonIcon;
 Clip buhClip;
 public Main() throws Exception {
   URL imageURL = getClass().getClassLoader().getResource("images/k.jpeg");
   buttonIcon = new ImageIcon(imageURL);
   button = new JButton("Click to Buh!", buttonIcon);
   button.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
       if (buhClip != null) {
         buhClip.setFramePosition(0);
         buhClip.start();
       } else
         System.out.println("Couldn"t load sound");
     }
   });
   getContentPane().add(button);
   URL soundURL = getClass().getClassLoader().getResource("sounds/b.aiff");
   Line.Info linfo = new Line.Info(Clip.class);
   Line line = AudioSystem.getLine(linfo);
   buhClip = (Clip) line;
   AudioInputStream ais = AudioSystem.getAudioInputStream(soundURL);
   buhClip.open(ais);
 }
 public static final void main(String[] args) throws Exception {
   JFrame frame = new Main();
   frame.pack();
   frame.setVisible(true);
 }

}

 </source>
   
  
 
  



Loading and Playing Midi Audio

   <source lang="java">

import java.io.File; import java.net.URL; import javax.sound.midi.MidiSystem; import javax.sound.midi.Sequence; import javax.sound.midi.Sequencer; public class Main {

 public static void main(String[] argv) throws Exception {
   Sequence sequence = MidiSystem.getSequence(new File("midifile"));
   // From URL
   sequence = MidiSystem.getSequence(new URL("http://hostname/midifile"));
   // Create a sequencer for the sequence
   Sequencer sequencer = MidiSystem.getSequencer();
   sequencer.open();
   sequencer.setSequence(sequence);
   // Start playing
   sequencer.start();
 }

}

 </source>
   
  
 
  



Loading and Playing Sampled Audio

   <source lang="java">

import java.io.File; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; import javax.sound.sampled.DataLine; public class Main {

 public static void main(String[] argv) throws Exception {
   AudioInputStream stream = AudioSystem.getAudioInputStream(new File(
       "audiofile"));
   // From URL
   // stream = AudioSystem.getAudioInputStream(new URL(
   // "http://hostname/audiofile"));
   AudioFormat format = stream.getFormat();
   if (format.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) {
     format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, format
         .getSampleRate(), format.getSampleSizeInBits() * 2, format
         .getChannels(), format.getFrameSize() * 2, format.getFrameRate(),
         true); // big endian
     stream = AudioSystem.getAudioInputStream(format, stream);
   }
   DataLine.Info info = new DataLine.Info(Clip.class, stream.getFormat(),
       ((int) stream.getFrameLength() * format.getFrameSize()));
   Clip clip = (Clip) AudioSystem.getLine(info);
   clip.open(stream);
   clip.start();
 }

}

 </source>
   
  
 
  



Make your own Java Media Player to play media files

   <source lang="java">

import java.awt.*; import java.awt.event.*; import java.io.*; import javax.swing.*; import javax.media.*; public class MediaPlayerDemo extends JFrame {

 public static void main(String args[]) {
   Player player;
   File file = new File("yourFile");
   player = Manager.createPlayer(file.toURI().toURL());

// player.addControllerListener(new EventHandler());

   player.start(); // start player
   
   player.close();
   Component visual = player.getVisualComponent();
   Component control = player.getControlPanelComponent();
 }

}

 </source>
   
  
 
  



Play an audio file from a JAR file

   <source lang="java">

import java.io.InputStream; import sun.audio.AudioPlayer; import sun.audio.AudioStream; public class Main {

 public static void main(String args[]) throws Throwable {
   InputStream in = Main.class.getResourceAsStream(args[0]);
   AudioStream as = new AudioStream(in);
   AudioPlayer.player.start(as);
   Thread.sleep(5000);
 }

}

 </source>
   
  
 
  



Play a streaming Midi audio

   <source lang="java">

import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.net.URL; import javax.sound.midi.MidiSystem; import javax.sound.midi.Sequencer; public class Main {

 public static void main(String[] argv) throws Exception {
   Sequencer sequencer = MidiSystem.getSequencer();
   sequencer.open();
   // From file
   InputStream input = new BufferedInputStream(new FileInputStream(new File("midiaudiofile")));
   // From URL
   input = new BufferedInputStream(new URL("http://hostname/rmffile").openStream());
   sequencer.setSequence(input);
   // Start playing
   sequencer.start();
 }

}

 </source>
   
  
 
  



Playing Streaming Midi Audio

   <source lang="java">

import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.net.URL; import javax.sound.midi.MidiSystem; import javax.sound.midi.Sequencer; public class Main {

 public static void main(String[] argv) throws Exception {
   Sequencer sequencer = MidiSystem.getSequencer();
   sequencer.open();
   // From file
   InputStream is = new BufferedInputStream(new FileInputStream(new File(
       "midifile")));
   // From URL

// is = new BufferedInputStream(new URL("http://hostname/rmffile")

 //      .openStream());
   sequencer.setSequence(is);
   // Start playing
   sequencer.start();
 }

}

 </source>
   
  
 
  



Playing Streaming Sampled Audio

   <source lang="java">

import java.io.File; import java.net.URL; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine; import javax.sound.sampled.SourceDataLine; public class Main {

 public static void main(String[] argv) throws Exception {
   AudioInputStream stream = AudioSystem.getAudioInputStream(new File(
       "audiofile"));

// stream = AudioSystem.getAudioInputStream(new URL(

 //      "http://hostname/audiofile"));
   AudioFormat format = stream.getFormat();
   if (format.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) {
     format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, format
         .getSampleRate(), format.getSampleSizeInBits() * 2, format
         .getChannels(), format.getFrameSize() * 2, format.getFrameRate(),
         true); // big endian
     stream = AudioSystem.getAudioInputStream(format, stream);
   }
   SourceDataLine.Info info = new DataLine.Info(SourceDataLine.class, stream
       .getFormat(), ((int) stream.getFrameLength() * format.getFrameSize()));
   SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
   line.open(stream.getFormat());
   line.start();
   int numRead = 0;
   byte[] buf = new byte[line.getBufferSize()];
   while ((numRead = stream.read(buf, 0, buf.length)) >= 0) {
     int offset = 0;
     while (offset < numRead) {
       offset += line.write(buf, offset, numRead - offset);
     }
   }
   line.drain();
   line.stop();
 }

}

 </source>
   
  
 
  



Play sound

   <source lang="java">

import java.applet.Applet; import java.applet.AudioClip; public class NoisyButton {

 public static void main(String[] args) throws Exception {
   java.io.File file = new java.io.File("bark.aiff");
   AudioClip sound = Applet.newAudioClip(file.toURL());
   sound.play();
 }

}


 </source>
   
  
 
  



Setting the Volume of a Sampled Audio Player

   <source lang="java">

import javax.sound.sampled.AudioSystem; import javax.sound.sampled.BooleanControl; import javax.sound.sampled.Clip; import javax.sound.sampled.DataLine; import javax.sound.sampled.FloatControl; public class Main {

 public static void main(String[] argv) throws Exception {
   DataLine.Info info = null;
   Clip clip = (Clip) AudioSystem.getLine(info);
   FloatControl gainControl = (FloatControl) clip
       .getControl(FloatControl.Type.MASTER_GAIN);
   double gain = .5D; // number between 0 and 1 (loudest)
   float dB = (float) (Math.log(gain) / Math.log(10.0) * 20.0);
   gainControl.setValue(dB);
   BooleanControl muteControl = (BooleanControl) clip
       .getControl(BooleanControl.Type.MUTE);
   muteControl.setValue(true);
   muteControl.setValue(false);
 }

}

 </source>
   
  
 
  



Setting the Volume of Playing Midi Audio

   <source lang="java">

import javax.sound.midi.MidiChannel; import javax.sound.midi.MidiSystem; import javax.sound.midi.Sequencer; import javax.sound.midi.Synthesizer; public class Main {

 public static void main(String[] argv) throws Exception {
   Sequencer sequencer = MidiSystem.getSequencer();
   sequencer.open();
   if (sequencer instanceof Synthesizer) {
     Synthesizer synthesizer = (Synthesizer) sequencer;
     MidiChannel[] channels = synthesizer.getChannels();
     // gain is a value between 0 and 1 (loudest)
     double gain = 0.9D;
     for (int i = 0; i < channels.length; i++) {
       channels[i].controlChange(7, (int) (gain * 127.0));
     }
   }
 }

}

 </source>
   
  
 
  



Simple program to try out the new Sound stuff in JDK1.2

   <source lang="java">

/*

* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
* All rights reserved. Software written by Ian F. Darwin and others.
* $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS""
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* 
* Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
* cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
* pioneering role in inventing and promulgating (and standardizing) the Java 
* language and environment is gratefully acknowledged.
* 
* The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
* inventing predecessor languages C and C++ is also gratefully acknowledged.
*/

import java.applet.Applet; import java.net.URL; /**

* Simple program to try out the "new Sound" stuff in JDK1.2 -- allows
* Applications, not just Applets, to play Sound.
*/

public class SoundPlay {

 static String defSounds[] = { "file:///javasrc/graphics/test.wav",
     "file:///music/midi/Beet5th.mid", };
 public static void main(String[] av) {
   if (av.length == 0)
     main(defSounds);
   else
     for (int i = 0; i < av.length; i++) {
       System.out.println("Starting " + av[i]);
       try {
         URL snd = new URL(av[i]);
         // open to see if works or throws exception, close to free
         // fd"s
         // snd.openConnection().getInputStream().close();
         Applet.newAudioClip(snd).play();
       } catch (Exception e) {
         System.err.println(e);
       }
     }
   // With this call, program exits before/during play.
   // Without it, on some versions, program hangs forever after play.
   // System.exit(0);
 }

}


 </source>
   
  
 
  



Sound Applet

   <source lang="java">

/* From http://java.sun.ru/docs/books/tutorial/index.html */ /*

* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* -Redistribution of source code must retain the above copyright notice, this
*  list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduce the above copyright notice,
*  this list of conditions and the following disclaimer in the documentation
*  and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed, licensed or intended
* for use in the design, construction, operation or maintenance of any
* nuclear facility.
*/

import java.applet.AudioClip; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.net.URL; import javax.swing.JApplet; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JPanel; public class SoundApplet extends JApplet implements ActionListener,

   ItemListener {
 AppletSoundList soundList;
 String auFile = "spacemusic.au";
 String aiffFile = "flute+hrn+mrmba.aif";
 String midiFile = "trippygaia1.mid";
 String rmfFile = "jungle.rmf";
 String wavFile = "bottle-open.wav";
 String chosenFile;
 AudioClip onceClip, loopClip;
 JComboBox formats;
 JButton playButton, loopButton, stopButton;
 boolean looping = false;
 public void init() {
   String[] fileTypes = { auFile, aiffFile, midiFile, rmfFile, wavFile };
   formats = new JComboBox(fileTypes);
   formats.setSelectedIndex(0);
   chosenFile = (String) formats.getSelectedItem();
   formats.addItemListener(this);
   playButton = new JButton("Play");
   playButton.addActionListener(this);
   loopButton = new JButton("Loop");
   loopButton.addActionListener(this);
   stopButton = new JButton("Stop");
   stopButton.addActionListener(this);
   stopButton.setEnabled(false);
   JPanel controlPanel = new JPanel();
   controlPanel.add(formats);
   controlPanel.add(playButton);
   controlPanel.add(loopButton);
   controlPanel.add(stopButton);
   getContentPane().add(controlPanel);
   startLoadingSounds();
 }
 public void itemStateChanged(ItemEvent e) {
   chosenFile = (String) formats.getSelectedItem();
   soundList.startLoading(chosenFile);
 }
 void startLoadingSounds() {
   //Start asynchronous sound loading.
   soundList = new AppletSoundList(this, getCodeBase());
   soundList.startLoading(auFile);
   soundList.startLoading(aiffFile);
   soundList.startLoading(midiFile);
   soundList.startLoading(rmfFile);
   soundList.startLoading(wavFile);
 }
 public void stop() {
   onceClip.stop(); //Cut short the one-time sound.
   if (looping) {
     loopClip.stop(); //Stop the sound loop.
   }
 }
 public void start() {
   if (looping) {
     loopClip.loop(); //Restart the sound loop.
   }
 }
 public void actionPerformed(ActionEvent event) {
   //PLAY BUTTON
   Object source = event.getSource();
   if (source == playButton) {
     //Try to get the AudioClip.
     onceClip = soundList.getClip(chosenFile);
     onceClip.play(); //Play it once.
     stopButton.setEnabled(true);
     showStatus("Playing sound " + chosenFile + ".");
     if (onceClip == null) {
       showStatus("Sound " + chosenFile + " not loaded yet.");
     }
     return;
   }
   //START LOOP BUTTON
   if (source == loopButton) {
     loopClip = soundList.getClip(chosenFile);
     looping = true;
     loopClip.loop(); //Start the sound loop.
     loopButton.setEnabled(false); //Disable loop button.
     stopButton.setEnabled(true);
     showStatus("Playing sound " + chosenFile + " continuously.");
     if (loopClip == null) {
       showStatus("Sound " + chosenFile + " not loaded yet.");
     }
     return;
   }
   //STOP LOOP BUTTON
   if (source == stopButton) {
     if (looping) {
       looping = false;
       loopClip.stop(); //Stop the sound loop.
       loopButton.setEnabled(true); //Enable start button.
     } else if (onceClip != null) {
       onceClip.stop();
     }
     stopButton.setEnabled(false);
     showStatus("Stopped playing " + chosenFile + ".");
     return;
   }
 }

} //Loads and holds a bunch of audio files whose locations are specified //relative to a fixed base URL. class AppletSoundList extends java.util.Hashtable {

 JApplet applet;
 URL baseURL;
 public AppletSoundList(JApplet applet, URL baseURL) {
   super(5); //Initialize Hashtable with capacity of 5 entries.
   this.applet = applet;
   this.baseURL = baseURL;
 }
 public void startLoading(String relativeURL) {
   new AppletSoundLoader(applet, this, baseURL, relativeURL);
 }
 public AudioClip getClip(String relativeURL) {
   return (AudioClip) get(relativeURL);
 }
 public void putClip(AudioClip clip, String relativeURL) {
   put(relativeURL, clip);
 }

} class AppletSoundLoader extends Thread {

 JApplet applet;
 AppletSoundList soundList;
 URL baseURL;
 String relativeURL;
 public AppletSoundLoader(JApplet applet, AppletSoundList soundList,
     URL baseURL, String relativeURL) {
   this.applet = applet;
   this.soundList = soundList;
   this.baseURL = baseURL;
   this.relativeURL = relativeURL;
   setPriority(MIN_PRIORITY);
   start();
 }
 public void run() {
   AudioClip audioClip = applet.getAudioClip(baseURL, relativeURL);
   soundList.putClip(audioClip, relativeURL);
 }

}


 </source>
   
  
 
  



Sound Application

   <source lang="java">

/* From http://java.sun.ru/docs/books/tutorial/index.html */ /*

* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* -Redistribution of source code must retain the above copyright notice, this
*  list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduce the above copyright notice,
*  this list of conditions and the following disclaimer in the documentation
*  and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed, licensed or intended
* for use in the design, construction, operation or maintenance of any
* nuclear facility.
*/

import java.applet.Applet; import java.applet.AudioClip; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.net.MalformedURLException; import java.net.URL; import javax.swing.JApplet; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class SoundApplication extends JPanel implements ActionListener,

   ItemListener {
 SoundList soundList;
 String auFile = "spacemusic.au";
 String aiffFile = "flute+hrn+mrmba.aif";
 String midiFile = "trippygaia1.mid";
 String rmfFile = "jungle.rmf";
 String wavFile = "bottle-open.wav";
 String chosenFile;
 AudioClip onceClip, loopClip;
 URL codeBase;
 JComboBox formats;
 JButton playButton, loopButton, stopButton;
 JLabel status;
 boolean looping = false;
 public SoundApplication() {
   String[] fileTypes = { auFile, aiffFile, midiFile, rmfFile, wavFile };
   formats = new JComboBox(fileTypes);
   formats.setSelectedIndex(0);
   chosenFile = (String) formats.getSelectedItem();
   formats.addItemListener(this);
   playButton = new JButton("Play");
   playButton.addActionListener(this);
   loopButton = new JButton("Loop");
   loopButton.addActionListener(this);
   stopButton = new JButton("Stop");
   stopButton.addActionListener(this);
   stopButton.setEnabled(false);
   status = new JLabel(
       "Click Play or Loop to play the selected sound file.");
   JPanel controlPanel = new JPanel();
   controlPanel.add(formats);
   controlPanel.add(playButton);
   controlPanel.add(loopButton);
   controlPanel.add(stopButton);
   JPanel statusPanel = new JPanel();
   statusPanel.add(status);
   add(controlPanel);
   add(statusPanel);
   startLoadingSounds();
 }
 public void itemStateChanged(ItemEvent e) {
   chosenFile = (String) formats.getSelectedItem();
   soundList.startLoading(chosenFile);
 }
 void startLoadingSounds() {
   //Start asynchronous sound loading.
   try {
     codeBase = new URL("file:" + System.getProperty("user.dir") + "/");
   } catch (MalformedURLException e) {
     System.err.println(e.getMessage());
   }
   soundList = new SoundList(codeBase);
   soundList.startLoading(auFile);
   soundList.startLoading(aiffFile);
   soundList.startLoading(midiFile);
   soundList.startLoading(rmfFile);
   soundList.startLoading(wavFile);
 }
 public void stop() {
   onceClip.stop(); //Cut short the one-time sound.
   if (looping) {
     loopClip.stop(); //Stop the sound loop.
   }
 }
 public void start() {
   if (looping) {
     loopClip.loop(); //Restart the sound loop.
   }
 }
 public void actionPerformed(ActionEvent event) {
   //PLAY BUTTON
   Object source = event.getSource();
   if (source == playButton) {
     //Try to get the AudioClip.
     onceClip = soundList.getClip(chosenFile);
     stopButton.setEnabled(true);
     onceClip.play(); //Play it once.
     status.setText("Playing sound " + chosenFile + ".");
     if (onceClip == null) {
       status.setText("Sound " + chosenFile + " not loaded yet.");
     }
     return;
   }
   //START LOOP BUTTON
   if (source == loopButton) {
     loopClip = soundList.getClip(chosenFile);
     looping = true;
     loopClip.loop(); //Start the sound loop.
     loopButton.setEnabled(false); //Disable start button.
     stopButton.setEnabled(true);
     status.setText("Playing sound " + chosenFile + " continuously.");
     if (loopClip == null) {
       status.setText("Sound " + chosenFile + " not loaded yet.");
     }
     return;
   }
   //STOP LOOP BUTTON
   if (source == stopButton) {
     if (looping) {
       looping = false;
       loopClip.stop(); //Stop the sound loop.
       loopButton.setEnabled(true); //Enable start button.
     } else if (onceClip != null) {
       onceClip.stop();
     }
     stopButton.setEnabled(false);
     status.setText("Stopped playing " + chosenFile + ".");
     return;
   }
 }
 public static void main(String s[]) {
   WindowListener l = new WindowAdapter() {
     public void windowClosing(WindowEvent e) {
       System.exit(0);
     }
   };
   JFrame f = new JFrame("SoundApplication");
   f.addWindowListener(l);
   f.getContentPane().add(new SoundApplication());
   f.setSize(new Dimension(400, 100));
   f.show();
 }

} /**

* Loads and holds a bunch of audio files whose locations are specified relative
* to a fixed base URL.
*/

class SoundList extends java.util.Hashtable {

 JApplet applet;
 URL baseURL;
 public SoundList(URL baseURL) {
   super(5); //Initialize Hashtable with capacity of 5 entries.
   this.baseURL = baseURL;
 }
 public void startLoading(String relativeURL) {
   new SoundLoader(this, baseURL, relativeURL);
 }
 public AudioClip getClip(String relativeURL) {
   return (AudioClip) get(relativeURL);
 }
 public void putClip(AudioClip clip, String relativeURL) {
   put(relativeURL, clip);
 }

} class SoundLoader extends Thread {

 SoundList soundList;
 URL completeURL;
 String relativeURL;
 public SoundLoader(SoundList soundList, URL baseURL, String relativeURL) {
   this.soundList = soundList;
   try {
     completeURL = new URL(baseURL, relativeURL);
   } catch (MalformedURLException e) {
     System.err.println(e.getMessage());
   }
   this.relativeURL = relativeURL;
   setPriority(MIN_PRIORITY);
   start();
 }
 public void run() {
   AudioClip audioClip = Applet.newAudioClip(completeURL);
   soundList.putClip(audioClip, relativeURL);
 }

}


 </source>
   
  
 
  



Sound Manager Test

   <source lang="java">

      /*

DEVELOPING GAME IN JAVA Caracteristiques Editeur : NEW RIDERS Auteur : BRACKEEN Parution : 09 2003 Pages : 972 Isbn : 1-59273-005-1 Reliure : Paperback Disponibilite : Disponible a la librairie

  • /

import java.awt.Color; import java.awt.Container; import java.awt.DisplayMode; import java.awt.EventQueue; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Image; import java.awt.Toolkit; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferStrategy; import java.awt.image.BufferedImage; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.FileInputStream; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.util.LinkedList; import javax.sound.midi.InvalidMidiDataException; import javax.sound.midi.MetaEventListener; import javax.sound.midi.MetaMessage; import javax.sound.midi.MidiSystem; import javax.sound.midi.MidiUnavailableException; import javax.sound.midi.Sequence; import javax.sound.midi.Sequencer; 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.Mixer; import javax.sound.sampled.SourceDataLine; import javax.sound.sampled.UnsupportedAudioFileException; import javax.swing.AbstractButton; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JToggleButton; import javax.swing.RepaintManager; /**

* The SoundManagerTest demonstrates the functionality of the SoundManager
* class. It provides the following demos:
*
    *
  • Playing a Midi sequence. *
  • Toggle a track of a playing Midi sequence. *
  • Playing a sound. *
  • Playing a Sound with an Echo filter. *
  • Looping a sound. *
  • Playing the maximum number of sounds at once. *
  • Pausing all sounds. *
* <p>
* This class wasn"t listed in the book ;)
* 
* @see SoundManager
* @see Sound
* @see SoundFilter
*/

public class SoundManagerTest extends GameCore implements ActionListener {

 public static void main(String[] args) {
   new SoundManagerTest().run();
 }
 // uncompressed, 44100Hz, 16-bit, mono, signed, little-endian
 private static final AudioFormat PLAYBACK_FORMAT = new AudioFormat(44100,
     16, 1, true, false);
 private static final int MANY_SOUNDS_COUNT = SoundManager
     .getMaxSimultaneousSounds(PLAYBACK_FORMAT);
 private static final int DRUM_TRACK = 1;
 private static final String EXIT = "Exit";
 private static final String PAUSE = "Pause";
 private static final String PLAY_MUSIC = "Play Music";
 private static final String MUSIC_DRUMS = "Toggle Drums";
 private static final String PLAY_SOUND = "Play Sound";
 private static final String PLAY_ECHO_SOUND = "Play Echoed Sound";
 private static final String PLAY_LOOPING_SOUND = "Play Looping Sound";
 private static final String PLAY_MANY_SOUNDS = "Play " + MANY_SOUNDS_COUNT
     + " Sounds";
 private SoundManager soundManager;
 private MidiPlayer midiPlayer;
 private Sequence music;
 private Sound boop;
 private Sound bzz;
 private InputStream lastloopingSound;
 public void init() {
   super.init();
   initSounds();
   initUI();
 }
 /**
  * Loads sounds and music.
  */
 public void initSounds() {
   midiPlayer = new MidiPlayer();
   soundManager = new SoundManager(PLAYBACK_FORMAT);
   music = midiPlayer.getSequence("../sounds/music.midi");
   boop = soundManager.getSound("../sounds/boop.wav");
   bzz = soundManager.getSound("../sounds/fly-bzz.wav");
 }
 /**
  * Creates the UI, which is a row of buttons.
  */
 public void initUI() {
   // make sure Swing components don"t paint themselves
   NullRepaintManager.install();
   JFrame frame = super.screen.getFullScreenWindow();
   Container contentPane = frame.getContentPane();
   contentPane.setLayout(new FlowLayout());
   contentPane.add(createButton(PAUSE, true));
   contentPane.add(createButton(PLAY_MUSIC, true));
   contentPane.add(createButton(MUSIC_DRUMS, false));
   contentPane.add(createButton(PLAY_SOUND, false));
   contentPane.add(createButton(PLAY_ECHO_SOUND, false));
   contentPane.add(createButton(PLAY_LOOPING_SOUND, true));
   contentPane.add(createButton(PLAY_MANY_SOUNDS, false));
   contentPane.add(createButton(EXIT, false));
   // explicitly layout components (needed on some systems)
   frame.validate();
 }
 /**
  * Draws all Swing components
  */
 public void draw(Graphics2D g) {
   JFrame frame = super.screen.getFullScreenWindow();
   frame.getLayeredPane().paintComponents(g);
 }
 /**
  * Creates a button (either JButton or JToggleButton).
  */
 public AbstractButton createButton(String name, boolean canToggle) {
   AbstractButton button;
   if (canToggle) {
     button = new JToggleButton(name);
   } else {
     button = new JButton(name);
   }
   button.addActionListener(this);
   button.setIgnoreRepaint(true);
   button.setFocusable(false);
   return button;
 }
 /**
  * Performs actions when a button is pressed.
  */
 public void actionPerformed(ActionEvent e) {
   String command = e.getActionCommand();
   AbstractButton button = (AbstractButton) e.getSource();
   if (command == EXIT) {
     midiPlayer.close();
     soundManager.close();
     stop();
   } else if (command == PAUSE) {
     // pause the sound
     soundManager.setPaused(button.isSelected());
     midiPlayer.setPaused(button.isSelected());
   } else if (command == PLAY_MUSIC) {
     // toggle music on or off
     if (button.isSelected()) {
       midiPlayer.play(music, true);
     } else {
       midiPlayer.stop();
     }
   } else if (command == MUSIC_DRUMS) {
     // toggle drums on or off
     Sequencer sequencer = midiPlayer.getSequencer();
     if (sequencer != null) {
       boolean mute = sequencer.getTrackMute(DRUM_TRACK);
       sequencer.setTrackMute(DRUM_TRACK, !mute);
     }
   } else if (command == PLAY_SOUND) {
     // play a normal sound
     soundManager.play(boop);
   } else if (command == PLAY_ECHO_SOUND) {
     // play a sound with an echo
     EchoFilter filter = new EchoFilter(11025, .6f);
     soundManager.play(boop, filter, false);
   } else if (command == PLAY_LOOPING_SOUND) {
     // play or stop the looping sound
     if (button.isSelected()) {
       lastloopingSound = soundManager.play(bzz, null, true);
     } else if (lastloopingSound != null) {
       try {
         lastloopingSound.close();
       } catch (IOException ex) {
       }
       lastloopingSound = null;
     }
   } else if (command == PLAY_MANY_SOUNDS) {
     // play several sounds at once, to test the system
     for (int i = 0; i < MANY_SOUNDS_COUNT; i++) {
       soundManager.play(boop);
     }
   }
 }

} /**

* The SoundManager class manages sound playback. The SoundManager is a
* ThreadPool, with each thread playing back one sound at a time. This allows
* the SoundManager to easily limit the number of simultaneous sounds being
* played.
* <p>
* Possible ideas to extend this class:
*
    *
  • add a setMasterVolume() method, which uses Controls to set the volume * for each line. *
  • don"t play a sound if more than, say, 500ms has passed since the request * to play *
*/

class SoundManager extends ThreadPool {

 private AudioFormat playbackFormat;
 private ThreadLocal localLine;
 private ThreadLocal localBuffer;
 private Object pausedLock;
 private boolean paused;
 /**
  * Creates a new SoundManager using the maximum number of simultaneous
  * sounds.
  */
 public SoundManager(AudioFormat playbackFormat) {
   this(playbackFormat, getMaxSimultaneousSounds(playbackFormat));
 }
 /**
  * Creates a new SoundManager with the specified maximum number of
  * simultaneous sounds.
  */
 public SoundManager(AudioFormat playbackFormat, int maxSimultaneousSounds) {
   super(Math.min(maxSimultaneousSounds,
       getMaxSimultaneousSounds(playbackFormat)));
   this.playbackFormat = playbackFormat;
   localLine = new ThreadLocal();
   localBuffer = new ThreadLocal();
   pausedLock = new Object();
   // notify threads in pool it"s ok to start
   synchronized (this) {
     notifyAll();
   }
 }
 /**
  * Gets the maximum number of simultaneous sounds with the specified
  * AudioFormat that the default mixer can play.
  */
 public static int getMaxSimultaneousSounds(AudioFormat playbackFormat) {
   DataLine.Info lineInfo = new DataLine.Info(SourceDataLine.class,
       playbackFormat);
   Mixer mixer = AudioSystem.getMixer(null);
   return mixer.getMaxLines(lineInfo);
 }
 /**
  * Does any clean up before closing.
  */
 protected void cleanUp() {
   // signal to unpause
   setPaused(false);
   // close the mixer (stops any running sounds)
   Mixer mixer = AudioSystem.getMixer(null);
   if (mixer.isOpen()) {
     mixer.close();
   }
 }
 public void close() {
   cleanUp();
   super.close();
 }
 public void join() {
   cleanUp();
   super.join();
 }
 /**
  * Sets the paused state. Sounds may not pause immediately.
  */
 public void setPaused(boolean paused) {
   if (this.paused != paused) {
     synchronized (pausedLock) {
       this.paused = paused;
       if (!paused) {
         // restart sounds
         pausedLock.notifyAll();
       }
     }
   }
 }
 /**
  * Returns the paused state.
  */
 public boolean isPaused() {
   return paused;
 }
 /**
  * Loads a Sound from the file system. Returns null if an error occurs.
  */
 public Sound getSound(String filename) {
   return getSound(getAudioInputStream(filename));
 }
 /**
  * Loads a Sound from an input stream. Returns null if an error occurs.
  */
 public Sound getSound(InputStream is) {
   return getSound(getAudioInputStream(is));
 }
 /**
  * Loads a Sound from an AudioInputStream.
  */
 public Sound getSound(AudioInputStream audioStream) {
   if (audioStream == null) {
     return null;
   }
   // get the number of bytes to read
   int length = (int) (audioStream.getFrameLength() * audioStream
       .getFormat().getFrameSize());
   // read the entire stream
   byte[] samples = new byte[length];
   DataInputStream is = new DataInputStream(audioStream);
   try {
     is.readFully(samples);
     is.close();
   } catch (IOException ex) {
     ex.printStackTrace();
   }
   // return the samples
   return new Sound(samples);
 }
 /**
  * Creates an AudioInputStream from a sound from the file system.
  */
 public AudioInputStream getAudioInputStream(String filename) {
   try {
     return getAudioInputStream(new FileInputStream(filename));
   } catch (IOException ex) {
     ex.printStackTrace();
     return null;
   }
 }
 /**
  * Creates an AudioInputStream from a sound from an input stream
  */
 public AudioInputStream getAudioInputStream(InputStream is) {
   try {
     if (!is.markSupported()) {
       is = new BufferedInputStream(is);
     }
     // open the source stream
     AudioInputStream source = AudioSystem.getAudioInputStream(is);
     // convert to playback format
     return AudioSystem.getAudioInputStream(playbackFormat, source);
   } catch (UnsupportedAudioFileException ex) {
     ex.printStackTrace();
   } catch (IOException ex) {
     ex.printStackTrace();
   } catch (IllegalArgumentException ex) {
     ex.printStackTrace();
   }
   return null;
 }
 /**
  * Plays a sound. This method returns immediately.
  */
 public InputStream play(Sound sound) {
   return play(sound, null, false);
 }
 /**
  * Plays a sound with an optional SoundFilter, and optionally looping. This
  * method returns immediately.
  */
 public InputStream play(Sound sound, SoundFilter filter, boolean loop) {
   InputStream is;
   if (sound != null) {
     if (loop) {
       is = new LoopingByteInputStream(sound.getSamples());
     } else {
       is = new ByteArrayInputStream(sound.getSamples());
     }
     return play(is, filter);
   }
   return null;
 }
 /**
  * Plays a sound from an InputStream. This method returns immediately.
  */
 public InputStream play(InputStream is) {
   return play(is, null);
 }
 /**
  * Plays a sound from an InputStream with an optional sound filter. This
  * method returns immediately.
  */
 public InputStream play(InputStream is, SoundFilter filter) {
   if (is != null) {
     if (filter != null) {
       is = new FilteredSoundStream(is, filter);
     }
     runTask(new SoundPlayer(is));
   }
   return is;
 }
 /**
  * Signals that a PooledThread has started. Creates the Thread"s line and
  * buffer.
  */
 protected void threadStarted() {
   // wait for the SoundManager constructor to finish
   synchronized (this) {
     try {
       wait();
     } catch (InterruptedException ex) {
     }
   }
   // use a short, 100ms (1/10th sec) buffer for filters that
   // change in real-time
   int bufferSize = playbackFormat.getFrameSize()
       * Math.round(playbackFormat.getSampleRate() / 10);
   // create, open, and start the line
   SourceDataLine line;
   DataLine.Info lineInfo = new DataLine.Info(SourceDataLine.class,
       playbackFormat);
   try {
     line = (SourceDataLine) AudioSystem.getLine(lineInfo);
     line.open(playbackFormat, bufferSize);
   } catch (LineUnavailableException ex) {
     // the line is unavailable - signal to end this thread
     Thread.currentThread().interrupt();
     return;
   }
   line.start();
   // create the buffer
   byte[] buffer = new byte[bufferSize];
   // set this thread"s locals
   localLine.set(line);
   localBuffer.set(buffer);
 }
 /**
  * Signals that a PooledThread has stopped. Drains and closes the Thread"s
  * Line.
  */
 protected void threadStopped() {
   SourceDataLine line = (SourceDataLine) localLine.get();
   if (line != null) {
     line.drain();
     line.close();
   }
 }
 /**
  * The SoundPlayer class is a task for the PooledThreads to run. It receives
  * the threads"s Line and byte buffer from the ThreadLocal variables and
  * plays a sound from an InputStream.
  * <p>
  * This class only works when called from a PooledThread.
  */
 protected class SoundPlayer implements Runnable {
   private InputStream source;
   public SoundPlayer(InputStream source) {
     this.source = source;
   }
   public void run() {
     // get line and buffer from ThreadLocals
     SourceDataLine line = (SourceDataLine) localLine.get();
     byte[] buffer = (byte[]) localBuffer.get();
     if (line == null || buffer == null) {
       // the line is unavailable
       return;
     }
     // copy data to the line
     try {
       int numBytesRead = 0;
       while (numBytesRead != -1) {
         // if paused, wait until unpaused
         synchronized (pausedLock) {
           if (paused) {
             try {
               pausedLock.wait();
             } catch (InterruptedException ex) {
               return;
             }
           }
         }
         // copy data
         numBytesRead = source.read(buffer, 0, buffer.length);
         if (numBytesRead != -1) {
           line.write(buffer, 0, numBytesRead);
         }
       }
     } catch (IOException ex) {
       ex.printStackTrace();
     }
   }
 }

} class MidiPlayer implements MetaEventListener {

 // Midi meta event
 public static final int END_OF_TRACK_MESSAGE = 47;
 private Sequencer sequencer;
 private boolean loop;
 private boolean paused;
 /**
  * Creates a new MidiPlayer object.
  */
 public MidiPlayer() {
   try {
     sequencer = MidiSystem.getSequencer();
     sequencer.open();
     sequencer.addMetaEventListener(this);
   } catch (MidiUnavailableException ex) {
     sequencer = null;
   }
 }
 /**
  * Loads a sequence from the file system. Returns null if an error occurs.
  */
 public Sequence getSequence(String filename) {
   try {
     return getSequence(new FileInputStream(filename));
   } catch (IOException ex) {
     ex.printStackTrace();
     return null;
   }
 }
 /**
  * Loads a sequence from an input stream. Returns null if an error occurs.
  */
 public Sequence getSequence(InputStream is) {
   try {
     if (!is.markSupported()) {
       is = new BufferedInputStream(is);
     }
     Sequence s = MidiSystem.getSequence(is);
     is.close();
     return s;
   } catch (InvalidMidiDataException ex) {
     ex.printStackTrace();
     return null;
   } catch (IOException ex) {
     ex.printStackTrace();
     return null;
   }
 }
 /**
  * Plays a sequence, optionally looping. This method returns immediately.
  * The sequence is not played if it is invalid.
  */
 public void play(Sequence sequence, boolean loop) {
   if (sequencer != null && sequence != null && sequencer.isOpen()) {
     try {
       sequencer.setSequence(sequence);
       sequencer.start();
       this.loop = loop;
     } catch (InvalidMidiDataException ex) {
       ex.printStackTrace();
     }
   }
 }
 /**
  * This method is called by the sound system when a meta event occurs. In
  * this case, when the end-of-track meta event is received, the sequence is
  * restarted if looping is on.
  */
 public void meta(MetaMessage event) {
   if (event.getType() == END_OF_TRACK_MESSAGE) {
     if (sequencer != null && sequencer.isOpen() && loop) {
       sequencer.start();
     }
   }
 }
 /**
  * Stops the sequencer and resets its position to 0.
  */
 public void stop() {
   if (sequencer != null && sequencer.isOpen()) {
     sequencer.stop();
     sequencer.setMicrosecondPosition(0);
   }
 }
 /**
  * Closes the sequencer.
  */
 public void close() {
   if (sequencer != null && sequencer.isOpen()) {
     sequencer.close();
   }
 }
 /**
  * Gets the sequencer.
  */
 public Sequencer getSequencer() {
   return sequencer;
 }
 /**
  * Sets the paused state. Music may not immediately pause.
  */
 public void setPaused(boolean paused) {
   if (this.paused != paused && sequencer != null && sequencer.isOpen()) {
     this.paused = paused;
     if (paused) {
       sequencer.stop();
     } else {
       sequencer.start();
     }
   }
 }
 /**
  * Returns the paused state.
  */
 public boolean isPaused() {
   return paused;
 }

} /**

* Simple abstract class used for testing. Subclasses should implement the
* draw() method.
*/

abstract class GameCore {

 protected static final int FONT_SIZE = 24;
 private static final DisplayMode POSSIBLE_MODES[] = {
     new DisplayMode(800, 600, 32, 0), new DisplayMode(800, 600, 24, 0),
     new DisplayMode(800, 600, 16, 0), new DisplayMode(640, 480, 32, 0),
     new DisplayMode(640, 480, 24, 0), new DisplayMode(640, 480, 16, 0) };
 private boolean isRunning;
 protected ScreenManager screen;
 /**
  * Signals the game loop that it"s time to quit
  */
 public void stop() {
   isRunning = false;
 }
 /**
  * Calls init() and gameLoop()
  */
 public void run() {
   try {
     init();
     gameLoop();
   } finally {
     screen.restoreScreen();
   }
 }
 /**
  * Sets full screen mode and initiates and objects.
  */
 public void init() {
   screen = new ScreenManager();
   DisplayMode displayMode = screen
       .findFirstCompatibleMode(POSSIBLE_MODES);
   screen.setFullScreen(displayMode);
   Window window = screen.getFullScreenWindow();
   window.setFont(new Font("Dialog", Font.PLAIN, FONT_SIZE));
   window.setBackground(Color.blue);
   window.setForeground(Color.white);
   isRunning = true;
 }
 public Image loadImage(String fileName) {
   return new ImageIcon(fileName).getImage();
 }
 /**
  * Runs through the game loop until stop() is called.
  */
 public void gameLoop() {
   long startTime = System.currentTimeMillis();
   long currTime = startTime;
   while (isRunning) {
     long elapsedTime = System.currentTimeMillis() - currTime;
     currTime += elapsedTime;
     // update
     update(elapsedTime);
     // draw the screen
     Graphics2D g = screen.getGraphics();
     draw(g);
     g.dispose();
     screen.update();
     // take a nap
     try {
       Thread.sleep(20);
     } catch (InterruptedException ex) {
     }
   }
 }
 /**
  * Updates the state of the game/animation based on the amount of elapsed
  * time that has passed.
  */
 public void update(long elapsedTime) {
   // do nothing
 }
 /**
  * Draws to the screen. Subclasses must override this method.
  */
 public abstract void draw(Graphics2D g);

} /**

* The NullRepaintManager is a RepaintManager that doesn"t do any repainting.
* Useful when all the rendering is done manually by the application.
*/

class NullRepaintManager extends RepaintManager {

 /**
  * Installs the NullRepaintManager.
  */
 public static void install() {
   RepaintManager repaintManager = new NullRepaintManager();
   repaintManager.setDoubleBufferingEnabled(false);
   RepaintManager.setCurrentManager(repaintManager);
 }
 public void addInvalidComponent(JComponent c) {
   // do nothing
 }
 public void addDirtyRegion(JComponent c, int x, int y, int w, int h) {
   // do nothing
 }
 public void markCompletelyDirty(JComponent c) {
   // do nothing
 }
 public void paintDirtyRegions() {
   // do nothing
 }

} /**

* The ScreenManager class manages initializing and displaying full screen
* graphics modes.
*/

class ScreenManager {

 private GraphicsDevice device;
 /**
  * Creates a new ScreenManager object.
  */
 public ScreenManager() {
   GraphicsEnvironment environment = GraphicsEnvironment
       .getLocalGraphicsEnvironment();
   device = environment.getDefaultScreenDevice();
 }
 /**
  * Returns a list of compatible display modes for the default device on the
  * system.
  */
 public DisplayMode[] getCompatibleDisplayModes() {
   return device.getDisplayModes();
 }
 /**
  * Returns the first compatible mode in a list of modes. Returns null if no
  * modes are compatible.
  */
 public DisplayMode findFirstCompatibleMode(DisplayMode modes[]) {
   DisplayMode goodModes[] = device.getDisplayModes();
   for (int i = 0; i < modes.length; i++) {
     for (int j = 0; j < goodModes.length; j++) {
       if (displayModesMatch(modes[i], goodModes[j])) {
         return modes[i];
       }
     }
   }
   return null;
 }
 /**
  * Returns the current display mode.
  */
 public DisplayMode getCurrentDisplayMode() {
   return device.getDisplayMode();
 }
 /**
  * Determines if two display modes "match". Two display modes match if they
  * have the same resolution, bit depth, and refresh rate. The bit depth is
  * ignored if one of the modes has a bit depth of
  * DisplayMode.BIT_DEPTH_MULTI. Likewise, the refresh rate is ignored if one
  * of the modes has a refresh rate of DisplayMode.REFRESH_RATE_UNKNOWN.
  */
 public boolean displayModesMatch(DisplayMode mode1, DisplayMode mode2)
 {
   if (mode1.getWidth() != mode2.getWidth()
       || mode1.getHeight() != mode2.getHeight()) {
     return false;
   }
   if (mode1.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI
       && mode2.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI
       && mode1.getBitDepth() != mode2.getBitDepth()) {
     return false;
   }
   if (mode1.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN
       && mode2.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN
       && mode1.getRefreshRate() != mode2.getRefreshRate()) {
     return false;
   }
   return true;
 }
 /**
  * Enters full screen mode and changes the display mode. If the specified
  * display mode is null or not compatible with this device, or if the
  * display mode cannot be changed on this system, the current display mode
  * is used.
  * <p>
  * The display uses a BufferStrategy with 2 buffers.
  */
 public void setFullScreen(DisplayMode displayMode) {
   final JFrame frame = new JFrame();
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.setUndecorated(true);
   frame.setIgnoreRepaint(true);
   frame.setResizable(false);
   device.setFullScreenWindow(frame);
   if (displayMode != null && device.isDisplayChangeSupported()) {
     try {
       device.setDisplayMode(displayMode);
     } catch (IllegalArgumentException ex) {
     }
     // fix for mac os x
     frame.setSize(displayMode.getWidth(), displayMode.getHeight());
   }
   // avoid potential deadlock in 1.4.1_02
   try {
     EventQueue.invokeAndWait(new Runnable() {
       public void run() {
         frame.createBufferStrategy(2);
       }
     });
   } catch (InterruptedException ex) {
     // ignore
   } catch (InvocationTargetException ex) {
     // ignore
   }
 }
 /**
  * Gets the graphics context for the display. The ScreenManager uses double
  * buffering, so applications must call update() to show any graphics drawn.
  * <p>
  * The application must dispose of the graphics object.
  */
 public Graphics2D getGraphics() {
   Window window = device.getFullScreenWindow();
   if (window != null) {
     BufferStrategy strategy = window.getBufferStrategy();
     return (Graphics2D) strategy.getDrawGraphics();
   } else {
     return null;
   }
 }
 /**
  * Updates the display.
  */
 public void update() {
   Window window = device.getFullScreenWindow();
   if (window != null) {
     BufferStrategy strategy = window.getBufferStrategy();
     if (!strategy.contentsLost()) {
       strategy.show();
     }
   }
   // Sync the display on some systems.
   // (on Linux, this fixes event queue problems)
   Toolkit.getDefaultToolkit().sync();
 }
 /**
  * Returns the window currently used in full screen mode. Returns null if
  * the device is not in full screen mode.
  */
 public JFrame getFullScreenWindow() {
   return (JFrame) device.getFullScreenWindow();
 }
 /**
  * Returns the width of the window currently used in full screen mode.
  * Returns 0 if the device is not in full screen mode.
  */
 public int getWidth() {
   Window window = device.getFullScreenWindow();
   if (window != null) {
     return window.getWidth();
   } else {
     return 0;
   }
 }
 /**
  * Returns the height of the window currently used in full screen mode.
  * Returns 0 if the device is not in full screen mode.
  */
 public int getHeight() {
   Window window = device.getFullScreenWindow();
   if (window != null) {
     return window.getHeight();
   } else {
     return 0;
   }
 }
 /**
  * Restores the screen"s display mode.
  */
 public void restoreScreen() {
   Window window = device.getFullScreenWindow();
   if (window != null) {
     window.dispose();
   }
   device.setFullScreenWindow(null);
 }
 /**
  * Creates an image compatible with the current display.
  */
 public BufferedImage createCompatibleImage(int w, int h, int transparancy) {
   Window window = device.getFullScreenWindow();
   if (window != null) {
     GraphicsConfiguration gc = window.getGraphicsConfiguration();
     return gc.createCompatibleImage(w, h, transparancy);
   }
   return null;
 }

} /**

* The EchoFilter class is a SoundFilter that emulates an echo.
* 
* @see FilteredSoundStream
*/

class EchoFilter extends SoundFilter {

 private short[] delayBuffer;
 private int delayBufferPos;
 private float decay;
 /**
  * Creates an EchoFilter with the specified number of delay samples and the
  * specified decay rate.
  * <p>
  * The number of delay samples specifies how long before the echo is
  * initially heard. For a 1 second echo with mono, 44100Hz sound, use 44100
  * delay samples.
  * <p>
  * The decay value is how much the echo has decayed from the source. A decay
  * value of .5 means the echo heard is half as loud as the source.
  */
 public EchoFilter(int numDelaySamples, float decay) {
   delayBuffer = new short[numDelaySamples];
   this.decay = decay;
 }
 /**
  * Gets the remaining size, in bytes, of samples that this filter can echo
  * after the sound is done playing. Ensures that the sound will have decayed
  * to below 1% of maximum volume (amplitude).
  */
 public int getRemainingSize() {
   float finalDecay = 0.01f;
   // derived from Math.pow(decay,x) <= finalDecay
   int numRemainingBuffers = (int) Math.ceil(Math.log(finalDecay)
       / Math.log(decay));
   int bufferSize = delayBuffer.length * 2;
   return bufferSize * numRemainingBuffers;
 }
 /**
  * Clears this EchoFilter"s internal delay buffer.
  */
 public void reset() {
   for (int i = 0; i < delayBuffer.length; i++) {
     delayBuffer[i] = 0;
   }
   delayBufferPos = 0;
 }
 /**
  * Filters the sound samples to add an echo. The samples played are added to
  * the sound in the delay buffer multipied by the decay rate. The result is
  * then stored in the delay buffer, so multiple echoes are heard.
  */
 public void filter(byte[] samples, int offset, int length) {
   for (int i = offset; i < offset + length; i += 2) {
     // update the sample
     short oldSample = getSample(samples, i);
     short newSample = (short) (oldSample + decay
         * delayBuffer[delayBufferPos]);
     setSample(samples, i, newSample);
     // update the delay buffer
     delayBuffer[delayBufferPos] = newSample;
     delayBufferPos++;
     if (delayBufferPos == delayBuffer.length) {
       delayBufferPos = 0;
     }
   }
 }

} /**

* A abstract class designed to filter sound samples. Since SoundFilters may use
* internal buffering of samples, a new SoundFilter object should be created for
* every sound played. However, SoundFilters can be reused after they are
* finished by called the reset() method.
* <p>
* Assumes all samples are 16-bit, signed, little-endian format.
* 
* @see FilteredSoundStream
*/

abstract class SoundFilter {

 /**
  * Resets this SoundFilter. Does nothing by default.
  */
 public void reset() {
   // do nothing
 }
 /**
  * Gets the remaining size, in bytes, that this filter plays after the sound
  * is finished. An example would be an echo that plays longer than it"s
  * original sound. This method returns 0 by default.
  */
 public int getRemainingSize() {
   return 0;
 }
 /**
  * Filters an array of samples. Samples should be in 16-bit, signed,
  * little-endian format.
  */
 public void filter(byte[] samples) {
   filter(samples, 0, samples.length);
 }
 /**
  * Filters an array of samples. Samples should be in 16-bit, signed,
  * little-endian format. This method should be implemented by subclasses.
  */
 public abstract void filter(byte[] samples, int offset, int length);
 /**
  * Convenience method for getting a 16-bit sample from a byte array. Samples
  * should be in 16-bit, signed, little-endian format.
  */
 public static short getSample(byte[] buffer, int position) {
   return (short) (((buffer[position + 1] & 0xff) << 8) | (buffer[position] & 0xff));
 }
 /**
  * Convenience method for setting a 16-bit sample in a byte array. Samples
  * should be in 16-bit, signed, little-endian format.
  */
 public static void setSample(byte[] buffer, int position, short sample) {
   buffer[position] = (byte) (sample & 0xff);
   buffer[position + 1] = (byte) ((sample >> 8) & 0xff);
 }

} /**

* A thread pool is a group of a limited number of threads that are used to
* execute tasks.
*/

class ThreadPool extends ThreadGroup {

 private boolean isAlive;
 private LinkedList taskQueue;
 private int threadID;
 private static int threadPoolID;
 /**
  * Creates a new ThreadPool.
  * 
  * @param numThreads
  *            The number of threads in the pool.
  */
 public ThreadPool(int numThreads) {
   super("ThreadPool-" + (threadPoolID++));
   setDaemon(true);
   isAlive = true;
   taskQueue = new LinkedList();
   for (int i = 0; i < numThreads; i++) {
     new PooledThread().start();
   }
 }
 /**
  * Requests a new task to run. This method returns immediately, and the task
  * executes on the next available idle thread in this ThreadPool.
  * <p>
  * Tasks start execution in the order they are received.
  * 
  * @param task
  *            The task to run. If null, no action is taken.
  * @throws IllegalStateException
  *             if this ThreadPool is already closed.
  */
 public synchronized void runTask(Runnable task) {
   if (!isAlive) {
     throw new IllegalStateException();
   }
   if (task != null) {
     taskQueue.add(task);
     notify();
   }
 }
 protected synchronized Runnable getTask() throws InterruptedException {
   while (taskQueue.size() == 0) {
     if (!isAlive) {
       return null;
     }
     wait();
   }
   return (Runnable) taskQueue.removeFirst();
 }
 /**
  * Closes this ThreadPool and returns immediately. All threads are stopped,
  * and any waiting tasks are not executed. Once a ThreadPool is closed, no
  * more tasks can be run on this ThreadPool.
  */
 public synchronized void close() {
   if (isAlive) {
     isAlive = false;
     taskQueue.clear();
     interrupt();
   }
 }
 /**
  * Closes this ThreadPool and waits for all running threads to finish. Any
  * waiting tasks are executed.
  */
 public void join() {
   // notify all waiting threads that this ThreadPool is no
   // longer alive
   synchronized (this) {
     isAlive = false;
     notifyAll();
   }
   // wait for all threads to finish
   Thread[] threads = new Thread[activeCount()];
   int count = enumerate(threads);
   for (int i = 0; i < count; i++) {
     try {
       threads[i].join();
     } catch (InterruptedException ex) {
     }
   }
 }
 /**
  * Signals that a PooledThread has started. This method does nothing by
  * default; subclasses should override to do any thread-specific startup
  * tasks.
  */
 protected void threadStarted() {
   // do nothing
 }
 /**
  * Signals that a PooledThread has stopped. This method does nothing by
  * default; subclasses should override to do any thread-specific cleanup
  * tasks.
  */
 protected void threadStopped() {
   // do nothing
 }
 /**
  * A PooledThread is a Thread in a ThreadPool group, designed to run tasks
  * (Runnables).
  */
 private class PooledThread extends Thread {
   public PooledThread() {
     super(ThreadPool.this, "PooledThread-" + (threadID++));
   }
   public void run() {
     // signal that this thread has started
     threadStarted();
     while (!isInterrupted()) {
       // get a task to run
       Runnable task = null;
       try {
         task = getTask();
       } catch (InterruptedException ex) {
       }
       // if getTask() returned null or was interrupted,
       // close this thread.
       if (task == null) {
         break;
       }
       // run the task, and eat any exceptions it throws
       try {
         task.run();
       } catch (Throwable t) {
         uncaughtException(this, t);
       }
     }
     // signal that this thread has stopped
     threadStopped();
   }
 }

} /**

* The Sound class is a container for sound samples. The sound samples are
* format-agnostic and are stored as a byte array.
*/

class Sound {

 private byte[] samples;
 /**
  * Create a new Sound object with the specified byte array. The array is not
  * copied.
  */
 public Sound(byte[] samples) {
   this.samples = samples;
 }
 /**
  * Returns this Sound"s objects samples as a byte array.
  */
 public byte[] getSamples() {
   return samples;
 }

} /**

* The LoopingByteInputStream is a ByteArrayInputStream that loops indefinitly.
* The looping stops when the close() method is called.
* <p>
* Possible ideas to extend this class:
*
    *
  • Add an option to only loop a certain number of times. *
*/

class LoopingByteInputStream extends ByteArrayInputStream {

 private boolean closed;
 /**
  * Creates a new LoopingByteInputStream with the specified byte array. The
  * array is not copied.
  */
 public LoopingByteInputStream(byte[] buffer) {
   super(buffer);
   closed = false;
 }
 /**
  * Reads length bytes from the array. If the end of the array
  * is reached, the reading starts over from the beginning of the array.
  * Returns -1 if the array has been closed.
  */
 public int read(byte[] buffer, int offset, int length) {
   if (closed) {
     return -1;
   }
   int totalBytesRead = 0;
   while (totalBytesRead < length) {
     int numBytesRead = super.read(buffer, offset + totalBytesRead,
         length - totalBytesRead);
     if (numBytesRead > 0) {
       totalBytesRead += numBytesRead;
     } else {
       reset();
     }
   }
   return totalBytesRead;
 }
 /**
  * Closes the stream. Future calls to the read() methods will return 1.
  */
 public void close() throws IOException {
   super.close();
   closed = true;
 }

} /**

* The FilteredSoundStream class is a FilterInputStream that applies a
* SoundFilter to the underlying input stream.
* 
* @see SoundFilter
*/

class FilteredSoundStream extends FilterInputStream {

 private static final int REMAINING_SIZE_UNKNOWN = -1;
 private SoundFilter soundFilter;
 private int remainingSize;
 /**
  * Creates a new FilteredSoundStream object with the specified InputStream
  * and SoundFilter.
  */
 public FilteredSoundStream(InputStream in, SoundFilter soundFilter) {
   super(in);
   this.soundFilter = soundFilter;
   remainingSize = REMAINING_SIZE_UNKNOWN;
 }
 /**
  * Overrides the FilterInputStream method to apply this filter whenever
  * bytes are read
  */
 public int read(byte[] samples, int offset, int length) throws IOException {
   // read and filter the sound samples in the stream
   int bytesRead = super.read(samples, offset, length);
   if (bytesRead > 0) {
     soundFilter.filter(samples, offset, bytesRead);
     return bytesRead;
   }
   // if there are no remaining bytes in the sound stream,
   // check if the filter has any remaining bytes ("echoes").
   if (remainingSize == REMAINING_SIZE_UNKNOWN) {
     remainingSize = soundFilter.getRemainingSize();
     // round down to nearest multiple of 4
     // (typical frame size)
     remainingSize = remainingSize / 4 * 4;
   }
   if (remainingSize > 0) {
     length = Math.min(length, remainingSize);
     // clear the buffer
     for (int i = offset; i < offset + length; i++) {
       samples[i] = 0;
     }
     // filter the remaining bytes
     soundFilter.filter(samples, offset, length);
     remainingSize -= length;
     // return
     return length;
   } else {
     // end of stream
     return -1;
   }
 }

}


 </source>
   
  
 
  



Sound player

   <source lang="java">

import java.applet.Applet; import java.applet.AudioClip; import java.io.File; import java.net.MalformedURLException; import java.net.URL; public class Play {

 public static void main(String args[]) {
   try {
     // Loop
     URL url = new URL(
         "http://java.sun.ru/applets/other/Hangman/audio/whoopy.au");
     AudioClip clip = Applet.newAudioClip(url);
     clip.loop();
     Thread.sleep(5000);
     //Play
     File file = new File("bark.wav");
     clip = Applet.newAudioClip(file.toURL());
     clip.play();
     Thread.sleep(500);
     System.exit(0);
   } catch (InterruptedException e) {
   } catch (MalformedURLException e) {
   }
 }

}


 </source>
   
  
 
  



The Filter3dTest class demonstrates the Filter3d functionality

   <source lang="java">

      /*

DEVELOPING GAME IN JAVA Caracteristiques Editeur : NEW RIDERS Auteur : BRACKEEN Parution : 09 2003 Pages : 972 Isbn : 1-59273-005-1 Reliure : Paperback Disponibilite : Disponible a la librairie

  • /

import java.awt.AWTException; import java.awt.Color; import java.awt.ruponent; import java.awt.Cursor; import java.awt.DisplayMode; import java.awt.EventQueue; import java.awt.Font; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Image; import java.awt.Point; import java.awt.Robot; import java.awt.Toolkit; import java.awt.Window; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.awt.image.BufferStrategy; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.File; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; 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; import javax.sound.sampled.UnsupportedAudioFileException; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.SwingUtilities; /**

* The Filter3dTest class demonstrates the Filter3d functionality. A fly buzzes
* around the listener, and the closer the fly is, the louder it"s heard.
* 
* @see Filter3d
* @see SimpleSoundPlayer
*/

public class Filter3dTest extends GameCore {

 public static void main(String[] args) {
   new Filter3dTest().run();
 }
 private Sprite fly;
 private Sprite listener;
 private InputManager inputManager;
 private GameAction exit;
 private SimpleSoundPlayer bzzSound;
 private InputStream bzzSoundStream;
 public void init() {
   super.init();
   // set up input manager
   exit = new GameAction("exit", GameAction.DETECT_INITAL_PRESS_ONLY);
   inputManager = new InputManager(screen.getFullScreenWindow());
   inputManager.mapToKey(exit, KeyEvent.VK_ESCAPE);
   inputManager.setCursor(InputManager.INVISIBLE_CURSOR);
   createSprites();
   // load the sound
   bzzSound = new SimpleSoundPlayer("../sounds/fly-bzz.wav");
   // create the 3d filter
   Filter3d filter = new Filter3d(fly, listener, screen.getHeight());
   // create the filtered sound stream
   bzzSoundStream = new FilteredSoundStream(new LoopingByteInputStream(
       bzzSound.getSamples()), filter);
   // play the sound in a separate thread
   new Thread() {
     public void run() {
       bzzSound.play(bzzSoundStream);
     }
   }.start();
 }
 /**
  * Loads images and creates sprites.
  */
 private void createSprites() {
   // load images
   Image fly1 = loadImage("../images/fly1.png");
   Image fly2 = loadImage("../images/fly2.png");
   Image fly3 = loadImage("../images/fly3.png");
   Image ear = loadImage("../images/ear.png");
   // create "fly" sprite
   Animation anim = new Animation();
   anim.addFrame(fly1, 50);
   anim.addFrame(fly2, 50);
   anim.addFrame(fly3, 50);
   anim.addFrame(fly2, 50);
   fly = new Sprite(anim);
   // create the listener sprite
   anim = new Animation();
   anim.addFrame(ear, 0);
   listener = new Sprite(anim);
   listener.setX((screen.getWidth() - listener.getWidth()) / 2);
   listener.setY((screen.getHeight() - listener.getHeight()) / 2);
 }
 public void update(long elapsedTime) {
   if (exit.isPressed()) {
     stop();
   } else {
     listener.update(elapsedTime);
     fly.update(elapsedTime);
     fly.setX(inputManager.getMouseX());
     fly.setY(inputManager.getMouseY());
   }
 }
 public void stop() {
   super.stop();
   // stop the bzz sound
   try {
     bzzSoundStream.close();
   } catch (IOException ex) {
   }
 }
 public void draw(Graphics2D g) {
   // draw background
   g.setColor(new Color(0x33cc33));
   g.fillRect(0, 0, screen.getWidth(), screen.getHeight());
   // draw listener
   g.drawImage(listener.getImage(), Math.round(listener.getX()), Math
       .round(listener.getY()), null);
   // draw fly
   g.drawImage(fly.getImage(), Math.round(fly.getX()), Math.round(fly
       .getY()), null);
 }

} /**

* The SimpleSoundPlayer encapsulates a sound that can be opened from the file
* system and later played.
*/

class SimpleSoundPlayer {

 public static void main(String[] args) {
   // load a sound
   SimpleSoundPlayer sound = new SimpleSoundPlayer("../sounds/voice.wav");
   // create the stream to play
   InputStream stream = new ByteArrayInputStream(sound.getSamples());
   // play the sound
   sound.play(stream);
   // exit
   System.exit(0);
 }
 private AudioFormat format;
 private byte[] samples;
 /**
  * Opens a sound from a file.
  */
 public SimpleSoundPlayer(String filename) {
   try {
     // open the audio input stream
     AudioInputStream stream = AudioSystem.getAudioInputStream(new File(
         filename));
     format = stream.getFormat();
     // get the audio samples
     samples = getSamples(stream);
   } catch (UnsupportedAudioFileException ex) {
     ex.printStackTrace();
   } catch (IOException ex) {
     ex.printStackTrace();
   }
 }
 /**
  * Gets the samples of this sound as a byte array.
  */
 public byte[] getSamples() {
   return samples;
 }
 /**
  * Gets the samples from an AudioInputStream as an array of bytes.
  */
 private byte[] getSamples(AudioInputStream audioStream) {
   // get the number of bytes to read
   int length = (int) (audioStream.getFrameLength() * format
       .getFrameSize());
   // read the entire stream
   byte[] samples = new byte[length];
   DataInputStream is = new DataInputStream(audioStream);
   try {
     is.readFully(samples);
   } catch (IOException ex) {
     ex.printStackTrace();
   }
   // return the samples
   return samples;
 }
 /**
  * Plays a stream. This method blocks (doesn"t return) until the sound is
  * finished playing.
  */
 public void play(InputStream source) {
   // use a short, 100ms (1/10th sec) buffer for real-time
   // change to the sound stream
   int bufferSize = format.getFrameSize()
       * Math.round(format.getSampleRate() / 10);
   byte[] buffer = new byte[bufferSize];
   // create a line to play to
   SourceDataLine line;
   try {
     DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
     line = (SourceDataLine) AudioSystem.getLine(info);
     line.open(format, bufferSize);
   } catch (LineUnavailableException ex) {
     ex.printStackTrace();
     return;
   }
   // start the line
   line.start();
   // copy data to the line
   try {
     int numBytesRead = 0;
     while (numBytesRead != -1) {
       numBytesRead = source.read(buffer, 0, buffer.length);
       if (numBytesRead != -1) {
         line.write(buffer, 0, numBytesRead);
       }
     }
   } catch (IOException ex) {
     ex.printStackTrace();
   }
   // wait until all data is played, then close the line
   line.drain();
   line.close();
 }

} /**

* The InputManager manages input of key and mouse events. Events are mapped to
* GameActions.
*/

class InputManager implements KeyListener, MouseListener, MouseMotionListener,

   MouseWheelListener {
 /**
  * An invisible cursor.
  */
 public static final Cursor INVISIBLE_CURSOR = Toolkit.getDefaultToolkit()
     .createCustomCursor(Toolkit.getDefaultToolkit().getImage(""),
         new Point(0, 0), "invisible");
 // mouse codes
 public static final int MOUSE_MOVE_LEFT = 0;
 public static final int MOUSE_MOVE_RIGHT = 1;
 public static final int MOUSE_MOVE_UP = 2;
 public static final int MOUSE_MOVE_DOWN = 3;
 public static final int MOUSE_WHEEL_UP = 4;
 public static final int MOUSE_WHEEL_DOWN = 5;
 public static final int MOUSE_BUTTON_1 = 6;
 public static final int MOUSE_BUTTON_2 = 7;
 public static final int MOUSE_BUTTON_3 = 8;
 private static final int NUM_MOUSE_CODES = 9;
 // key codes are defined in java.awt.KeyEvent.
 // most of the codes (except for some rare ones like
 // "alt graph") are less than 600.
 private static final int NUM_KEY_CODES = 600;
 private GameAction[] keyActions = new GameAction[NUM_KEY_CODES];
 private GameAction[] mouseActions = new GameAction[NUM_MOUSE_CODES];
 private Point mouseLocation;
 private Point centerLocation;
 private Component comp;
 private Robot robot;
 private boolean isRecentering;
 /**
  * Creates a new InputManager that listens to input from the specified
  * component.
  */
 public InputManager(Component comp) {
   this.rup = comp;
   mouseLocation = new Point();
   centerLocation = new Point();
   // register key and mouse listeners
   comp.addKeyListener(this);
   comp.addMouseListener(this);
   comp.addMouseMotionListener(this);
   comp.addMouseWheelListener(this);
   // allow input of the TAB key and other keys normally
   // used for focus traversal
   comp.setFocusTraversalKeysEnabled(false);
 }
 /**
  * Sets the cursor on this InputManager"s input component.
  */
 public void setCursor(Cursor cursor) {
   comp.setCursor(cursor);
 }
 /**
  * Sets whether realtive mouse mode is on or not. For relative mouse mode,
  * the mouse is "locked" in the center of the screen, and only the changed
  * in mouse movement is measured. In normal mode, the mouse is free to move
  * about the screen.
  */
 public void setRelativeMouseMode(boolean mode) {
   if (mode == isRelativeMouseMode()) {
     return;
   }
   if (mode) {
     try {
       robot = new Robot();
       recenterMouse();
     } catch (AWTException ex) {
       // couldn"t create robot!
       robot = null;
     }
   } else {
     robot = null;
   }
 }
 /**
  * Returns whether or not relative mouse mode is on.
  */
 public boolean isRelativeMouseMode() {
   return (robot != null);
 }
 /**
  * Maps a GameAction to a specific key. The key codes are defined in
  * java.awt.KeyEvent. If the key already has a GameAction mapped to it, the
  * new GameAction overwrites it.
  */
 public void mapToKey(GameAction gameAction, int keyCode) {
   keyActions[keyCode] = gameAction;
 }
 /**
  * Maps a GameAction to a specific mouse action. The mouse codes are defined
  * herer in InputManager (MOUSE_MOVE_LEFT, MOUSE_BUTTON_1, etc). If the
  * mouse action already has a GameAction mapped to it, the new GameAction
  * overwrites it.
  */
 public void mapToMouse(GameAction gameAction, int mouseCode) {
   mouseActions[mouseCode] = gameAction;
 }
 /**
  * Clears all mapped keys and mouse actions to this GameAction.
  */
 public void clearMap(GameAction gameAction) {
   for (int i = 0; i < keyActions.length; i++) {
     if (keyActions[i] == gameAction) {
       keyActions[i] = null;
     }
   }
   for (int i = 0; i < mouseActions.length; i++) {
     if (mouseActions[i] == gameAction) {
       mouseActions[i] = null;
     }
   }
   gameAction.reset();
 }
 /**
  * Gets a List of names of the keys and mouse actions mapped to this
  * GameAction. Each entry in the List is a String.
  */
 public List getMaps(GameAction gameCode) {
   ArrayList list = new ArrayList();
   for (int i = 0; i < keyActions.length; i++) {
     if (keyActions[i] == gameCode) {
       list.add(getKeyName(i));
     }
   }
   for (int i = 0; i < mouseActions.length; i++) {
     if (mouseActions[i] == gameCode) {
       list.add(getMouseName(i));
     }
   }
   return list;
 }
 /**
  * Resets all GameActions so they appear like they haven"t been pressed.
  */
 public void resetAllGameActions() {
   for (int i = 0; i < keyActions.length; i++) {
     if (keyActions[i] != null) {
       keyActions[i].reset();
     }
   }
   for (int i = 0; i < mouseActions.length; i++) {
     if (mouseActions[i] != null) {
       mouseActions[i].reset();
     }
   }
 }
 /**
  * Gets the name of a key code.
  */
 public static String getKeyName(int keyCode) {
   return KeyEvent.getKeyText(keyCode);
 }
 /**
  * Gets the name of a mouse code.
  */
 public static String getMouseName(int mouseCode) {
   switch (mouseCode) {
   case MOUSE_MOVE_LEFT:
     return "Mouse Left";
   case MOUSE_MOVE_RIGHT:
     return "Mouse Right";
   case MOUSE_MOVE_UP:
     return "Mouse Up";
   case MOUSE_MOVE_DOWN:
     return "Mouse Down";
   case MOUSE_WHEEL_UP:
     return "Mouse Wheel Up";
   case MOUSE_WHEEL_DOWN:
     return "Mouse Wheel Down";
   case MOUSE_BUTTON_1:
     return "Mouse Button 1";
   case MOUSE_BUTTON_2:
     return "Mouse Button 2";
   case MOUSE_BUTTON_3:
     return "Mouse Button 3";
   default:
     return "Unknown mouse code " + mouseCode;
   }
 }
 /**
  * Gets the x position of the mouse.
  */
 public int getMouseX() {
   return mouseLocation.x;
 }
 /**
  * Gets the y position of the mouse.
  */
 public int getMouseY() {
   return mouseLocation.y;
 }
 /**
  * Uses the Robot class to try to postion the mouse in the center of the
  * screen.
  * <p>
  * Note that use of the Robot class may not be available on all platforms.
  */
 private synchronized void recenterMouse() {
   if (robot != null && comp.isShowing()) {
     centerLocation.x = comp.getWidth() / 2;
     centerLocation.y = comp.getHeight() / 2;
     SwingUtilities.convertPointToScreen(centerLocation, comp);
     isRecentering = true;
     robot.mouseMove(centerLocation.x, centerLocation.y);
   }
 }
 private GameAction getKeyAction(KeyEvent e) {
   int keyCode = e.getKeyCode();
   if (keyCode < keyActions.length) {
     return keyActions[keyCode];
   } else {
     return null;
   }
 }
 /**
  * Gets the mouse code for the button specified in this MouseEvent.
  */
 public static int getMouseButtonCode(MouseEvent e) {
   switch (e.getButton()) {
   case MouseEvent.BUTTON1:
     return MOUSE_BUTTON_1;
   case MouseEvent.BUTTON2:
     return MOUSE_BUTTON_2;
   case MouseEvent.BUTTON3:
     return MOUSE_BUTTON_3;
   default:
     return -1;
   }
 }
 private GameAction getMouseButtonAction(MouseEvent e) {
   int mouseCode = getMouseButtonCode(e);
   if (mouseCode != -1) {
     return mouseActions[mouseCode];
   } else {
     return null;
   }
 }
 // from the KeyListener interface
 public void keyPressed(KeyEvent e) {
   GameAction gameAction = getKeyAction(e);
   if (gameAction != null) {
     gameAction.press();
   }
   // make sure the key isn"t processed for anything else
   e.consume();
 }
 // from the KeyListener interface
 public void keyReleased(KeyEvent e) {
   GameAction gameAction = getKeyAction(e);
   if (gameAction != null) {
     gameAction.release();
   }
   // make sure the key isn"t processed for anything else
   e.consume();
 }
 // from the KeyListener interface
 public void keyTyped(KeyEvent e) {
   // make sure the key isn"t processed for anything else
   e.consume();
 }
 // from the MouseListener interface
 public void mousePressed(MouseEvent e) {
   GameAction gameAction = getMouseButtonAction(e);
   if (gameAction != null) {
     gameAction.press();
   }
 }
 // from the MouseListener interface
 public void mouseReleased(MouseEvent e) {
   GameAction gameAction = getMouseButtonAction(e);
   if (gameAction != null) {
     gameAction.release();
   }
 }
 // from the MouseListener interface
 public void mouseClicked(MouseEvent e) {
   // do nothing
 }
 // from the MouseListener interface
 public void mouseEntered(MouseEvent e) {
   mouseMoved(e);
 }
 // from the MouseListener interface
 public void mouseExited(MouseEvent e) {
   mouseMoved(e);
 }
 // from the MouseMotionListener interface
 public void mouseDragged(MouseEvent e) {
   mouseMoved(e);
 }
 // from the MouseMotionListener interface
 public synchronized void mouseMoved(MouseEvent e) {
   // this event is from re-centering the mouse - ignore it
   if (isRecentering && centerLocation.x == e.getX()
       && centerLocation.y == e.getY()) {
     isRecentering = false;
   } else {
     int dx = e.getX() - mouseLocation.x;
     int dy = e.getY() - mouseLocation.y;
     mouseHelper(MOUSE_MOVE_LEFT, MOUSE_MOVE_RIGHT, dx);
     mouseHelper(MOUSE_MOVE_UP, MOUSE_MOVE_DOWN, dy);
     if (isRelativeMouseMode()) {
       recenterMouse();
     }
   }
   mouseLocation.x = e.getX();
   mouseLocation.y = e.getY();
 }
 // from the MouseWheelListener interface
 public void mouseWheelMoved(MouseWheelEvent e) {
   mouseHelper(MOUSE_WHEEL_UP, MOUSE_WHEEL_DOWN, e.getWheelRotation());
 }
 private void mouseHelper(int codeNeg, int codePos, int amount) {
   GameAction gameAction;
   if (amount < 0) {
     gameAction = mouseActions[codeNeg];
   } else {
     gameAction = mouseActions[codePos];
   }
   if (gameAction != null) {
     gameAction.press(Math.abs(amount));
     gameAction.release();
   }
 }

} /**

* Simple abstract class used for testing. Subclasses should implement the
* draw() method.
*/

abstract class GameCore {

 protected static final int FONT_SIZE = 24;
 private static final DisplayMode POSSIBLE_MODES[] = {
     new DisplayMode(800, 600, 32, 0), new DisplayMode(800, 600, 24, 0),
     new DisplayMode(800, 600, 16, 0), new DisplayMode(640, 480, 32, 0),
     new DisplayMode(640, 480, 24, 0), new DisplayMode(640, 480, 16, 0) };
 private boolean isRunning;
 protected ScreenManager screen;
 /**
  * Signals the game loop that it"s time to quit
  */
 public void stop() {
   isRunning = false;
 }
 /**
  * Calls init() and gameLoop()
  */
 public void run() {
   try {
     init();
     gameLoop();
   } finally {
     screen.restoreScreen();
     lazilyExit();
   }
 }
 /**
  * Exits the VM from a daemon thread. The daemon thread waits 2 seconds then
  * calls System.exit(0). Since the VM should exit when only daemon threads
  * are running, this makes sure System.exit(0) is only called if neccesary.
  * It"s neccesary if the Java Sound system is running.
  */
 public void lazilyExit() {
   Thread thread = new Thread() {
     public void run() {
       // first, wait for the VM exit on its own.
       try {
         Thread.sleep(2000);
       } catch (InterruptedException ex) {
       }
       // system is still running, so force an exit
       System.exit(0);
     }
   };
   thread.setDaemon(true);
   thread.start();
 }
 /**
  * Sets full screen mode and initiates and objects.
  */
 public void init() {
   screen = new ScreenManager();
   DisplayMode displayMode = screen
       .findFirstCompatibleMode(POSSIBLE_MODES);
   screen.setFullScreen(displayMode);
   Window window = screen.getFullScreenWindow();
   window.setFont(new Font("Dialog", Font.PLAIN, FONT_SIZE));
   window.setBackground(Color.blue);
   window.setForeground(Color.white);
   isRunning = true;
 }
 public Image loadImage(String fileName) {
   return new ImageIcon(fileName).getImage();
 }
 /**
  * Runs through the game loop until stop() is called.
  */
 public void gameLoop() {
   long startTime = System.currentTimeMillis();
   long currTime = startTime;
   while (isRunning) {
     long elapsedTime = System.currentTimeMillis() - currTime;
     currTime += elapsedTime;
     // update
     update(elapsedTime);
     // draw the screen
     Graphics2D g = screen.getGraphics();
     draw(g);
     g.dispose();
     screen.update();
     // take a nap
     try {
       Thread.sleep(20);
     } catch (InterruptedException ex) {
     }
   }
 }
 /**
  * Updates the state of the game/animation based on the amount of elapsed
  * time that has passed.
  */
 public void update(long elapsedTime) {
   // do nothing
 }
 /**
  * Draws to the screen. Subclasses must override this method.
  */
 public abstract void draw(Graphics2D g);

} /**

* The GameAction class is an abstract to a user-initiated action, like jumping
* or moving. GameActions can be mapped to keys or the mouse with the
* InputManager.
*/

class GameAction {

 /**
  * Normal behavior. The isPressed() method returns true as long as the key
  * is held down.
  */
 public static final int NORMAL = 0;
 /**
  * Initial press behavior. The isPressed() method returns true only after
  * the key is first pressed, and not again until the key is released and
  * pressed again.
  */
 public static final int DETECT_INITAL_PRESS_ONLY = 1;
 private static final int STATE_RELEASED = 0;
 private static final int STATE_PRESSED = 1;
 private static final int STATE_WAITING_FOR_RELEASE = 2;
 private String name;
 private int behavior;
 private int amount;
 private int state;
 /**
  * Create a new GameAction with the NORMAL behavior.
  */
 public GameAction(String name) {
   this(name, NORMAL);
 }
 /**
  * Create a new GameAction with the specified behavior.
  */
 public GameAction(String name, int behavior) {
   this.name = name;
   this.behavior = behavior;
   reset();
 }
 /**
  * Gets the name of this GameAction.
  */
 public String getName() {
   return name;
 }
 /**
  * Resets this GameAction so that it appears like it hasn"t been pressed.
  */
 public void reset() {
   state = STATE_RELEASED;
   amount = 0;
 }
 /**
  * Taps this GameAction. Same as calling press() followed by release().
  */
 public synchronized void tap() {
   press();
   release();
 }
 /**
  * Signals that the key was pressed.
  */
 public synchronized void press() {
   press(1);
 }
 /**
  * Signals that the key was pressed a specified number of times, or that the
  * mouse move a spcified distance.
  */
 public synchronized void press(int amount) {
   if (state != STATE_WAITING_FOR_RELEASE) {
     this.amount += amount;
     state = STATE_PRESSED;
   }
 }
 /**
  * Signals that the key was released
  */
 public synchronized void release() {
   state = STATE_RELEASED;
 }
 /**
  * Returns whether the key was pressed or not since last checked.
  */
 public synchronized boolean isPressed() {
   return (getAmount() != 0);
 }
 /**
  * For keys, this is the number of times the key was pressed since it was
  * last checked. For mouse movement, this is the distance moved.
  */
 public synchronized int getAmount() {
   int retVal = amount;
   if (retVal != 0) {
     if (state == STATE_RELEASED) {
       amount = 0;
     } else if (behavior == DETECT_INITAL_PRESS_ONLY) {
       state = STATE_WAITING_FOR_RELEASE;
       amount = 0;
     }
   }
   return retVal;
 }

} class Sprite {

 private Animation anim;
 // position (pixels)
 private float x;
 private float y;
 // velocity (pixels per millisecond)
 private float dx;
 private float dy;
 /**
  * Creates a new Sprite object with the specified Animation.
  */
 public Sprite(Animation anim) {
   this.anim = anim;
 }
 /**
  * Updates this Sprite"s Animation and its position based on the velocity.
  */
 public void update(long elapsedTime) {
   x += dx * elapsedTime;
   y += dy * elapsedTime;
   anim.update(elapsedTime);
 }
 /**
  * Gets this Sprite"s current x position.
  */
 public float getX() {
   return x;
 }
 /**
  * Gets this Sprite"s current y position.
  */
 public float getY() {
   return y;
 }
 /**
  * Sets this Sprite"s current x position.
  */
 public void setX(float x) {
   this.x = x;
 }
 /**
  * Sets this Sprite"s current y position.
  */
 public void setY(float y) {
   this.y = y;
 }
 /**
  * Gets this Sprite"s width, based on the size of the current image.
  */
 public int getWidth() {
   return anim.getImage().getWidth(null);
 }
 /**
  * Gets this Sprite"s height, based on the size of the current image.
  */
 public int getHeight() {
   return anim.getImage().getHeight(null);
 }
 /**
  * Gets the horizontal velocity of this Sprite in pixels per millisecond.
  */
 public float getVelocityX() {
   return dx;
 }
 /**
  * Gets the vertical velocity of this Sprite in pixels per millisecond.
  */
 public float getVelocityY() {
   return dy;
 }
 /**
  * Sets the horizontal velocity of this Sprite in pixels per millisecond.
  */
 public void setVelocityX(float dx) {
   this.dx = dx;
 }
 /**
  * Sets the vertical velocity of this Sprite in pixels per millisecond.
  */
 public void setVelocityY(float dy) {
   this.dy = dy;
 }
 /**
  * Gets this Sprite"s current image.
  */
 public Image getImage() {
   return anim.getImage();
 }

} /**

* The Filter3d class is a SoundFilter that creates a 3d sound effect. The sound
* is filtered so that it is quiter the farther away the sound source is from
* the listener.
* <p>
* Possible ideas to extend this class:
*
    *
  • pan the sound to the left and right speakers *
* 
* @see FilteredSoundStream
*/

class Filter3d extends SoundFilter {

 // number of samples to shift when changing the volume.
 private static final int NUM_SHIFTING_SAMPLES = 500;
 private Sprite source;
 private Sprite listener;
 private int maxDistance;
 private float lastVolume;
 /**
  * Creates a new Filter3d object with the specified source and listener
  * Sprites. The Sprite"s position can be changed while this filter is
  * running.
  * <p>
  * The maxDistance parameter is the maximum distance that the sound can be
  * heard.
  */
 public Filter3d(Sprite source, Sprite listener, int maxDistance) {
   this.source = source;
   this.listener = listener;
   this.maxDistance = maxDistance;
   this.lastVolume = 0.0f;
 }
 /**
  * Filters the sound so that it gets more quiet with distance.
  */
 public void filter(byte[] samples, int offset, int length) {
   if (source == null || listener == null) {
     // nothing to filter - return
     return;
   }
   // calculate the listener"s distance from the sound source
   float dx = (source.getX() - listener.getX());
   float dy = (source.getY() - listener.getY());
   float distance = (float) Math.sqrt(dx * dx + dy * dy);
   // set volume from 0 (no sound) to 1
   float newVolume = (maxDistance - distance) / maxDistance;
   if (newVolume <= 0) {
     newVolume = 0;
   }
   // set the volume of the sample
   int shift = 0;
   for (int i = offset; i < offset + length; i += 2) {
     float volume = newVolume;
     // shift from the last volume to the new volume
     if (shift < NUM_SHIFTING_SAMPLES) {
       volume = lastVolume + (newVolume - lastVolume) * shift
           / NUM_SHIFTING_SAMPLES;
       shift++;
     }
     // change the volume of the sample
     short oldSample = getSample(samples, i);
     short newSample = (short) (oldSample * volume);
     setSample(samples, i, newSample);
   }
   lastVolume = newVolume;
 }

} /**

* The FilteredSoundStream class is a FilterInputStream that applies a
* SoundFilter to the underlying input stream.
* 
* @see SoundFilter
*/

class FilteredSoundStream extends FilterInputStream {

 private static final int REMAINING_SIZE_UNKNOWN = -1;
 private SoundFilter soundFilter;
 private int remainingSize;
 /**
  * Creates a new FilteredSoundStream object with the specified InputStream
  * and SoundFilter.
  */
 public FilteredSoundStream(InputStream in, SoundFilter soundFilter) {
   super(in);
   this.soundFilter = soundFilter;
   remainingSize = REMAINING_SIZE_UNKNOWN;
 }
 /**
  * Overrides the FilterInputStream method to apply this filter whenever
  * bytes are read
  */
 public int read(byte[] samples, int offset, int length) throws IOException {
   // read and filter the sound samples in the stream
   int bytesRead = super.read(samples, offset, length);
   if (bytesRead > 0) {
     soundFilter.filter(samples, offset, bytesRead);
     return bytesRead;
   }
   // if there are no remaining bytes in the sound stream,
   // check if the filter has any remaining bytes ("echoes").
   if (remainingSize == REMAINING_SIZE_UNKNOWN) {
     remainingSize = soundFilter.getRemainingSize();
     // round down to nearest multiple of 4
     // (typical frame size)
     remainingSize = remainingSize / 4 * 4;
   }
   if (remainingSize > 0) {
     length = Math.min(length, remainingSize);
     // clear the buffer
     for (int i = offset; i < offset + length; i++) {
       samples[i] = 0;
     }
     // filter the remaining bytes
     soundFilter.filter(samples, offset, length);
     remainingSize -= length;
     // return
     return length;
   } else {
     // end of stream
     return -1;
   }
 }

} /**

* The Animation class manages a series of images (frames) and the amount of
* time to display each frame.
*/

class Animation {

 private ArrayList frames;
 private int currFrameIndex;
 private long animTime;
 private long totalDuration;
 /**
  * Creates a new, empty Animation.
  */
 public Animation() {
   frames = new ArrayList();
   totalDuration = 0;
   start();
 }
 /**
  * Adds an image to the animation with the specified duration (time to
  * display the image).
  */
 public synchronized void addFrame(Image image, long duration) {
   totalDuration += duration;
   frames.add(new AnimFrame(image, totalDuration));
 }
 /**
  * Starts this animation over from the beginning.
  */
 public synchronized void start() {
   animTime = 0;
   currFrameIndex = 0;
 }
 /**
  * Updates this animation"s current image (frame), if neccesary.
  */
 public synchronized void update(long elapsedTime) {
   if (frames.size() > 1) {
     animTime += elapsedTime;
     if (animTime >= totalDuration) {
       animTime = animTime % totalDuration;
       currFrameIndex = 0;
     }
     while (animTime > getFrame(currFrameIndex).endTime) {
       currFrameIndex++;
     }
   }
 }
 /**
  * Gets this Animation"s current image. Returns null if this animation has
  * no images.
  */
 public synchronized Image getImage() {
   if (frames.size() == 0) {
     return null;
   } else {
     return getFrame(currFrameIndex).image;
   }
 }
 private AnimFrame getFrame(int i) {
   return (AnimFrame) frames.get(i);
 }
 private class AnimFrame {
   Image image;
   long endTime;
   public AnimFrame(Image image, long endTime) {
     this.image = image;
     this.endTime = endTime;
   }
 }

} /**

* The LoopingByteInputStream is a ByteArrayInputStream that loops indefinitly.
* The looping stops when the close() method is called.
* <p>
* Possible ideas to extend this class:
*
    *
  • Add an option to only loop a certain number of times. *
*/

class LoopingByteInputStream extends ByteArrayInputStream {

 private boolean closed;
 /**
  * Creates a new LoopingByteInputStream with the specified byte array. The
  * array is not copied.
  */
 public LoopingByteInputStream(byte[] buffer) {
   super(buffer);
   closed = false;
 }
 /**
  * Reads length bytes from the array. If the end of the array
  * is reached, the reading starts over from the beginning of the array.
  * Returns -1 if the array has been closed.
  */
 public int read(byte[] buffer, int offset, int length) {
   if (closed) {
     return -1;
   }
   int totalBytesRead = 0;
   while (totalBytesRead < length) {
     int numBytesRead = super.read(buffer, offset + totalBytesRead,
         length - totalBytesRead);
     if (numBytesRead > 0) {
       totalBytesRead += numBytesRead;
     } else {
       reset();
     }
   }
   return totalBytesRead;
 }
 /**
  * Closes the stream. Future calls to the read() methods will return 1.
  */
 public void close() throws IOException {
   super.close();
   closed = true;
 }

} /**

* A abstract class designed to filter sound samples. Since SoundFilters may use
* internal buffering of samples, a new SoundFilter object should be created for
* every sound played. However, SoundFilters can be reused after they are
* finished by called the reset() method.
* <p>
* Assumes all samples are 16-bit, signed, little-endian format.
* 
* @see FilteredSoundStream
*/

abstract class SoundFilter {

 /**
  * Resets this SoundFilter. Does nothing by default.
  */
 public void reset() {
   // do nothing
 }
 /**
  * Gets the remaining size, in bytes, that this filter plays after the sound
  * is finished. An example would be an echo that plays longer than it"s
  * original sound. This method returns 0 by default.
  */
 public int getRemainingSize() {
   return 0;
 }
 /**
  * Filters an array of samples. Samples should be in 16-bit, signed,
  * little-endian format.
  */
 public void filter(byte[] samples) {
   filter(samples, 0, samples.length);
 }
 /**
  * Filters an array of samples. Samples should be in 16-bit, signed,
  * little-endian format. This method should be implemented by subclasses.
  */
 public abstract void filter(byte[] samples, int offset, int length);
 /**
  * Convenience method for getting a 16-bit sample from a byte array. Samples
  * should be in 16-bit, signed, little-endian format.
  */
 public static short getSample(byte[] buffer, int position) {
   return (short) (((buffer[position + 1] & 0xff) << 8) | (buffer[position] & 0xff));
 }
 /**
  * Convenience method for setting a 16-bit sample in a byte array. Samples
  * should be in 16-bit, signed, little-endian format.
  */
 public static void setSample(byte[] buffer, int position, short sample) {
   buffer[position] = (byte) (sample & 0xff);
   buffer[position + 1] = (byte) ((sample >> 8) & 0xff);
 }

} /**

* The ScreenManager class manages initializing and displaying full screen
* graphics modes.
*/

class ScreenManager {

 private GraphicsDevice device;
 /**
  * Creates a new ScreenManager object.
  */
 public ScreenManager() {
   GraphicsEnvironment environment = GraphicsEnvironment
       .getLocalGraphicsEnvironment();
   device = environment.getDefaultScreenDevice();
 }
 /**
  * Returns a list of compatible display modes for the default device on the
  * system.
  */
 public DisplayMode[] getCompatibleDisplayModes() {
   return device.getDisplayModes();
 }
 /**
  * Returns the first compatible mode in a list of modes. Returns null if no
  * modes are compatible.
  */
 public DisplayMode findFirstCompatibleMode(DisplayMode modes[]) {
   DisplayMode goodModes[] = device.getDisplayModes();
   for (int i = 0; i < modes.length; i++) {
     for (int j = 0; j < goodModes.length; j++) {
       if (displayModesMatch(modes[i], goodModes[j])) {
         return modes[i];
       }
     }
   }
   return null;
 }
 /**
  * Returns the current display mode.
  */
 public DisplayMode getCurrentDisplayMode() {
   return device.getDisplayMode();
 }
 /**
  * Determines if two display modes "match". Two display modes match if they
  * have the same resolution, bit depth, and refresh rate. The bit depth is
  * ignored if one of the modes has a bit depth of
  * DisplayMode.BIT_DEPTH_MULTI. Likewise, the refresh rate is ignored if one
  * of the modes has a refresh rate of DisplayMode.REFRESH_RATE_UNKNOWN.
  */
 public boolean displayModesMatch(DisplayMode mode1, DisplayMode mode2)
 {
   if (mode1.getWidth() != mode2.getWidth()
       || mode1.getHeight() != mode2.getHeight()) {
     return false;
   }
   if (mode1.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI
       && mode2.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI
       && mode1.getBitDepth() != mode2.getBitDepth()) {
     return false;
   }
   if (mode1.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN
       && mode2.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN
       && mode1.getRefreshRate() != mode2.getRefreshRate()) {
     return false;
   }
   return true;
 }
 /**
  * Enters full screen mode and changes the display mode. If the specified
  * display mode is null or not compatible with this device, or if the
  * display mode cannot be changed on this system, the current display mode
  * is used.
  * <p>
  * The display uses a BufferStrategy with 2 buffers.
  */
 public void setFullScreen(DisplayMode displayMode) {
   final JFrame frame = new JFrame();
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.setUndecorated(true);
   frame.setIgnoreRepaint(true);
   frame.setResizable(false);
   device.setFullScreenWindow(frame);
   if (displayMode != null && device.isDisplayChangeSupported()) {
     try {
       device.setDisplayMode(displayMode);
     } catch (IllegalArgumentException ex) {
     }
     // fix for mac os x
     frame.setSize(displayMode.getWidth(), displayMode.getHeight());
   }
   // avoid potential deadlock in 1.4.1_02
   try {
     EventQueue.invokeAndWait(new Runnable() {
       public void run() {
         frame.createBufferStrategy(2);
       }
     });
   } catch (InterruptedException ex) {
     // ignore
   } catch (InvocationTargetException ex) {
     // ignore
   }
 }
 /**
  * Gets the graphics context for the display. The ScreenManager uses double
  * buffering, so applications must call update() to show any graphics drawn.
  * <p>
  * The application must dispose of the graphics object.
  */
 public Graphics2D getGraphics() {
   Window window = device.getFullScreenWindow();
   if (window != null) {
     BufferStrategy strategy = window.getBufferStrategy();
     return (Graphics2D) strategy.getDrawGraphics();
   } else {
     return null;
   }
 }
 /**
  * Updates the display.
  */
 public void update() {
   Window window = device.getFullScreenWindow();
   if (window != null) {
     BufferStrategy strategy = window.getBufferStrategy();
     if (!strategy.contentsLost()) {
       strategy.show();
     }
   }
   // Sync the display on some systems.
   // (on Linux, this fixes event queue problems)
   Toolkit.getDefaultToolkit().sync();
 }
 /**
  * Returns the window currently used in full screen mode. Returns null if
  * the device is not in full screen mode.
  */
 public JFrame getFullScreenWindow() {
   return (JFrame) device.getFullScreenWindow();
 }
 /**
  * Returns the width of the window currently used in full screen mode.
  * Returns 0 if the device is not in full screen mode.
  */
 public int getWidth() {
   Window window = device.getFullScreenWindow();
   if (window != null) {
     return window.getWidth();
   } else {
     return 0;
   }
 }
 /**
  * Returns the height of the window currently used in full screen mode.
  * Returns 0 if the device is not in full screen mode.
  */
 public int getHeight() {
   Window window = device.getFullScreenWindow();
   if (window != null) {
     return window.getHeight();
   } else {
     return 0;
   }
 }
 /**
  * Restores the screen"s display mode.
  */
 public void restoreScreen() {
   Window window = device.getFullScreenWindow();
   if (window != null) {
     window.dispose();
   }
   device.setFullScreenWindow(null);
 }
 /**
  * Creates an image compatible with the current display.
  */
 public BufferedImage createCompatibleImage(int w, int h, int transparancy) {
   Window window = device.getFullScreenWindow();
   if (window != null) {
     GraphicsConfiguration gc = window.getGraphicsConfiguration();
     return gc.createCompatibleImage(w, h, transparancy);
   }
   return null;
 }

}


 </source>
   
  
 
  



This is a simple program to record sounds and play them back

   <source lang="java">


/*

*
* Copyright (c) 1999 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free,
* license to use, modify and redistribute this software in 
* source and binary code form, provided that i) this copyright
* notice and license appear on all copies of the software; and 
* ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty
* of any kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS
* AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE 
* HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR 
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT
* WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT
* OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, 
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS
* OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY
* TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGES.
This software is not designed or intended for use in on-line
control of aircraft, air traffic, aircraft navigation or
aircraft communications; or in the design, construction,
operation or maintenance of any nuclear facility. Licensee 
represents and warrants that it will not use or redistribute 
the Software for such purposes.
*/

/* The above copyright statement is included because this

* program uses several methods from the JavaSoundDemo
* distributed by SUN. In some cases, the sound processing methods
* unmodified or only slightly modified.
* All other methods copyright Steve Potts, 2002
*/

import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; 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; import javax.sound.sampled.TargetDataLine; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.border.EmptyBorder; import javax.swing.border.SoftBevelBorder; /**

* SimpleSoundCapture Example. This is a simple program to record sounds and
* play them back. It uses some methods from the CapturePlayback program in the
* JavaSoundDemo. For licensizing reasons the disclaimer above is included.
* 
* @author Steve Potts
*/

public class SimpleSoundCapture extends JPanel implements ActionListener {

 final int bufSize = 16384;
 Capture capture = new Capture();
 Playback playback = new Playback();
 AudioInputStream audioInputStream;
 JButton playB, captB;
 JTextField textField;
 String errStr;
 double duration, seconds;
 File file;
 public SimpleSoundCapture() {
   setLayout(new BorderLayout());
   EmptyBorder eb = new EmptyBorder(5, 5, 5, 5);
   SoftBevelBorder sbb = new SoftBevelBorder(SoftBevelBorder.LOWERED);
   setBorder(new EmptyBorder(5, 5, 5, 5));
   JPanel p1 = new JPanel();
   p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS));
   JPanel p2 = new JPanel();
   p2.setBorder(sbb);
   p2.setLayout(new BoxLayout(p2, BoxLayout.Y_AXIS));
   JPanel buttonsPanel = new JPanel();
   buttonsPanel.setBorder(new EmptyBorder(10, 0, 5, 0));
   playB = addButton("Play", buttonsPanel, false);
   captB = addButton("Record", buttonsPanel, true);
   p2.add(buttonsPanel);
   p1.add(p2);
   add(p1);
 }
 public void open() {
 }
 public void close() {
   if (playback.thread != null) {
     playB.doClick(0);
   }
   if (capture.thread != null) {
     captB.doClick(0);
   }
 }
 private JButton addButton(String name, JPanel p, boolean state) {
   JButton b = new JButton(name);
   b.addActionListener(this);
   b.setEnabled(state);
   p.add(b);
   return b;
 }
 public void actionPerformed(ActionEvent e) {
   Object obj = e.getSource();
   if (obj.equals(playB)) {
     if (playB.getText().startsWith("Play")) {
       playback.start();
       captB.setEnabled(false);
       playB.setText("Stop");
     } else {
       playback.stop();
       captB.setEnabled(true);
       playB.setText("Play");
     }
   } else if (obj.equals(captB)) {
     if (captB.getText().startsWith("Record")) {
       capture.start();
       playB.setEnabled(false);
       captB.setText("Stop");
     } else {
       capture.stop();
       playB.setEnabled(true);
     }
   }
 }
 /**
  * Write data to the OutputChannel.
  */
 public class Playback implements Runnable {
   SourceDataLine line;
   Thread thread;
   public void start() {
     errStr = null;
     thread = new Thread(this);
     thread.setName("Playback");
     thread.start();
   }
   public void stop() {
     thread = null;
   }
   private void shutDown(String message) {
     if ((errStr = message) != null) {
       System.err.println(errStr);
     }
     if (thread != null) {
       thread = null;
       captB.setEnabled(true);
       playB.setText("Play");
     }
   }
   public void run() {
     // make sure we have something to play
     if (audioInputStream == null) {
       shutDown("No loaded audio to play back");
       return;
     }
     // reset to the beginnning of the stream
     try {
       audioInputStream.reset();
     } catch (Exception e) {
       shutDown("Unable to reset the stream\n" + e);
       return;
     }
     // get an AudioInputStream of the desired format for playback
     AudioFormat.Encoding encoding = AudioFormat.Encoding.PCM_SIGNED;
     float rate = 44100.0f;
     int channels = 2;
     int frameSize = 4;
     int sampleSize = 16;
     boolean bigEndian = true;
     AudioFormat format = new AudioFormat(encoding, rate, sampleSize, channels, (sampleSize / 8)
         * channels, rate, bigEndian);
     AudioInputStream playbackInputStream = AudioSystem.getAudioInputStream(format,
         audioInputStream);
     if (playbackInputStream == null) {
       shutDown("Unable to convert stream of format " + audioInputStream + " to format " + format);
       return;
     }
     // define the required attributes for our line,
     // and make sure a compatible line is supported.
     DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
     if (!AudioSystem.isLineSupported(info)) {
       shutDown("Line matching " + info + " not supported.");
       return;
     }
     // get and open the source data line for playback.
     try {
       line = (SourceDataLine) AudioSystem.getLine(info);
       line.open(format, bufSize);
     } catch (LineUnavailableException ex) {
       shutDown("Unable to open the line: " + ex);
       return;
     }
     // play back the captured audio data
     int frameSizeInBytes = format.getFrameSize();
     int bufferLengthInFrames = line.getBufferSize() / 8;
     int bufferLengthInBytes = bufferLengthInFrames * frameSizeInBytes;
     byte[] data = new byte[bufferLengthInBytes];
     int numBytesRead = 0;
     // start the source data line
     line.start();
     while (thread != null) {
       try {
         if ((numBytesRead = playbackInputStream.read(data)) == -1) {
           break;
         }
         int numBytesRemaining = numBytesRead;
         while (numBytesRemaining > 0) {
           numBytesRemaining -= line.write(data, 0, numBytesRemaining);
         }
       } catch (Exception e) {
         shutDown("Error during playback: " + e);
         break;
       }
     }
     // we reached the end of the stream.
     // let the data play out, then
     // stop and close the line.
     if (thread != null) {
       line.drain();
     }
     line.stop();
     line.close();
     line = null;
     shutDown(null);
   }
 } // End class Playback
 /**
  * Reads data from the input channel and writes to the output stream
  */
 class Capture implements Runnable {
   TargetDataLine line;
   Thread thread;
   public void start() {
     errStr = null;
     thread = new Thread(this);
     thread.setName("Capture");
     thread.start();
   }
   public void stop() {
     thread = null;
   }
   private void shutDown(String message) {
     if ((errStr = message) != null && thread != null) {
       thread = null;
       playB.setEnabled(true);
       captB.setText("Record");
       System.err.println(errStr);
     }
   }
   public void run() {
     duration = 0;
     audioInputStream = null;
     // define the required attributes for our line,
     // and make sure a compatible line is supported.
     AudioFormat.Encoding encoding = AudioFormat.Encoding.PCM_SIGNED;
     float rate = 44100.0f;
     int channels = 2;
     int frameSize = 4;
     int sampleSize = 16;
     boolean bigEndian = true;
     AudioFormat format = new AudioFormat(encoding, rate, sampleSize, channels, (sampleSize / 8)
         * channels, rate, bigEndian);
     DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
     if (!AudioSystem.isLineSupported(info)) {
       shutDown("Line matching " + info + " not supported.");
       return;
     }
     // get and open the target data line for capture.
     try {
       line = (TargetDataLine) AudioSystem.getLine(info);
       line.open(format, line.getBufferSize());
     } catch (LineUnavailableException ex) {
       shutDown("Unable to open the line: " + ex);
       return;
     } catch (SecurityException ex) {
       shutDown(ex.toString());
       //JavaSound.showInfoDialog();
       return;
     } catch (Exception ex) {
       shutDown(ex.toString());
       return;
     }
     // play back the captured audio data
     ByteArrayOutputStream out = new ByteArrayOutputStream();
     int frameSizeInBytes = format.getFrameSize();
     int bufferLengthInFrames = line.getBufferSize() / 8;
     int bufferLengthInBytes = bufferLengthInFrames * frameSizeInBytes;
     byte[] data = new byte[bufferLengthInBytes];
     int numBytesRead;
     line.start();
     while (thread != null) {
       if ((numBytesRead = line.read(data, 0, bufferLengthInBytes)) == -1) {
         break;
       }
       out.write(data, 0, numBytesRead);
     }
     // we reached the end of the stream.
     // stop and close the line.
     line.stop();
     line.close();
     line = null;
     // stop and close the output stream
     try {
       out.flush();
       out.close();
     } catch (IOException ex) {
       ex.printStackTrace();
     }
     // load bytes into the audio input stream for playback
     byte audioBytes[] = out.toByteArray();
     ByteArrayInputStream bais = new ByteArrayInputStream(audioBytes);
     audioInputStream = new AudioInputStream(bais, format, audioBytes.length / frameSizeInBytes);
     long milliseconds = (long) ((audioInputStream.getFrameLength() * 1000) / format
         .getFrameRate());
     duration = milliseconds / 1000.0;
     try {
       audioInputStream.reset();
     } catch (Exception ex) {
       ex.printStackTrace();
       return;
     }
   }
 } // End class Capture
 public static void main(String s[]) {
   SimpleSoundCapture ssc = new SimpleSoundCapture();
   ssc.open();
   JFrame f = new JFrame("Capture/Playback");
   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   f.getContentPane().add("Center", ssc);
   f.pack();
   Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
   int w = 360;
   int h = 170;
   f.setLocation(screenSize.width / 2 - w / 2, screenSize.height / 2 - h / 2);
   f.setSize(w, h);
   f.show();
 }

}

 </source>