View Javadoc

1   /*
2    *  MicroEmulator
3    *  Copyright (C) 2006 John Blackmon
4    *
5    *  This library is free software; you can redistribute it and/or
6    *  modify it under the terms of the GNU Lesser General Public
7    *  License as published by the Free Software Foundation; either
8    *  version 2.1 of the License, or (at your option) any later version.
9    *
10   *  This library is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   *  Lesser General Public License for more details.
14   *
15   *  You should have received a copy of the GNU Lesser General Public
16   *  License along with this library; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  
20  package javax.microedition.media;
21  
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.util.Iterator;
25  import java.util.Vector;
26  
27  import javax.sound.midi.InvalidMidiDataException;
28  import javax.sound.midi.MetaEventListener;
29  import javax.sound.midi.MetaMessage;
30  import javax.sound.midi.MidiSystem;
31  import javax.sound.midi.MidiUnavailableException;
32  import javax.sound.midi.Receiver;
33  import javax.sound.midi.Sequence;
34  import javax.sound.midi.Sequencer;
35  import javax.sound.midi.Synthesizer;
36  import javax.sound.midi.Transmitter;
37  
38  class MidiAudioPlayer implements Player, MetaEventListener 
39  {
40  	private Sequence  sequence = null;             // The contents of a MIDI file
41  	private Sequencer sequencer = null;            // We play MIDI Sequences with a Sequencer
42  	private Vector    vListeners = null;           // All PlayerListeners for this audio
43  	private int       iLoopCount = 1;
44  	
45  	public boolean open( InputStream stream, String type ) 
46  	{
47  		try 
48  	    {
49      		// First, get a Sequencer to play sequences of MIDI events
50      		//That is, to send events to a Synthesizer at the right time.
51      		sequencer = MidiSystem.getSequencer( ); // Used to play sequences
52      		sequencer.open(); // Turn it on.
53      		//Get a Synthesizer for the Sequencer to send notes to
54      		Synthesizer synth = MidiSystem.getSynthesizer( );
55      		synth.open( ); // acquire whatever resources it needs
56      		//The Sequencer obtained above may be connected to a Synthesizer
57      		//by default, or it may not. Therefore, we explicitly connect it.
58      		Transmitter transmitter = sequencer.getTransmitter( );
59      		Receiver receiver = synth.getReceiver( );
60      		transmitter.setReceiver(receiver);
61      		//Read the sequence from the file and tell the sequencer about it
62      		sequence = MidiSystem.getSequence( stream );
63      		sequencer.setSequence(sequence);
64  	    } 
65  	    catch( IOException e ){ e.printStackTrace(); }
66  	    catch( MidiUnavailableException e ){ e.printStackTrace(); }
67  	    catch( InvalidMidiDataException e ){ e.printStackTrace(); }
68  		return false;
69  	}
70  
71  	protected void dispose() 
72  	{
73          close();
74  	}
75  	
76  	public void addPlayerListener(PlayerListener playerListener) 
77  	{
78  		if( vListeners == null )
79  			vListeners = new Vector();
80  		vListeners.add( playerListener );
81  	}
82  
83  	public void close() 
84  	{
85  		Manager.mediaDone( this );
86  		if( sequencer != null )
87  			sequencer.close();
88  	}
89  
90  	public void deallocate() {
91  	}
92  
93  	public String getContentType() {
94  		return "audio/midi";
95  	}
96  
97  	public long getDuration() {
98  		return 0;
99  	}
100 
101 	public long getMediaTime() 
102 	{
103 		if( sequencer != null )
104 			return sequencer.getMicrosecondPosition();
105 		return 0;
106 	}
107 
108 	public int getState() {
109 		// TODO Auto-generated method stub
110 		return 0;
111 	}
112 
113 	public void prefetch() throws MediaException {
114 		// TODO Auto-generated method stub
115 
116 	}
117 
118 	public void realize() throws MediaException {
119 		// TODO Auto-generated method stub
120 
121 	}
122 
123 	public void removePlayerListener(PlayerListener playerListener) 
124 	{
125 	   if( vListeners == null )
126 		   return;
127 	   for( Iterator it = vListeners.iterator (); it.hasNext (); ) 
128 	   {
129 		    PlayerListener listener = (PlayerListener) it.next ();
130 		    if( listener == playerListener )
131 		    {
132 		    	vListeners.remove( listener );
133 		    	break;
134 	   		}
135 	   }
136 	}
137 
138 	public void setLoopCount(int count) 
139 	{
140 		iLoopCount = count;
141 	}
142 
143 	public long setMediaTime(long now) throws MediaException {
144 		if( sequencer != null )
145 			sequencer.setMicrosecondPosition( now );
146 		return now;
147 	}
148 
149 	public void start() throws MediaException {
150 		if( sequencer != null )
151 		{
152 			sequencer.addMetaEventListener( this );
153 			sequencer.start();
154 		}
155 	}
156 
157 	public void stop() throws MediaException {
158 		if( sequencer != null )
159 			sequencer.stop();
160 	}
161 
162 	public Control getControl(String controlType) {
163 		// TODO Auto-generated method stub
164 		return null;
165 	}
166 
167 	public Control[] getControls() {
168 		// TODO Auto-generated method stub
169 		return null;
170 	}
171 
172     public void meta( MetaMessage event )
173     {
174         if (event.getType() == 47) //End of Track type
175         {
176         	iLoopCount--;
177         	if( iLoopCount > 0 )
178         	{
179         		sequencer.setMicrosecondPosition( 0 );
180         		try{ start(); } 
181         		catch( MediaException e ) { e.printStackTrace(); }
182         	}
183         	else
184         	{
185     			close();
186     			if( vListeners != null )
187     			{
188     				for( Iterator it = vListeners.iterator (); it.hasNext (); ) 
189     				{
190     				    PlayerListener listener = (PlayerListener) it.next ();
191     				    listener.playerUpdate( this, PlayerListener.END_OF_MEDIA, null );
192     				}
193     			}
194         	}
195         }
196     }
197 
198 }