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