content: import java.io.File;
  
  import javax.sound.midi.MidiSystem;
  import javax.sound.midi.Receiver;
  import javax.sound.midi.Sequence;
  import javax.sound.midi.Sequencer;
  import javax.sound.midi.ShortMessage;
  import javax.sound.midi.Synthesizer;
  
  /**
   * Midi file playing.
   * 
   * @author Primadude.
   */
  public class Midi implements Runnable {
  
  	/**
  	 * The name of the midi file.
  	 */
  	String midiFileName;
  
  	/**
  	 * The dir of the midi file.
  	 */
  	String midiSaveDir;
  
  	/**
  	 * The Sequence object.
  	 */
  	Sequence sequence;
  
  	/**
  	 * The Sequencer object.
  	 */
  	Sequencer sequencer;
  
  	/**
  	 * The Synthesizer object.
  	 */
  	Synthesizer synthesizer;
  
  	/**
  	 * Gets the name of the midi file.
  	 * 
  	 * @return The midiFileName variable.
  	 */
  	public String getMidiFileName() {
  		return midiFileName;
  	}
  
  	/**
  	 * Gets the midi file directory.
  	 * 
  	 * @return The midiSaveDir variable.
  	 */
  	public String getMidiSaveDir() {
  		return midiSaveDir;
  	}
  
  	/**
  	 * Sets the midi file name.
  	 * 
  	 * @param midiFileName
  	 *            The String to set the file name to.
  	 */
  	public void setMidiFileName(String midiFileName) {
  		this.midiFileName = midiFileName;
  	}
  
  	/**
  	 * Sets the midi directory.
  	 * 
  	 * @param midiFileName
  	 *            The String to set the file directory to.
  	 */
  	public void setMidiSaveDir(String midiSaveDir) {
  		this.midiSaveDir = midiSaveDir;
  	}
  
  	/**
  	 * Checks if the sequenced is finished. If the sequence is finished, it is
  	 * faded out and closed.
  	 */
  	@Override
  	public void run() {
  		while (sequencer != null) {
  			if (sequencer.getTickPosition() >= sequencer.getTickLength()) {
  				fadeOut();
  			}
  		}
  	}
  
  	/**
  	 * Sets the volume of the midi that is playing.
  	 * 
  	 * @param volume
  	 *            The volume of the midi sound.
  	 * @return True or false.
  	 */
  	public boolean setVolume(double value) {
  		try {
  			Receiver receiver = MidiSystem.getReceiver();
  			ShortMessage volumeMessage = new ShortMessage();
  
  			for (int i = 0; i < 16; i++) {
  				volumeMessage.setMessage(ShortMessage.CONTROL_CHANGE, i, 7, (int) (value * 127.0));
  				receiver.send(volumeMessage, -1);
  			}
  			return true;
  		} catch (Exception e) {
  			e.printStackTrace();
  			return false;
  		}
  	}
  
  	/**
  	 * Fades the volume of the midi out. Stops the current midi playing.
  	 */
  	public void fadeOut() {
  		double volume = 1;
  		while (volume - 0.05 > 0 && setVolume(volume)) {
  			try {
  				Thread.sleep(150);
  			} catch (Exception exception) {
  			}
  			volume -= 0.025;
  		}
  		try {
  			if (synthesizer != null) {
  				synthesizer.close();
  				synthesizer = null;
  			}
  			if (sequencer != null) {
  				if (sequencer.isOpen()) {
  					sequencer.stop();
  				}
  				sequencer.close();
  			}
  		} catch (Exception exception) {
  		}
  	}
  
  	/**
  	 * Starts playing the midi.
  	 */
  	public void startMidi() {
  		String midiDir = getMidiFileName() + getMidiSaveDir();
  		new Thread(this);
  
  		try {
  			if (sequencer != null) {
  				fadeOut();
  			}
  			sequencer = null;
  			sequence = null;
  
  			File file = new File(midiDir);
  
  			if (file.exists()) {
  				sequence = MidiSystem.getSequence(file);
  			}
  			sequencer = MidiSystem.getSequencer();
  			sequencer.setSequence(sequence);
  			synthesizer = MidiSystem.getSynthesizer();
  			synthesizer.open();
  
  			if (synthesizer.getDefaultSoundbank() == null) {
  				sequencer.getTransmitter().setReceiver(MidiSystem.getReceiver());
  			} else {
  				sequencer.getTransmitter().setReceiver(synthesizer.getReceiver());
  			}
  			sequencer.open();
  			sequencer.start();
  		} catch (Exception exception) {
  			exception.printStackTrace();
  		}
  	}
  }