reformat benchmark source codes to meet the requirements of the annotation generation.
[IRC.git] / Robust / src / Benchmarks / SSJava / MP3DecoderInfer / Decoder.java
1 /*\r
2  * 11/19/04             1.0 moved to LGPL.\r
3  * 01/12/99             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  * The <code>Decoder</code> class encapsulates the details of decoding an MPEG\r
23  * audio frame.\r
24  * \r
25  * @author MDM\r
26  * @version 0.0.7 12/12/99\r
27  * @since 0.0.5\r
28  */\r
29 \r
30 public class Decoder implements DecoderErrors {\r
31 \r
32   static private final Params DEFAULT_PARAMS = new Params();\r
33 \r
34   /**\r
35    * The Bistream from which the MPEG audio frames are read.\r
36    */\r
37   //\r
38   // private Bitstream stream;\r
39 \r
40   /**\r
41    * The Obuffer instance that will receive the decoded PCM samples.\r
42    */\r
43   //\r
44   // private Obuffer output;\r
45 \r
46   /**\r
47    * Synthesis filter for the left channel.\r
48    */\r
49   //\r
50   // private SynthesisFilter filter1;\r
51 \r
52   /**\r
53    * Sythesis filter for the right channel.\r
54    */\r
55   //\r
56   // private SynthesisFilter filter2;\r
57 \r
58   /**\r
59    * The decoder used to decode layer III frames.\r
60    */\r
61 \r
62   private LayerIIIDecoder l3decoder;\r
63   //\r
64   // private LayerIIDecoder l2decoder;\r
65   //\r
66   // private LayerIDecoder l1decoder;\r
67 \r
68   private int outputFrequency;\r
69 \r
70   private int outputChannels;\r
71 \r
72   private Equalizer equalizer = new Equalizer();\r
73 \r
74   private Params params;\r
75 \r
76   private boolean initialized;\r
77 \r
78   /**\r
79    * Creates a new <code>Decoder</code> instance with default parameters.\r
80    */\r
81 \r
82   public Decoder() {\r
83     this(null);\r
84   }\r
85 \r
86   /**\r
87    * Creates a new <code>Decoder</code> instance with default parameters.\r
88    * \r
89    * @param params\r
90    *          The <code>Params</code> instance that describes the customizable\r
91    *          aspects of the decoder.\r
92    */\r
93   public Decoder(@DELEGATE Params params0) {\r
94 \r
95     if (params0 == null) {\r
96       params0 = getDefaultParams();\r
97     }\r
98 \r
99     params = params0;\r
100 \r
101     Equalizer eq = params.getInitialEqualizerSettings();\r
102     if (eq != null) {\r
103       equalizer.setFrom(eq);\r
104     }\r
105   }\r
106 \r
107   static public Params getDefaultParams() {\r
108     return (Params) DEFAULT_PARAMS.clone();\r
109   }\r
110 \r
111   // public void setEqualizer(Equalizer eq) {\r
112   // if (eq == null)\r
113   // eq = Equalizer.PASS_THRU_EQ;\r
114   //\r
115   // equalizer.setFrom(eq);\r
116   //\r
117   // float[] factors = equalizer.getBandFactors();\r
118   //\r
119   // if (filter1 != null)\r
120   // filter1.setEQ(factors);\r
121   //\r
122   // if (filter2 != null)\r
123   // filter2.setEQ(factors);\r
124   // }\r
125 \r
126   public void init(Header header) {\r
127     float scalefactor = 32700.0f;\r
128 \r
129     int mode = header.mode();\r
130     int layer = header.layer();\r
131     int channels = mode == Header.SINGLE_CHANNEL ? 1 : 2;\r
132 \r
133     // set up output buffer if not set up by client.\r
134     // if (output == null)\r
135     // output = new SampleBuffer(header.frequency(), channels);\r
136     SampleBufferWrapper.init(header.frequency(), channels);\r
137 \r
138     float[] factors = equalizer.getBandFactors();\r
139     SynthesisFilter filter1 = new SynthesisFilter(0, scalefactor, factors);\r
140 \r
141     // REVIEW: allow mono output for stereo\r
142     SynthesisFilter filter2 = null;\r
143     if (channels == 2) {\r
144       filter2 = new SynthesisFilter(1, scalefactor, factors);\r
145     }\r
146 \r
147     outputChannels = channels;\r
148     outputFrequency = header.frequency();\r
149 \r
150     l3decoder = new LayerIIIDecoder(header, filter1, filter2, OutputChannels.BOTH_CHANNELS);\r
151 \r
152   }\r
153 \r
154   /**\r
155    * Decodes one frame from an MPEG audio bitstream.\r
156    * \r
157    * @param header\r
158    *          The header describing the frame to decode.\r
159    * @param bitstream\r
160    *          The bistream that provides the bits for te body of the frame.\r
161    * \r
162    * @return A SampleBuffer containing the decoded samples.\r
163    */\r
164 \r
165   public void decodeFrame(Header header) throws DecoderException {\r
166 \r
167     SampleBufferWrapper.clear_buffer();\r
168     l3decoder.decode(header);\r
169     // SampleBufferWrapper.getOutput().write_buffer(1);\r
170 \r
171   }\r
172 \r
173   /**\r
174    * Changes the output buffer. This will take effect the next time\r
175    * decodeFrame() is called.\r
176    */\r
177   // public void setOutputBuffer(Obuffer out) {\r
178   // output = out;\r
179   // }\r
180 \r
181   /**\r
182    * Retrieves the sample frequency of the PCM samples output by this decoder.\r
183    * This typically corresponds to the sample rate encoded in the MPEG audio\r
184    * stream.\r
185    * \r
186    * @param the\r
187    *          sample rate (in Hz) of the samples written to the output buffer\r
188    *          when decoding.\r
189    */\r
190   public int getOutputFrequency() {\r
191     return outputFrequency;\r
192   }\r
193 \r
194   /**\r
195    * Retrieves the number of channels of PCM samples output by this decoder.\r
196    * This usually corresponds to the number of channels in the MPEG audio\r
197    * stream, although it may differ.\r
198    * \r
199    * @return The number of output channels in the decoded samples: 1 for mono,\r
200    *         or 2 for stereo.\r
201    * \r
202    */\r
203   public int getOutputChannels() {\r
204     return outputChannels;\r
205   }\r
206 \r
207   /**\r
208    * Retrieves the maximum number of samples that will be written to the output\r
209    * buffer when one frame is decoded. This can be used to help calculate the\r
210    * size of other buffers whose size is based upon the number of samples\r
211    * written to the output buffer. NB: this is an upper bound and fewer samples\r
212    * may actually be written, depending upon the sample rate and number of\r
213    * channels.\r
214    * \r
215    * @return The maximum number of samples that are written to the output buffer\r
216    *         when decoding a single frame of MPEG audio.\r
217    */\r
218   public int getOutputBlockSize() {\r
219     return Obuffer.OBUFFERSIZE;\r
220   }\r
221 \r
222   protected DecoderException newDecoderException(int errorcode) {\r
223     return new DecoderException(errorcode, null);\r
224   }\r
225 \r
226   protected DecoderException newDecoderException(int errorcode, Throwable throwable) {\r
227     return new DecoderException(errorcode, throwable);\r
228   }\r
229 }\r
230 \r
231 /**\r
232  * The <code>Params</code> class presents the customizable aspects of the\r
233  * decoder.\r
234  * <p>\r
235  * Instances of this class are not thread safe.\r
236  */\r
237 public class Params implements Cloneable {\r
238 \r
239   // private OutputChannels outputChannels = OutputChannels.BOTH;\r
240   private OutputChannels outputChannels = new OutputChannels(0);\r
241 \r
242   private Equalizer equalizer = new Equalizer();\r
243 \r
244   public Params() {\r
245   }\r
246 \r
247   public Object clone() {\r
248     // TODO: need to have better clone method\r
249     Params clone = new Params();\r
250     clone.outputChannels = new OutputChannels(outputChannels.getChannelsOutputCode());\r
251     clone.equalizer = new Equalizer();\r
252     return clone;\r
253     // try\r
254     // {\r
255     // return super.clone();\r
256     // }\r
257     // catch (CloneNotSupportedException ex)\r
258     // {\r
259     // throw new InternalError(this+": "+ex);\r
260     // }\r
261   }\r
262 \r
263   public void setOutputChannels(OutputChannels out) {\r
264     if (out == null)\r
265       throw new NullPointerException("out");\r
266 \r
267     outputChannels = out;\r
268   }\r
269 \r
270   public OutputChannels getOutputChannels() {\r
271     return outputChannels;\r
272   }\r
273 \r
274   /**\r
275    * Retrieves the equalizer settings that the decoder's equalizer will be\r
276    * initialized from.\r
277    * <p>\r
278    * The <code>Equalizer</code> instance returned cannot be changed in real time\r
279    * to affect the decoder output as it is used only to initialize the decoders\r
280    * EQ settings. To affect the decoder's output in realtime, use the Equalizer\r
281    * returned from the getEqualizer() method on the decoder.\r
282    * \r
283    * @return The <code>Equalizer</code> used to initialize the EQ settings of\r
284    *         the decoder.\r
285    */\r
286   public Equalizer getInitialEqualizerSettings() {\r
287     return equalizer;\r
288   }\r
289 \r
290 }