mp3decoder finally passes 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("SB1<SB,SB<F,F<H,H<SH,SH*,SB1*")
31 @METHODDEFAULT("MODE<THIS,THIS<C,C<IN,THISLOC=THIS,C*")
32 class LayerIDecoder implements FrameDecoder {
33
34   @LOC("SH")
35   protected Bitstream stream;
36   @LOC("SH")
37   protected Header header;
38   @LOC("F")
39   protected SynthesisFilter filter1;
40   @LOC("F")
41   protected SynthesisFilter filter2;
42   @LOC("H")
43   protected Obuffer buffer;
44   @LOC("H")
45   protected int which_channels;
46   @LOC("H")
47   protected int mode;
48
49   @LOC("H")
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.H") 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.SB1") boolean read_ready = false;
132     @LOC("THIS,LayerIDecoder.SB1") boolean write_ready = false;
133
134     @LOC("MODE") int mode = header.mode(); // header.mode() will return
135                                            // DELTA(THIS)
136
137     @LOC("THIS,LayerIDecoder.SB1") 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<SH0,SH*,L*")
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     public static final float table_factor[] = { 0.0f, (1.0f / 2.0f) * (4.0f / 3.0f),
170         (1.0f / 4.0f) * (8.0f / 7.0f), (1.0f / 8.0f) * (16.0f / 15.0f),
171         (1.0f / 16.0f) * (32.0f / 31.0f), (1.0f / 32.0f) * (64.0f / 63.0f),
172         (1.0f / 64.0f) * (128.0f / 127.0f), (1.0f / 128.0f) * (256.0f / 255.0f),
173         (1.0f / 256.0f) * (512.0f / 511.0f), (1.0f / 512.0f) * (1024.0f / 1023.0f),
174         (1.0f / 1024.0f) * (2048.0f / 2047.0f), (1.0f / 2048.0f) * (4096.0f / 4095.0f),
175         (1.0f / 4096.0f) * (8192.0f / 8191.0f), (1.0f / 8192.0f) * (16384.0f / 16383.0f),
176         (1.0f / 16384.0f) * (32768.0f / 32767.0f) };
177
178     public static final float table_offset[] = { 0.0f, ((1.0f / 2.0f) - 1.0f) * (4.0f / 3.0f),
179         ((1.0f / 4.0f) - 1.0f) * (8.0f / 7.0f), ((1.0f / 8.0f) - 1.0f) * (16.0f / 15.0f),
180         ((1.0f / 16.0f) - 1.0f) * (32.0f / 31.0f), ((1.0f / 32.0f) - 1.0f) * (64.0f / 63.0f),
181         ((1.0f / 64.0f) - 1.0f) * (128.0f / 127.0f), ((1.0f / 128.0f) - 1.0f) * (256.0f / 255.0f),
182         ((1.0f / 256.0f) - 1.0f) * (512.0f / 511.0f),
183         ((1.0f / 512.0f) - 1.0f) * (1024.0f / 1023.0f),
184         ((1.0f / 1024.0f) - 1.0f) * (2048.0f / 2047.0f),
185         ((1.0f / 2048.0f) - 1.0f) * (4096.0f / 4095.0f),
186         ((1.0f / 4096.0f) - 1.0f) * (8192.0f / 8191.0f),
187         ((1.0f / 8192.0f) - 1.0f) * (16384.0f / 16383.0f),
188         ((1.0f / 16384.0f) - 1.0f) * (32768.0f / 32767.0f) };
189
190     @LOC("H")
191     protected int subbandnumber;
192     @LOC("SH")
193     protected int samplenumber;
194     @LOC("H")
195     protected int allocation;
196     @LOC("L")
197     protected float scalefactor;
198     @LOC("L")
199     protected int samplelength;
200     @LOC("L")
201     protected float sample;
202     @LOC("L")
203     protected float factor;
204     @LOC("L")
205     protected float offset;
206
207     /**
208      * Construtor.
209      */
210     public SubbandLayer1(@LOC("IN") int subbandnumber) {
211       this.subbandnumber = subbandnumber;
212       samplenumber = 0;
213     }
214
215     /**
216            *
217            */
218     // @LATTICE("IN<THIS,THISLOC=THIS")
219     @LATTICE("THIS<IN,THISLOC=THIS")
220     public void read_allocation(@LOC("THIS,LayerIDecoder$SubbandLayer1.SH") Bitstream stream,
221         @LOC("IN") Header header, @LOC("THIS,LayerIDecoder$SubbandLayer1.L") Crc16 crc)
222         throws DecoderException {
223
224       if ((allocation = stream.get_bits(4)) == 15) {
225         // CGJ: catch this condition and throw appropriate exception
226         throw new DecoderException(DecoderErrors.ILLEGAL_SUBBAND_ALLOCATION, null);
227         // cerr << "WARNING: stream contains an illegal allocation!\n";
228         // MPEG-stream is corrupted!
229       }
230
231       if (crc != null) {
232         crc.add_bits(allocation, 4); // allocation has [THIS,H]
233         // crc has [IN]
234       }
235       if (allocation != 0) {
236         samplelength = allocation + 1;
237         factor = table_factor[allocation];
238         offset = table_offset[allocation];
239       }
240     }
241
242     /**
243            *
244            */
245     public void read_scalefactor(@LOC("IN") Bitstream stream, @LOC("IN") Header header) {
246       if (allocation != 0)
247         scalefactor = scalefactors[stream.get_bits(6)];
248     }
249
250     // ssjava
251     @LATTICE("THIS<IN,THISLOC=THIS")
252     @RETURNLOC("THIS,LayerIDecoder$SubbandLayer1.S")
253     public boolean read_sampledata(@LOC("THIS,LayerIDecoder$SubbandLayer1.S") Bitstream stream) {
254       if (allocation != 0) {
255         sample = (float) (stream.get_bits(samplelength));
256       }
257       if (++samplenumber == 12) {
258         samplenumber = 0;
259         return true;
260       }
261       return false;
262     }
263
264     // @METHODDEFAULT("OUT<V,V<THIS,THIS<C,C<IN,C*,THISLOC=THIS,RETURNLOC=OUT")
265     @LATTICE("THIS<IN,OUT,THISLOC=THIS,RETURNLOC=OUT")
266     public boolean put_next_sample(@LOC("IN") int channels,
267         @LOC("THIS,LayerIDecoder$SubbandLayer1.S") SynthesisFilter filter1,
268         @LOC("THIS,LayerIDecoder$SubbandLayer1.S") SynthesisFilter filter2) {
269       if ((allocation != 0) && (channels != OutputChannels.RIGHT_CHANNEL)) {
270         @LOC("THIS,LayerIDecoder$SubbandLayer1.L") float scaled_sample =
271             (sample * factor + offset) * scalefactor;
272         filter1.input_sample(scaled_sample, subbandnumber);
273       }
274       return true;
275     }
276   };
277
278   /**
279    * Class for layer I subbands in joint stereo mode.
280    */
281   @LATTICE("S<L,L<H,H<SH,SH<SH0,SH*")
282   @METHODDEFAULT("OUT<V,V<THIS,THIS<C,C<IN,C*,THISLOC=THIS,RETURNLOC=OUT")
283   static class SubbandLayer1IntensityStereo extends SubbandLayer1 {
284     @LOC("L")
285     protected float channel2_scalefactor;
286
287     /**
288      * Constructor
289      */
290     public SubbandLayer1IntensityStereo(@LOC("IN") int subbandnumber) {
291       super(subbandnumber);
292     }
293
294     /**
295            *
296            */
297     @LATTICE("THIS<IN2,IN2<IN1,IN1<IN0,THISLOC=THIS")
298     public void read_allocation(@LOC("IN1") Bitstream stream, @LOC("IN0") Header header,
299         @LOC("IN2") Crc16 crc) throws DecoderException {
300       super.read_allocation(stream, header, crc);
301     }
302
303     /**
304            *
305            */
306     public void read_scalefactor(@LOC("IN") Bitstream stream, @LOC("IN") Header header) {
307       if (allocation != 0) {
308         scalefactor = scalefactors[stream.get_bits(6)];
309         channel2_scalefactor = scalefactors[stream.get_bits(6)];
310       }
311     }
312
313     public boolean read_sampledata(@LOC("IN") Bitstream stream) {
314       return super.read_sampledata(stream);
315     }
316
317     public boolean put_next_sample(@LOC("IN") int channels, @LOC("IN") SynthesisFilter filter1,
318         @LOC("IN") SynthesisFilter filter2) {
319       if (allocation != 0) {
320         sample = sample * factor + offset; // requantization
321         if (channels == OutputChannels.BOTH_CHANNELS) {
322           @LOC("OUT") float sample1 = sample * scalefactor;
323           @LOC("OUT") float sample2 = sample * channel2_scalefactor;
324           filter1.input_sample(sample1, subbandnumber);
325           filter2.input_sample(sample2, subbandnumber);
326         } else if (channels == OutputChannels.LEFT_CHANNEL) {
327           @LOC("OUT") float sample1 = sample * scalefactor;
328           filter1.input_sample(sample1, subbandnumber);
329         } else {
330           @LOC("OUT") float sample2 = sample * channel2_scalefactor;
331           filter1.input_sample(sample2, subbandnumber);
332         }
333       }
334       return true;
335     }
336   };
337
338   /**
339    * Class for layer I subbands in stereo mode.
340    */
341   @LATTICE("S<L,L<H,H<SH,SH<SH0,SH*,S*")
342   @METHODDEFAULT("OUT<V,V<THIS,THIS<C,C<IN,C*,THISLOC=THIS,RETURNLOC=OUT")
343   static class SubbandLayer1Stereo extends SubbandLayer1 {
344     @LOC("H")
345     protected int channel2_allocation;
346     @LOC("L")
347     protected float channel2_scalefactor;
348     @LOC("L")
349     protected int channel2_samplelength;
350     @LOC("S")
351     protected float channel2_sample;
352     @LOC("L")
353     protected float channel2_factor;
354     @LOC("L")
355     protected float channel2_offset;
356
357     /**
358      * Constructor
359      */
360     public SubbandLayer1Stereo(@LOC("IN") int subbandnumber) {
361       super(subbandnumber);
362     }
363
364     /**
365            *
366            */
367     // ssjava
368     public void read_allocation(@LOC("THIS,LayerIDecoder$SubbandLayer1Stereo.SH") Bitstream stream,
369         @LOC("IN") Header header, @LOC("THIS,LayerIDecoder$SubbandLayer1Stereo.L") Crc16 crc)
370         throws DecoderException {
371       allocation = stream.get_bits(4);
372       channel2_allocation = stream.get_bits(4);
373       if (crc != null) {
374         crc.add_bits(allocation, 4);
375         crc.add_bits(channel2_allocation, 4);
376       }
377       if (allocation != 0) {
378         samplelength = allocation + 1;
379         factor = table_factor[allocation];
380         offset = table_offset[allocation];
381       }
382       if (channel2_allocation != 0) {
383         channel2_samplelength = channel2_allocation + 1;
384         channel2_factor = table_factor[channel2_allocation];
385         channel2_offset = table_offset[channel2_allocation];
386       }
387     }
388
389     /**
390            *
391            */
392     public void read_scalefactor(@LOC("IN") Bitstream stream, @LOC("IN") Header header) {
393       if (allocation != 0)
394         scalefactor = scalefactors[stream.get_bits(6)];
395       if (channel2_allocation != 0)
396         channel2_scalefactor = scalefactors[stream.get_bits(6)];
397     }
398
399     /**
400            *
401            */
402     @RETURNLOC("THIS,LayerIDecoder$SubbandLayer1Stereo.S")
403     public boolean read_sampledata(@LOC("THIS,LayerIDecoder$SubbandLayer1Stereo.S") Bitstream stream) {
404       @LOC("THIS,LayerIDecoder$SubbandLayer1Stereo.S") boolean returnvalue =
405           super.read_sampledata(stream);
406       if (channel2_allocation != 0) {
407         channel2_sample = (float) (stream.get_bits(channel2_samplelength));
408       }
409       return returnvalue;
410     }
411
412     /**
413            *
414            */
415     @RETURNLOC("OUT")
416     public boolean put_next_sample(@LOC("IN") int channels, @LOC("IN") SynthesisFilter filter1,
417         @LOC("IN") SynthesisFilter filter2) {
418       super.put_next_sample(channels, filter1, filter2);
419       if ((channel2_allocation != 0) && (channels != OutputChannels.LEFT_CHANNEL)) {
420         @LOC("OUT") float sample2 =
421             (channel2_sample * channel2_factor + channel2_offset) * channel2_scalefactor;
422         if (channels == OutputChannels.BOTH_CHANNELS)
423           filter2.input_sample(sample2, subbandnumber);
424         else
425           filter1.input_sample(sample2, subbandnumber);
426       }
427       return true;
428     }
429
430   };
431
432 }