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