changes: LayerIDecoder and LayerIIDecoder pass the flow-down rule checking
[IRC.git] / Robust / src / Tests / ssJava / mp3decoder / LayerIDecoder.java
1 /*
2  * 09/26/08     throw exception on subbband alloc error: Christopher G. Jennings (cjennings@acm.org)
3  * 
4  * 11/19/04             1.0 moved to LGPL.
5  * 
6  * 12/12/99             Initial version. Adapted from javalayer.java
7  *                              and Subband*.java. mdm@techie.com
8  *
9  * 02/28/99             Initial version : javalayer.java by E.B
10  *-----------------------------------------------------------------------
11  *   This program is free software; you can redistribute it and/or modify
12  *   it under the terms of the GNU Library General Public License as published
13  *   by the Free Software Foundation; either version 2 of the License, or
14  *   (at your option) any later version.
15  *
16  *   This program is distributed in the hope that it will be useful,
17  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *   GNU Library General Public License for more details.
20  *
21  *   You should have received a copy of the GNU Library General Public
22  *   License along with this program; if not, write to the Free Software
23  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  *----------------------------------------------------------------------
25  */
26
27 /**
28  * Implements decoding of MPEG Audio Layer I frames.
29  */
30 @LATTICE("SB<H,H<SH,SH*,SB*")
31 @METHODDEFAULT("MODE<THIS,THIS<C,C<IN,THISLOC=THIS,C*")
32 class LayerIDecoder implements FrameDecoder {
33
34   @LOC("H")
35   protected Bitstream stream;
36   @LOC("SH")
37   protected Header header;
38   @LOC("H")
39   protected SynthesisFilter filter1;
40   @LOC("H")
41   protected SynthesisFilter filter2;
42   @LOC("H")
43   protected Obuffer buffer;
44   @LOC("H")
45   protected int which_channels;
46   @LOC("SH")
47   protected int mode;
48
49   @LOC("SB")
50   protected int num_subbands;
51   @LOC("SB")
52   protected Subband[] subbands;
53
54   @LOC("H")
55   protected Crc16 crc = null; // new Crc16[1] to enable CRC checking.
56
57   public LayerIDecoder() {
58     crc = new Crc16();
59   }
60
61   public void create(@LOC("IN") Bitstream stream0, @LOC("IN") Header header0,
62       @LOC("IN") SynthesisFilter filtera, @LOC("IN") SynthesisFilter filterb,
63       @LOC("IN") Obuffer buffer0, @LOC("IN") int which_ch0) {
64     stream = stream0;
65     header = header0;
66     filter1 = filtera;
67     filter2 = filterb;
68     buffer = buffer0;
69     which_channels = which_ch0;
70
71   }
72
73   public void decodeFrame() throws DecoderException {
74
75     num_subbands = header.number_of_subbands();
76     subbands = new Subband[32];
77     mode = header.mode();
78
79     createSubbands();
80
81     readAllocation();
82     readScaleFactorSelection();
83
84     if ((crc != null) || header.checksum_ok()) {
85       readScaleFactors();
86
87       readSampleData();
88     }
89
90   }
91
92   protected void createSubbands() {
93     @LOC("THIS,LayerIDecoder.SB") int i;
94     if (mode == Header.SINGLE_CHANNEL) {
95       for (i = 0; i < num_subbands; ++i) {
96         subbands[i] = new SubbandLayer1(i);
97       }
98     } else if (mode == Header.JOINT_STEREO) {
99       for (i = 0; i < header.intensity_stereo_bound(); ++i) {
100         subbands[i] = new SubbandLayer1Stereo(i);
101       }
102       for (; i < num_subbands; ++i) {
103         subbands[i] = new SubbandLayer1IntensityStereo(i);
104       }
105     } else {
106       for (i = 0; i < num_subbands; ++i) {
107         subbands[i] = new SubbandLayer1Stereo(i);
108       }
109     }
110   }
111
112   protected void readAllocation() throws DecoderException {
113     // start to read audio data:
114     for (@LOC("THIS,LayerIDecoder.SB") int i = 0; i < num_subbands; ++i)
115       subbands[i].read_allocation(stream, header, crc);
116
117   }
118
119   protected void readScaleFactorSelection() {
120     // scale factor selection not present for layer I.
121   }
122
123   protected void readScaleFactors() {
124     for (@LOC("THIS,LayerIDecoder.SB") int i = 0; i < num_subbands; ++i)
125       subbands[i].read_scalefactor(stream, header);
126   }
127
128   @LATTICE("MODE<THIS,THIS<C,THISLOC=THIS,C*")
129   protected void readSampleData() {
130
131     @LOC("THIS,LayerIDecoder.SB") boolean read_ready = false;
132     @LOC("THIS,LayerIDecoder.SB") boolean write_ready = false;
133
134     @LOC("MODE") int mode = header.mode(); // header.mode() will return
135                                            // DELTA(THIS)
136
137     @LOC("THIS,LayerIDecoder.SB") int i;
138     do {
139
140       for (i = 0; i < num_subbands; ++i) {
141         read_ready = subbands[i].read_sampledata(stream); // DELTA[Loc[readSampleData.V],Loc[LayerIDecoder.L]]
142       }
143
144       do {
145         for (i = 0; i < num_subbands; ++i) {
146           write_ready = subbands[i].put_next_sample(which_channels, filter1, filter2);
147         }
148
149         filter1.calculate_pcm_samples(buffer);
150         if ((which_channels == OutputChannels.BOTH_CHANNELS) && (mode != Header.SINGLE_CHANNEL)) {
151           filter2.calculate_pcm_samples(buffer);
152         }
153
154       } while (!write_ready);
155
156     } while (!read_ready);
157
158   }
159
160   /**
161    * Class for layer I subbands in single channel mode. Used for single channel
162    * mode and in derived class for intensity stereo mode
163    */
164   @LATTICE("S<L,L<H,H<SH,SH*,S*")
165   @METHODDEFAULT("OUT<V,V<THIS,THIS<C,C<IN,C*,THISLOC=THIS,RETURNLOC=OUT")
166   static class SubbandLayer1 extends Subband {
167
168     // Factors and offsets for sample requantization
169     @LOC("H")
170     public static final float table_factor[] = { 0.0f, (1.0f / 2.0f) * (4.0f / 3.0f),
171         (1.0f / 4.0f) * (8.0f / 7.0f), (1.0f / 8.0f) * (16.0f / 15.0f),
172         (1.0f / 16.0f) * (32.0f / 31.0f), (1.0f / 32.0f) * (64.0f / 63.0f),
173         (1.0f / 64.0f) * (128.0f / 127.0f), (1.0f / 128.0f) * (256.0f / 255.0f),
174         (1.0f / 256.0f) * (512.0f / 511.0f), (1.0f / 512.0f) * (1024.0f / 1023.0f),
175         (1.0f / 1024.0f) * (2048.0f / 2047.0f), (1.0f / 2048.0f) * (4096.0f / 4095.0f),
176         (1.0f / 4096.0f) * (8192.0f / 8191.0f), (1.0f / 8192.0f) * (16384.0f / 16383.0f),
177         (1.0f / 16384.0f) * (32768.0f / 32767.0f) };
178
179     @LOC("H")
180     public static final float table_offset[] = { 0.0f, ((1.0f / 2.0f) - 1.0f) * (4.0f / 3.0f),
181         ((1.0f / 4.0f) - 1.0f) * (8.0f / 7.0f), ((1.0f / 8.0f) - 1.0f) * (16.0f / 15.0f),
182         ((1.0f / 16.0f) - 1.0f) * (32.0f / 31.0f), ((1.0f / 32.0f) - 1.0f) * (64.0f / 63.0f),
183         ((1.0f / 64.0f) - 1.0f) * (128.0f / 127.0f), ((1.0f / 128.0f) - 1.0f) * (256.0f / 255.0f),
184         ((1.0f / 256.0f) - 1.0f) * (512.0f / 511.0f),
185         ((1.0f / 512.0f) - 1.0f) * (1024.0f / 1023.0f),
186         ((1.0f / 1024.0f) - 1.0f) * (2048.0f / 2047.0f),
187         ((1.0f / 2048.0f) - 1.0f) * (4096.0f / 4095.0f),
188         ((1.0f / 4096.0f) - 1.0f) * (8192.0f / 8191.0f),
189         ((1.0f / 8192.0f) - 1.0f) * (16384.0f / 16383.0f),
190         ((1.0f / 16384.0f) - 1.0f) * (32768.0f / 32767.0f) };
191
192     @LOC("H")
193     protected int subbandnumber;
194     @LOC("SH")
195     protected int samplenumber;
196     @LOC("H")
197     protected int allocation;
198     @LOC("L")
199     protected float scalefactor;
200     @LOC("L")
201     protected int samplelength;
202     @LOC("S")
203     protected float sample;
204     @LOC("L")
205     protected float factor;
206     @LOC("L")
207     protected float offset;
208
209     /**
210      * Construtor.
211      */
212     public SubbandLayer1(@LOC("IN") int subbandnumber) {
213       this.subbandnumber = subbandnumber;
214       samplenumber = 0;
215     }
216
217     /**
218            *
219            */
220     public void read_allocation(@LOC("IN") Bitstream stream, @LOC("IN") Header header,
221         @LOC("IN") Crc16 crc) throws DecoderException {
222       if ((allocation = stream.get_bits(4)) == 15) {
223         // CGJ: catch this condition and throw appropriate exception
224         throw new DecoderException(DecoderErrors.ILLEGAL_SUBBAND_ALLOCATION, null);
225         // cerr << "WARNING: stream contains an illegal allocation!\n";
226         // MPEG-stream is corrupted!
227       }
228
229       if (crc != null)
230         crc.add_bits(allocation, 4);
231       if (allocation != 0) {
232         samplelength = allocation + 1;
233         factor = table_factor[allocation];
234         offset = table_offset[allocation];
235       }
236     }
237
238     /**
239            *
240            */
241     public void read_scalefactor(@LOC("IN") Bitstream stream, @LOC("IN") Header header) {
242       if (allocation != 0)
243         scalefactor = scalefactors[stream.get_bits(6)];
244     }
245
246     public boolean read_sampledata(@LOC("IN") Bitstream stream) {
247       if (allocation != 0) {
248         sample = (float) (stream.get_bits(samplelength));
249       }
250       if (++samplenumber == 12) {
251         samplenumber = 0;
252         return true;
253       }
254       return false;
255     }
256
257     public boolean put_next_sample(@LOC("IN") int channels, @LOC("IN") SynthesisFilter filter1,
258         @LOC("IN") SynthesisFilter filter2) {
259       if ((allocation != 0) && (channels != OutputChannels.RIGHT_CHANNEL)) {
260         @LOC("OUT") float scaled_sample = (sample * factor + offset) * scalefactor;
261         filter1.input_sample(scaled_sample, subbandnumber);
262       }
263       return true;
264     }
265   };
266
267   /**
268    * Class for layer I subbands in joint stereo mode.
269    */
270   @LATTICE("S<L,L<H,H<SH,SH*")
271   @METHODDEFAULT("OUT<V,V<THIS,THIS<C,C<IN,C*,THISLOC=THIS,RETURNLOC=OUT")
272   static class SubbandLayer1IntensityStereo extends SubbandLayer1 {
273     @LOC("L")
274     protected float channel2_scalefactor;
275
276     /**
277      * Constructor
278      */
279     public SubbandLayer1IntensityStereo(@LOC("IN") int subbandnumber) {
280       super(subbandnumber);
281     }
282
283     /**
284            *
285            */
286     public void read_allocation(@LOC("IN") Bitstream stream, @LOC("IN") Header header,
287         @LOC("IN") Crc16 crc) throws DecoderException {
288       super.read_allocation(stream, header, crc);
289     }
290
291     /**
292            *
293            */
294     public void read_scalefactor(@LOC("IN") Bitstream stream, @LOC("IN") Header header) {
295       if (allocation != 0) {
296         scalefactor = scalefactors[stream.get_bits(6)];
297         channel2_scalefactor = scalefactors[stream.get_bits(6)];
298       }
299     }
300
301     public boolean read_sampledata(@LOC("IN") Bitstream stream) {
302       return super.read_sampledata(stream);
303     }
304
305     public boolean put_next_sample(@LOC("IN") int channels, @LOC("IN") SynthesisFilter filter1,
306         @LOC("IN") SynthesisFilter filter2) {
307       if (allocation != 0) {
308         sample = sample * factor + offset; // requantization
309         if (channels == OutputChannels.BOTH_CHANNELS) {
310           @LOC("OUT") float sample1 = sample * scalefactor;
311           @LOC("OUT") float sample2 = sample * channel2_scalefactor;
312           filter1.input_sample(sample1, subbandnumber);
313           filter2.input_sample(sample2, subbandnumber);
314         } else if (channels == OutputChannels.LEFT_CHANNEL) {
315           @LOC("OUT") float sample1 = sample * scalefactor;
316           filter1.input_sample(sample1, subbandnumber);
317         } else {
318           @LOC("OUT") float sample2 = sample * channel2_scalefactor;
319           filter1.input_sample(sample2, subbandnumber);
320         }
321       }
322       return true;
323     }
324   };
325
326   /**
327    * Class for layer I subbands in stereo mode.
328    */
329   @LATTICE("S<L,L<H,H<SH,SH*,S*")
330   @METHODDEFAULT("OUT<V,V<THIS,THIS<C,C<IN,C*,THISLOC=THIS,RETURNLOC=OUT")
331   static class SubbandLayer1Stereo extends SubbandLayer1 {
332     @LOC("H")
333     protected int channel2_allocation;
334     @LOC("L")
335     protected float channel2_scalefactor;
336     @LOC("L")
337     protected int channel2_samplelength;
338     @LOC("S")
339     protected float channel2_sample;
340     @LOC("L")
341     protected float channel2_factor;
342     @LOC("L")
343     protected float channel2_offset;
344
345     /**
346      * Constructor
347      */
348     public SubbandLayer1Stereo(@LOC("IN") int subbandnumber) {
349       super(subbandnumber);
350     }
351
352     /**
353            *
354            */
355     public void read_allocation(@LOC("IN") Bitstream stream, @LOC("IN") Header header,
356         @LOC("IN") Crc16 crc) throws DecoderException {
357       allocation = stream.get_bits(4);
358       channel2_allocation = stream.get_bits(4);
359       if (crc != null) {
360         crc.add_bits(allocation, 4);
361         crc.add_bits(channel2_allocation, 4);
362       }
363       if (allocation != 0) {
364         samplelength = allocation + 1;
365         factor = table_factor[allocation];
366         offset = table_offset[allocation];
367       }
368       if (channel2_allocation != 0) {
369         channel2_samplelength = channel2_allocation + 1;
370         channel2_factor = table_factor[channel2_allocation];
371         channel2_offset = table_offset[channel2_allocation];
372       }
373     }
374
375     /**
376            *
377            */
378     public void read_scalefactor(@LOC("IN") Bitstream stream, @LOC("IN") Header header) {
379       if (allocation != 0)
380         scalefactor = scalefactors[stream.get_bits(6)];
381       if (channel2_allocation != 0)
382         channel2_scalefactor = scalefactors[stream.get_bits(6)];
383     }
384
385     /**
386            *
387            */
388     @RETURNLOC("OUT")
389     public boolean read_sampledata(@LOC("IN") Bitstream stream) {
390       @LOC("OUT") boolean returnvalue = super.read_sampledata(stream);
391       if (channel2_allocation != 0) {
392         channel2_sample = (float) (stream.get_bits(channel2_samplelength));
393       }
394       return returnvalue;
395     }
396
397     /**
398            *
399            */
400     @RETURNLOC("OUT")
401     public boolean put_next_sample(@LOC("IN") int channels, @LOC("IN") SynthesisFilter filter1,
402         @LOC("IN") SynthesisFilter filter2) {
403       super.put_next_sample(channels, filter1, filter2);
404       if ((channel2_allocation != 0) && (channels != OutputChannels.LEFT_CHANNEL)) {
405         @LOC("OUT") float sample2 =
406             (channel2_sample * channel2_factor + channel2_offset) * channel2_scalefactor;
407         if (channels == OutputChannels.BOTH_CHANNELS)
408           filter2.input_sample(sample2, subbandnumber);
409         else
410           filter1.input_sample(sample2, subbandnumber);
411       }
412       return true;
413     }
414     
415   };
416
417 }