Development Java Tutorial

/*
 *
 * 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  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);
  }
}