b0f2356088df75a59dfb3aa96e022c5d92812c0e
[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 public class Player\r
36 {               \r
37         /**\r
38          * The current frame number. \r
39          */\r
40         private int frame = 0;\r
41         \r
42         /**\r
43          * The MPEG audio bitstream. \r
44          */\r
45         // javac blank final bug. \r
46         /*final*/ private Bitstream             bitstream;\r
47         \r
48         /**\r
49          * The MPEG audio decoder. \r
50          */\r
51         /*final*/ private Decoder               decoder; \r
52         \r
53         /**\r
54          * The AudioDevice the audio samples are written to. \r
55          */\r
56         //private AudioDevice   audio; \r
57         \r
58         /**\r
59          * Has the player been closed?\r
60          */\r
61         private boolean         closed = false;\r
62         \r
63         /**\r
64          * Has the player played back all frames from the stream?\r
65          */\r
66         private boolean         complete = false;\r
67 \r
68         private int                     lastPosition = 0;\r
69         \r
70         private Header header;\r
71         \r
72         /**\r
73          * Creates a new <code>Player</code> instance. \r
74          */\r
75         public Player(InputStream stream) throws JavaLayerException\r
76         {\r
77                 this(stream, null);     \r
78         }\r
79 \r
80 \r
81         public Player(InputStream stream, AudioDevice device) throws JavaLayerException\r
82         {\r
83                 bitstream = new Bitstream(stream);              \r
84                 decoder = new Decoder();\r
85                 \r
86                 // decoder initialization\r
87                 // taking out from ssjava loop \r
88                 header = bitstream.readFrame();  \r
89                 decoder.initialize(header, bitstream);\r
90                                 \r
91 //              if (device!=null)\r
92 //              {               \r
93 //                      audio = device;\r
94 //              }\r
95 //              else\r
96 //              {                       \r
97 //                      FactoryRegistry r = FactoryRegistry.systemRegistry();\r
98 //                      audio = r.createAudioDevice();\r
99 //              }\r
100                 \r
101                 device.open(decoder);\r
102         }\r
103         \r
104         \r
105         public void play() throws JavaLayerException\r
106         {\r
107                 play(Integer.MAX_VALUE);\r
108         }\r
109         \r
110         /**\r
111          * Plays a number of MPEG audio frames. \r
112          * \r
113          * @param frames        The number of frames to play. \r
114          * @return      true if the last frame was played, or false if there are\r
115          *                      more frames. \r
116          */\r
117         public boolean play(int frames) throws JavaLayerException\r
118         {\r
119                 boolean ret = true;\r
120                 \r
121              SSJAVA:\r
122                 while (frames-- > 0 && ret)\r
123                 {\r
124                         ret = decodeFrame();                    \r
125                 }\r
126                 /*\r
127                 if (!ret)\r
128                 {\r
129                         // last frame, ensure all data flushed to the audio device. \r
130                         AudioDevice out = audio;\r
131                         if (out!=null)\r
132                         {                               \r
133                                 out.flush();\r
134                                 synchronized (this)\r
135                                 {\r
136                                         complete = (!closed);\r
137                                         close();\r
138                                 }                               \r
139                         }\r
140                 }\r
141                 */\r
142                 return ret;\r
143         }\r
144                 \r
145         /**\r
146          * Cloases this player. Any audio currently playing is stopped\r
147          * immediately. \r
148          */\r
149         \r
150         public synchronized void close()\r
151         {               \r
152 /*\r
153                 AudioDevice out = audio;\r
154                 if (out!=null)\r
155                 { \r
156                         closed = true;\r
157                         audio = null;   \r
158                         // this may fail, so ensure object state is set up before\r
159                         // calling this method. \r
160                         out.close();\r
161                         lastPosition = out.getPosition();\r
162                         try\r
163                         {\r
164                                 bitstream.close();\r
165                         }\r
166                         catch (BitstreamException ex)\r
167                         {\r
168                         }\r
169                 }\r
170 */\r
171         }\r
172         \r
173         \r
174         /**\r
175          * Returns the completed status of this player.\r
176          * \r
177          * @return      true if all available MPEG audio frames have been\r
178          *                      decoded, or false otherwise. \r
179          */\r
180         public synchronized boolean isComplete()\r
181         {\r
182                 return complete;        \r
183         }\r
184                                 \r
185         /**\r
186          * Retrieves the position in milliseconds of the current audio\r
187          * sample being played. This method delegates to the <code>\r
188          * AudioDevice</code> that is used by this player to sound\r
189          * the decoded audio samples. \r
190          */\r
191         public int getPosition()\r
192         {\r
193                 //int position = lastPosition;\r
194                 \r
195                 //AudioDevice out = audio;              \r
196                 //if (out!=null)\r
197                 //{\r
198                 //      position = out.getPosition();   \r
199                 //}\r
200                 //return position;\r
201                 return 0;\r
202         }               \r
203         \r
204         /**\r
205          * Decodes a single frame.\r
206          * \r
207          * @return true if there are no more frames to decode, false otherwise.\r
208          */\r
209         protected boolean decodeFrame() throws JavaLayerException\r
210         {               \r
211                 try\r
212                 {\r
213                         //AudioDevice out = audio;\r
214                         //if (out==null)\r
215                         //      return false;\r
216 \r
217 //                      Header h = bitstream.readFrame();       \r
218 //                      \r
219 //                      if (h==null)\r
220 //                              return false;\r
221                                 \r
222                         // sample buffer set when decoder constructed\r
223                         SampleBuffer output = (SampleBuffer)decoder.decodeFrame(header, bitstream);\r
224                                                                                                                                                                                                                                                                                                         \r
225                         //synchronized (this)\r
226                         //{\r
227                         //      out = audio;\r
228                         //      if (out!=null)\r
229                         //      {                                       \r
230                         //              out.write(output.getBuffer(), 0, output.getBufferLength());\r
231                         //      }                               \r
232                         //}\r
233                                                                                                                                                         \r
234                         bitstream.closeFrame();\r
235                 }               \r
236                 catch (RuntimeException ex)\r
237                 {\r
238                         throw new JavaLayerException("Exception decoding audio frame", ex);\r
239                 }\r
240 /*\r
241                 catch (IOException ex)\r
242                 {\r
243                         System.out.println("exception decoding audio frame: "+ex);\r
244                         return false;   \r
245                 }\r
246                 catch (BitstreamException bitex)\r
247                 {\r
248                         System.out.println("exception decoding audio frame: "+bitex);\r
249                         return false;   \r
250                 }\r
251                 catch (DecoderException decex)\r
252                 {\r
253                         System.out.println("exception decoding audio frame: "+decex);\r
254                         return false;                           \r
255                 }\r
256 */              \r
257                 return true;\r
258         }\r
259         \r
260 }\r