1 import java.awt.image.SampleModel;
3 import FileOutputStream;
6 * 11/19/04 1.0 moved to LGPL.
7 * 29/01/00 Initial version. mdm@techie.com
8 *-----------------------------------------------------------------------
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Library General Public License as published
11 * by the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *----------------------------------------------------------------------
26 * The <code>Player</code> class implements a simple player for playback of an
33 // REVIEW: the audio device should not be opened until the
34 // first MPEG audio frame has been decoded.
35 @LATTICE("B<DE,DE<ST,DE<HE,HE<ST,ST<FR")
38 * The current frame number.
41 private int frame = 0;
44 * The MPEG audio bitstream.
46 // private Bitstream bitstream;
49 * The MPEG audio decoder.
52 private Decoder decoder;
55 * The AudioDevice the audio samples are written to.
57 // private AudioDevice audio;
60 * Has the player been closed?
63 private boolean closed = false;
66 * Has the player played back all frames from the stream?
69 private boolean complete = false;
72 private int lastPosition = 0;
75 private long sampleNumber;
78 * Creates a new <code>Player</code> instance.
80 public Player() throws JavaLayerException {
84 public Player(AudioDevice device) throws JavaLayerException {
85 // bitstream = new Bitstream(stream);
86 decoder = new Decoder();
94 // FactoryRegistry r = FactoryRegistry.systemRegistry();
95 // audio = r.createAudioDevice();
101 public void play() throws JavaLayerException {
102 play(Integer.MAX_VALUE);
106 * Plays a number of MPEG audio frames.
109 * The number of frames to play.
110 * @return true if the last frame was played, or false if there are more
113 @LATTICE("OUT<THIS,THIS<IN,IN*,THISLOC=THIS")
115 public boolean play(@LOC("IN") int frames) throws JavaLayerException {
116 @LOC("OUT") boolean ret = true;
118 // initialization before ssjava loop
119 @LOC("THIS,Player.FR") boolean init = true;
120 @LOC("THIS,Player.ST") Header h = BitstreamWrapper.readFrame();
124 System.out.println("Gobble sentinel: +++");
126 // @LOC("IN") int count = 0;
127 SSJAVA: while (true) {
131 ret = decodeFrame(init, h);
135 h = BitstreamWrapper.readFrame();
139 * if (!ret) { // last frame, ensure all data flushed to the audio device.
140 * AudioDevice out = audio; if (out!=null) { out.flush(); synchronized
141 * (this) { complete = (!closed); close(); } } }
147 * Cloases this player. Any audio currently playing is stopped immediately.
150 public synchronized void close() {
152 * AudioDevice out = audio; if (out!=null) { closed = true; audio = null; //
153 * this may fail, so ensure object state is set up before // calling this
154 * method. out.close(); lastPosition = out.getPosition(); try {
155 * bitstream.close(); } catch (BitstreamException ex) { } }
160 * Returns the completed status of this player.
162 * @return true if all available MPEG audio frames have been decoded, or false
165 public synchronized boolean isComplete() {
170 * Retrieves the position in milliseconds of the current audio sample being
171 * played. This method delegates to the <code>
172 * AudioDevice</code> that is used by this player to sound the decoded audio
175 public int getPosition() {
176 // int position = lastPosition;
178 // AudioDevice out = audio;
181 // position = out.getPosition();
188 * Decodes a single frame.
190 * @return true if there are no more frames to decode, false otherwise.
192 @LATTICE("C<THIS,O<THIS,THIS<IN,C*,THISLOC=THIS,RETURNLOC=O,GLOBALLOC=THIS")
193 protected boolean decodeFrame(@LOC("THIS,Player.FR") boolean init, @LOC("THIS,Player.ST") Header h)
194 throws JavaLayerException {
196 // AudioDevice out = audio;
200 // Header h = bitstream.readFrame();
206 // @LOC("O") SampleBuffer output = (SampleBuffer) decoder.decodeFrame(h);
207 decoder.decodeFrame(h);
209 // DEBUG_OUTPUT_CHECKSUM();
211 // synchronized (this)
216 // out.write(output.getBuffer(), 0, output.getBufferLength());
220 // bitstream.closeFrame();
221 } catch (RuntimeException ex) {
222 throw new JavaLayerException("Exception decoding audio frame", ex);
225 * catch (IOException ex) {
226 * System.out.println("exception decoding audio frame: "+ex); return false;
227 * } catch (BitstreamException bitex) {
228 * System.out.println("exception decoding audio frame: "+bitex); return
229 * false; } catch (DecoderException decex) {
230 * System.out.println("exception decoding audio frame: "+decex); return
237 public void DEBUG_OUTPUT() {
238 // it looks like there is left and right channel interleaved into the
239 // output buffer, so only sample one channel (stride=2)
240 short[] outbuf = SampleBufferWrapper.getBuffer();
241 for (int i = 0; i < SampleBufferWrapper.getBufferLength(); i = i + 2) {
242 System.out.println(sampleNumber + " " + outbuf[i]);
248 public void DEBUG_OUTPUT_CHECKSUM() {
250 @LOC("C") int sum = 0;
251 @LOC("C") short[] outbuf = SampleBufferWrapper.getBuffer();
252 // short[] outbuf = output.getBuffer();
253 TERMINATE: for (@LOC("C") int i = 0; i < SampleBufferWrapper.getBufferLength(); i++) {
254 // System.out.println(outbuf[i]);
257 System.out.println(sum);