3 * 11/19/04 1.0 moved to LGPL.
\r
4 * 29/01/00 Initial version. mdm@techie.com
\r
5 *-----------------------------------------------------------------------
\r
6 * This program is free software; you can redistribute it and/or modify
\r
7 * it under the terms of the GNU Library General Public License as published
\r
8 * by the Free Software Foundation; either version 2 of the License, or
\r
9 * (at your option) any later version.
\r
11 * This program is distributed in the hope that it will be useful,
\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 * GNU Library General Public License for more details.
\r
16 * You should have received a copy of the GNU Library General Public
\r
17 * License along with this program; if not, write to the Free Software
\r
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
\r
19 *----------------------------------------------------------------------
\r
25 * The <code>Player</code> class implements a simple player for playback
\r
26 * of an MPEG audio stream.
\r
28 * @author Mat McGowan
\r
32 // REVIEW: the audio device should not be opened until the
\r
33 // first MPEG audio frame has been decoded.
\r
34 @LATTICE("B<DE,DE<ST,DE<HE,HE<ST,ST<FR")
\r
38 * The current frame number.
\r
40 @LOC("FR") private int frame = 0;
\r
43 * The MPEG audio bitstream.
\r
45 // javac blank final bug.
\r
46 /*final*/ @LOC("ST") private Bitstream bitstream;
\r
49 * The MPEG audio decoder.
\r
51 /*final*/ @LOC("DE") private Decoder decoder;
\r
54 * The AudioDevice the audio samples are written to.
\r
56 //private AudioDevice audio;
\r
59 * Has the player been closed?
\r
61 @LOC("B") private boolean closed = false;
\r
64 * Has the player played back all frames from the stream?
\r
66 @LOC("B") private boolean complete = false;
\r
68 @LOC("B") private int lastPosition = 0;
\r
71 * Creates a new <code>Player</code> instance.
\r
73 public Player(InputStream stream) throws JavaLayerException
\r
75 this(stream, null);
\r
79 public Player(InputStream stream, AudioDevice device) throws JavaLayerException
\r
81 bitstream = new Bitstream(stream);
\r
82 decoder = new Decoder();
\r
84 // if (device!=null)
\r
90 // FactoryRegistry r = FactoryRegistry.systemRegistry();
\r
91 // audio = r.createAudioDevice();
\r
94 device.open(decoder);
\r
98 public void play() throws JavaLayerException
\r
100 play(Integer.MAX_VALUE);
\r
104 * Plays a number of MPEG audio frames.
\r
106 * @param frames The number of frames to play.
\r
107 * @return true if the last frame was played, or false if there are
\r
110 @LATTICE("IN<T,IN*,THISLOC=T")
\r
112 public boolean play(@LOC("IN") int frames) throws JavaLayerException
\r
114 @LOC("IN") boolean ret = true;
\r
118 while (frames-- > 0 && ret)
\r
120 System.out.println("DECODE");
\r
121 ret = decodeFrame();
\r
126 // last frame, ensure all data flushed to the audio device.
\r
127 AudioDevice out = audio;
\r
131 synchronized (this)
\r
133 complete = (!closed);
\r
143 * Cloases this player. Any audio currently playing is stopped
\r
147 public synchronized void close()
\r
150 AudioDevice out = audio;
\r
155 // this may fail, so ensure object state is set up before
\r
156 // calling this method.
\r
158 lastPosition = out.getPosition();
\r
163 catch (BitstreamException ex)
\r
172 * Returns the completed status of this player.
\r
174 * @return true if all available MPEG audio frames have been
\r
175 * decoded, or false otherwise.
\r
177 public synchronized boolean isComplete()
\r
183 * Retrieves the position in milliseconds of the current audio
\r
184 * sample being played. This method delegates to the <code>
\r
185 * AudioDevice</code> that is used by this player to sound
\r
186 * the decoded audio samples.
\r
188 public int getPosition()
\r
190 //int position = lastPosition;
\r
192 //AudioDevice out = audio;
\r
195 // position = out.getPosition();
\r
202 * Decodes a single frame.
\r
204 * @return true if there are no more frames to decode, false otherwise.
\r
206 @LATTICE("O<TH,THISLOC=TH")
\r
208 protected boolean decodeFrame() throws JavaLayerException
\r
212 //AudioDevice out = audio;
\r
216 Header h = bitstream.readFrame();
\r
221 // sample buffer set when decoder constructed
\r
222 @LOC("O") SampleBuffer output = (SampleBuffer)decoder.decodeFrame(h, bitstream);
\r
225 short[] outbuf = output.getBuffer();
\r
226 for (int i = 0; i < outbuf.length; i++) {
\r
227 // bw.write(outbuf[i]);
\r
228 System.out.println(outbuf[i]);
\r
232 //synchronized (this)
\r
237 // out.write(output.getBuffer(), 0, output.getBufferLength());
\r
241 bitstream.closeFrame();
\r
243 catch (RuntimeException ex)
\r
245 throw new JavaLayerException("Exception decoding audio frame", ex);
\r
248 catch (IOException ex)
\r
250 System.out.println("exception decoding audio frame: "+ex);
\r
253 catch (BitstreamException bitex)
\r
255 System.out.println("exception decoding audio frame: "+bitex);
\r
258 catch (DecoderException decex)
\r
260 System.out.println("exception decoding audio frame: "+decex);
\r