3d59e83c1b037e37714b7e01e10b7d9155929f6e
[IRC.git] / Robust / src / Tests / ssJava / mp3decoder / Player.java
1 import FileOutputStream;\r
2 \r
3 /*\r
4  * 11/19/04             1.0 moved to LGPL.\r
5  * 29/01/00             Initial version. mdm@techie.com\r
6  *-----------------------------------------------------------------------\r
7  *   This program is free software; you can redistribute it and/or modify\r
8  *   it under the terms of the GNU Library General Public License as published\r
9  *   by the Free Software Foundation; either version 2 of the License, or\r
10  *   (at your option) any later version.\r
11  *\r
12  *   This program is distributed in the hope that it will be useful,\r
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15  *   GNU Library General Public License for more details.\r
16  *\r
17  *   You should have received a copy of the GNU Library General Public\r
18  *   License along with this program; if not, write to the Free Software\r
19  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
20  *----------------------------------------------------------------------\r
21  */\r
22 \r
23 /**\r
24  * The <code>Player</code> class implements a simple player for playback of an\r
25  * MPEG audio stream.\r
26  * \r
27  * @author Mat McGowan\r
28  * @since 0.0.8\r
29  */\r
30 \r
31 // REVIEW: the audio device should not be opened until the\r
32 // first MPEG audio frame has been decoded.\r
33 @LATTICE("B<DE,DE<ST,DE<HE,HE<ST,ST<FR")\r
34 public class Player {\r
35   /**\r
36    * The current frame number.\r
37    */\r
38   @LOC("FR")\r
39   private int frame = 0;\r
40 \r
41   /**\r
42    * The MPEG audio bitstream.\r
43    */\r
44   // javac blank final bug.\r
45   /* final */@LOC("ST")\r
46   private Bitstream bitstream;\r
47 \r
48   /**\r
49    * The MPEG audio decoder.\r
50    */\r
51   /* final */@LOC("DE")\r
52   private Decoder decoder;\r
53 \r
54   /**\r
55    * The AudioDevice the audio samples are written to.\r
56    */\r
57   // private AudioDevice audio;\r
58 \r
59   /**\r
60    * Has the player been closed?\r
61    */\r
62   @LOC("B")\r
63   private boolean closed = false;\r
64 \r
65   /**\r
66    * Has the player played back all frames from the stream?\r
67    */\r
68   @LOC("B")\r
69   private boolean complete = false;\r
70 \r
71   @LOC("B")\r
72   private int lastPosition = 0;\r
73 \r
74   /**\r
75    * Creates a new <code>Player</code> instance.\r
76    */\r
77   public Player(InputStream stream) throws JavaLayerException {\r
78     this(stream, null);\r
79   }\r
80 \r
81   public Player(InputStream stream, AudioDevice device) throws JavaLayerException {\r
82     bitstream = new Bitstream(stream);\r
83     decoder = new Decoder();\r
84 \r
85     // if (device!=null)\r
86     // {\r
87     // audio = device;\r
88     // }\r
89     // else\r
90     // {\r
91     // FactoryRegistry r = FactoryRegistry.systemRegistry();\r
92     // audio = r.createAudioDevice();\r
93     // }\r
94 \r
95     device.open(decoder);\r
96   }\r
97 \r
98   public void play() throws JavaLayerException {\r
99     play(Integer.MAX_VALUE);\r
100   }\r
101 \r
102   /**\r
103    * Plays a number of MPEG audio frames.\r
104    * \r
105    * @param frames\r
106    *          The number of frames to play.\r
107    * @return true if the last frame was played, or false if there are more\r
108    *         frames.\r
109    */\r
110   @LATTICE("IN<T,IN*,THISLOC=T")\r
111   @RETURNLOC("IN")\r
112   public boolean play(@LOC("IN") int frames) throws JavaLayerException {\r
113     @LOC("IN") boolean ret = true;\r
114 \r
115     // FileOutputStream fos = new FileOutputStream("output.txt");\r
116 \r
117     int count = 0;\r
118     SSJAVA: while (frames-- > 0 && ret) {\r
119       ret = decodeFrame();\r
120     }\r
121 \r
122     // fos.flush();\r
123     // fos.close();\r
124     /*\r
125      * if (!ret) { // last frame, ensure all data flushed to the audio device.\r
126      * AudioDevice out = audio; if (out!=null) { out.flush(); synchronized\r
127      * (this) { complete = (!closed); close(); } } }\r
128      */\r
129     return ret;\r
130   }\r
131 \r
132   /**\r
133    * Cloases this player. Any audio currently playing is stopped immediately.\r
134    */\r
135 \r
136   public synchronized void close() {\r
137     /*\r
138      * AudioDevice out = audio; if (out!=null) { closed = true; audio = null; //\r
139      * this may fail, so ensure object state is set up before // calling this\r
140      * method. out.close(); lastPosition = out.getPosition(); try {\r
141      * bitstream.close(); } catch (BitstreamException ex) { } }\r
142      */\r
143   }\r
144 \r
145   /**\r
146    * Returns the completed status of this player.\r
147    * \r
148    * @return true if all available MPEG audio frames have been decoded, or false\r
149    *         otherwise.\r
150    */\r
151   public synchronized boolean isComplete() {\r
152     return complete;\r
153   }\r
154 \r
155   /**\r
156    * Retrieves the position in milliseconds of the current audio sample being\r
157    * played. This method delegates to the <code>\r
158    * AudioDevice</code> that is used by this player to sound the decoded audio\r
159    * samples.\r
160    */\r
161   public int getPosition() {\r
162     // int position = lastPosition;\r
163 \r
164     // AudioDevice out = audio;\r
165     // if (out!=null)\r
166     // {\r
167     // position = out.getPosition();\r
168     // }\r
169     // return position;\r
170     return 0;\r
171   }\r
172 \r
173   /**\r
174    * Decodes a single frame.\r
175    * \r
176    * @return true if there are no more frames to decode, false otherwise.\r
177    */\r
178   @LATTICE("O<TH,THISLOC=TH")\r
179   @RETURNLOC("O")\r
180   protected boolean decodeFrame() throws JavaLayerException {\r
181     try {\r
182       // AudioDevice out = audio;\r
183       // if (out==null)\r
184       // return false;\r
185 \r
186       Header h = bitstream.readFrame();\r
187 \r
188       if (h == null)\r
189         return false;\r
190 \r
191       // eom debug\r
192       // System.out.println("header framesize=" + h.framesize);\r
193       // System.out.println("br total="+h.getBitReserve().hsstell());\r
194       //\r
195 \r
196       // sample buffer set when decoder constructed\r
197       @LOC("O") SampleBuffer output = (SampleBuffer) decoder.decodeFrame(h, bitstream);\r
198 \r
199       // eom debug\r
200       int sum=0;\r
201       short[] outbuf = output.getBuffer();\r
202       for (int i = 0; i < output.getBufferLength(); i++) {\r
203 //        System.out.println(outbuf[i]);\r
204         sum+=outbuf[i];\r
205       }\r
206       System.out.println(sum);\r
207       //\r
208 \r
209       // synchronized (this)\r
210       // {\r
211       // out = audio;\r
212       // if (out!=null)\r
213       // {\r
214       // out.write(output.getBuffer(), 0, output.getBufferLength());\r
215       // }\r
216       // }\r
217 \r
218       // bitstream.closeFrame();\r
219     } catch (RuntimeException ex) {\r
220       throw new JavaLayerException("Exception decoding audio frame", ex);\r
221     }\r
222     /*\r
223      * catch (IOException ex) {\r
224      * System.out.println("exception decoding audio frame: "+ex); return false;\r
225      * } catch (BitstreamException bitex) {\r
226      * System.out.println("exception decoding audio frame: "+bitex); return\r
227      * false; } catch (DecoderException decex) {\r
228      * System.out.println("exception decoding audio frame: "+decex); return\r
229      * false; }\r
230      */\r
231     return true;\r
232   }\r
233 \r
234 }\r