001: /*
002: * Copyright (c) 2000 Silvere Martin-Michiellot All Rights Reserved.
003: *
004: * Silvere Martin-Michiellot grants you ("Licensee") a non-exclusive,
005: * royalty free, license to use, modify and redistribute this
006: * software in source and binary code form,
007: * provided that i) this copyright notice and license appear on all copies of
008: * the software; and ii) Licensee does not utilize the software in a manner
009: * which is disparaging to Silvere Martin-Michiellot.
010: *
011: * This software is provided "AS IS," without a warranty of any kind. ALL
012: * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
013: * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
014: * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. Silvere Martin-Michiellot
015: * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
016: * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
017: * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
018: * Silvere Martin-Michiellot OR ITS LICENSORS BE LIABLE
019: * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
020: * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
021: * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
022: * OR INABILITY TO USE SOFTWARE, EVEN IF Silvere Martin-Michiellot HAS BEEN
023: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
024: *
025: * This software is not designed or intended for use in on-line control of
026: * aircraft, air traffic, aircraft navigation or aircraft communications; or in
027: * the design, construction, operation or maintenance of any nuclear
028: * facility. Licensee represents and warrants that it will not use or
029: * redistribute the Software for such purposes.
030: *
031: */
032:
033: package com.db.media.audio;
034:
035: // This code is repackaged after the code from Florian Bomers & Matthias Pfisterer from JavaSound Examples
036: // Site http://www.jsresources.org/examples/
037: // Email tritonus-user@lists.sourceforge.net
038:
039: import java.io.*;
040: import javax.sound.midi.*;
041:
042: //Plays a single MIDI file.
043:
044: public class SimpleMidiPlayer {
045:
046: private static Sequencer sequencer = null;
047: private static Synthesizer synthesizer = null;
048:
049: public static void main(String[] args) {
050:
051: if (args.length == 0 || args[0].equals("-h")) {
052: printUsageAndExit();
053: }
054:
055: String strFilename = args[0];
056: File midiFile = new File(strFilename);
057:
058: Sequence sequence = null;
059: try {
060: sequence = MidiSystem.getSequence(midiFile);
061: } catch (Exception e) {
062: e.printStackTrace();
063: System.exit(1);
064: }
065:
066: try {
067: sequencer = MidiSystem.getSequencer();
068: } catch (MidiUnavailableException e) {
069: e.printStackTrace();
070: System.exit(1);
071: }
072: if (sequencer == null) {
073: System.out
074: .println("SimpleMidiPlayer can't get a Sequencer");
075: System.exit(1);
076: }
077:
078: /*
079: * There is a bug in the Sun jdk1.3.
080: * It prevents correct termination of the VM.
081: * So we have to exit ourselves.
082: * To accomplish this, we register a Listener to the Sequencer.
083: * It is called when there are "meta" events. Meta event
084: * 47 is end of track.
085: *
086: * Thanks to Espen Riskedal for finding this trick.
087: */
088: sequencer.addMetaEventListener(new MetaEventListener() {
089: public void meta(MetaMessage event) {
090: if (event.getType() == 47) {
091: sequencer.close();
092: if (synthesizer != null) {
093: synthesizer.close();
094: }
095: System.exit(0);
096: }
097: }
098: });
099:
100: try {
101: sequencer.open();
102: } catch (MidiUnavailableException e) {
103: e.printStackTrace();
104: System.exit(1);
105: }
106:
107: try {
108: sequencer.setSequence(sequence);
109: } catch (InvalidMidiDataException e) {
110: e.printStackTrace();
111: System.exit(1);
112: }
113:
114: /*
115: * Now, we set up the destinations the Sequence should be
116: * played on. Here, we try to use the default
117: * synthesizer. With some Java Sound implementations
118: * (Sun jdk1.3 and others derived from this codebase),
119: * the default sequencer and the default synthesizer
120: * are combined in one object. We test for this
121: * condition, and if it's true, nothing more has to
122: * be done. With other implementations (namely Tritonus),
123: * sequencers and synthesizers are always seperate
124: * objects. In this case, we have to set up a link
125: * between the two objects manually.
126: *
127: * By the way, you should never rely on sequencers
128: * being synthesizers, too; this is a highly non-
129: * portable programming style. You should be able to
130: * rely on the other case working. Alas, it is only
131: * partly true for the Sun jdk1.3.
132: */
133: if (!(sequencer instanceof Synthesizer)) {
134: try {
135: synthesizer = MidiSystem.getSynthesizer();
136: synthesizer.open();
137: Receiver synthReceiver = synthesizer.getReceiver();
138: Transmitter seqTransmitter = sequencer.getTransmitter();
139: seqTransmitter.setReceiver(synthReceiver);
140: } catch (MidiUnavailableException e) {
141: e.printStackTrace();
142: }
143: }
144:
145: sequencer.start();
146:
147: }
148:
149: private static void printUsageAndExit() {
150:
151: System.out.println("SimpleMidiPlayer: usage:");
152: System.out.println("\tjava SimpleMidiPlayer <midifile>");
153: System.exit(1);
154:
155: }
156:
157: }
|