1 import java.awt.image.SampleModel;
\r
3 import FileOutputStream;
\r
6 * 11/19/04 1.0 moved to LGPL.
\r
7 * 29/01/00 Initial version. mdm@techie.com
\r
8 *-----------------------------------------------------------------------
\r
9 * This program is free software; you can redistribute it and/or modify
\r
10 * it under the terms of the GNU Library General Public License as published
\r
11 * by the Free Software Foundation; either version 2 of the License, or
\r
12 * (at your option) any later version.
\r
14 * This program is distributed in the hope that it will be useful,
\r
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
17 * GNU Library General Public License for more details.
\r
19 * You should have received a copy of the GNU Library General Public
\r
20 * License along with this program; if not, write to the Free Software
\r
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
\r
22 *----------------------------------------------------------------------
\r
26 * The <code>Player</code> class implements a simple player for playback of an
\r
27 * MPEG audio stream.
\r
29 * @author Mat McGowan
\r
33 // REVIEW: the audio device should not be opened until the
\r
34 // first MPEG audio frame has been decoded.
\r
36 public class Player {
\r
38 * The current frame number.
\r
41 private int frame = 0;
\r
44 * The MPEG audio bitstream.
\r
46 // private Bitstream bitstream;
\r
49 * The MPEG audio decoder.
\r
52 private Decoder decoder;
\r
55 * The AudioDevice the audio samples are written to.
\r
57 // private AudioDevice audio;
\r
60 * Has the player been closed?
\r
63 private boolean closed = false;
\r
66 * Has the player played back all frames from the stream?
\r
69 private boolean complete = false;
\r
71 private int lastPosition = 0;
\r
73 private long sampleNumber;
\r
76 * Creates a new <code>Player</code> instance.
\r
78 public Player() throws JavaLayerException {
\r
82 public Player(AudioDevice device) throws JavaLayerException {
\r
83 // bitstream = new Bitstream(stream);
\r
84 decoder = new Decoder();
\r
86 // if (device!=null)
\r
92 // FactoryRegistry r = FactoryRegistry.systemRegistry();
\r
93 // audio = r.createAudioDevice();
\r
96 device.open(decoder);
\r
99 public void play() throws JavaLayerException {
\r
100 play(Integer.MAX_VALUE);
\r
104 * Plays a number of MPEG audio frames.
\r
107 * The number of frames to play.
\r
108 * @return true if the last frame was played, or false if there are more
\r
112 public boolean play(int frames) throws JavaLayerException {
\r
113 boolean ret = true;
\r
115 // initialization before ssjava loop
\r
116 boolean init = true;
\r
117 Header h = BitstreamWrapper.readFrame();
\r
121 System.out.println("Gobble sentinel: +++");
\r
125 // SSJAVA: while (true) {
\r
126 // if (h == null) {
\r
129 // ret = decodeFrame(init, h);
\r
133 // h = BitstreamWrapper.readFrame();
\r
137 * if (!ret) { // last frame, ensure all data flushed to the audio device.
\r
138 * AudioDevice out = audio; if (out!=null) { out.flush(); synchronized
\r
139 * (this) { complete = (!closed); close(); } } }
\r
144 public boolean play2( Header h){
\r
146 SSJAVA: while (true) {
\r
150 ret = decodeFrame(true, h);
\r
154 h = BitstreamWrapper.readFrame();
\r
159 * Cloases this player. Any audio currently playing is stopped immediately.
\r
162 public synchronized void close() {
\r
164 * AudioDevice out = audio; if (out!=null) { closed = true; audio = null; //
\r
165 * this may fail, so ensure object state is set up before // calling this
\r
166 * method. out.close(); lastPosition = out.getPosition(); try {
\r
167 * bitstream.close(); } catch (BitstreamException ex) { } }
\r
172 * Returns the completed status of this player.
\r
174 * @return true if all available MPEG audio frames have been decoded, or false
\r
177 public synchronized boolean isComplete() {
\r
182 * Retrieves the position in milliseconds of the current audio sample being
\r
183 * played. This method delegates to the <code>
\r
184 * AudioDevice</code> that is used by this player to sound the decoded audio
\r
187 public int getPosition() {
\r
188 // int position = lastPosition;
\r
190 // AudioDevice out = audio;
\r
193 // position = out.getPosition();
\r
195 // return position;
\r
200 * Decodes a single frame.
\r
202 * @return true if there are no more frames to decode, false otherwise.
\r
205 protected boolean decodeFrame(boolean init, Header h) throws JavaLayerException {
\r
207 // AudioDevice out = audio;
\r
211 // Header h = bitstream.readFrame();
\r
217 // SampleBuffer output = (SampleBuffer) decoder.decodeFrame(h);
\r
218 decoder.decodeFrame(h);
\r
220 // DEBUG_OUTPUT_CHECKSUM();
\r
222 // synchronized (this)
\r
227 // out.write(output.getBuffer(), 0, output.getBufferLength());
\r
231 // bitstream.closeFrame();
\r
232 } catch (RuntimeException ex) {
\r
233 throw new JavaLayerException("Exception decoding audio frame", ex);
\r
236 * catch (IOException ex) {
\r
237 * System.out.println("exception decoding audio frame: "+ex); return false;
\r
238 * } catch (BitstreamException bitex) {
\r
239 * System.out.println("exception decoding audio frame: "+bitex); return
\r
240 * false; } catch (DecoderException decex) {
\r
241 * System.out.println("exception decoding audio frame: "+decex); return
\r
248 public void DEBUG_OUTPUT() {
\r
249 // it looks like there is left and right channel interleaved into the
\r
250 // output buffer, so only sample one channel (stride=2)
\r
251 short[] outbuf = SampleBufferWrapper.getBuffer();
\r
252 for (int i = 0; i < SampleBufferWrapper.getBufferLength(); i = i + 2) {
\r
253 System.out.println(sampleNumber + " " + outbuf[i]);
\r
259 public void DEBUG_OUTPUT_CHECKSUM() {
\r
262 short[] outbuf = SampleBufferWrapper.getBuffer();
\r
263 // short[] outbuf = output.getBuffer();
\r
264 TERMINATE: for (int i = 0; i < SampleBufferWrapper.getBufferLength(); i++) {
\r
265 // System.out.println(outbuf[i]);
\r
268 System.out.println(sum);
\r