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