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