b895dafe9beb2a2a7eed4226e5b41b57c8356eb7
[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*,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     // @LATTICE("IN<THIS,THISLOC=THIS")
221     @LATTICE("THIS<IN,THISLOC=THIS")
222     public void read_allocation(@LOC("THIS,LayerIDecoder$SubbandLayer1.SH") Bitstream stream,
223         @LOC("IN") Header header, @LOC("THIS,LayerIDecoder$SubbandLayer1.L") Crc16 crc)
224         throws DecoderException {
225
226       if ((allocation = stream.get_bits(4)) == 15) {
227         // CGJ: catch this condition and throw appropriate exception
228         throw new DecoderException(DecoderErrors.ILLEGAL_SUBBAND_ALLOCATION, null);
229         // cerr << "WARNING: stream contains an illegal allocation!\n";
230         // MPEG-stream is corrupted!
231       }
232
233       if (crc != null) {
234         crc.add_bits(allocation, 4); // allocation has [THIS,H]
235         // crc has [IN]
236       }
237       if (allocation != 0) {
238         samplelength = allocation + 1;
239         factor = table_factor[allocation];
240         offset = table_offset[allocation];
241       }
242     }
243
244     /**
245            *
246            */
247     public void read_scalefactor(@LOC("IN") Bitstream stream, @LOC("IN") Header header) {
248       if (allocation != 0)
249         scalefactor = scalefactors[stream.get_bits(6)];
250     }
251
252     // ssjava
253     @LATTICE("THIS<IN,THISLOC=THIS")
254     @RETURNLOC("THIS,LayerIDecoder$SubbandLayer1.S")
255     public boolean read_sampledata(@LOC("THIS,LayerIDecoder$SubbandLayer1.S") Bitstream stream) {
256       if (allocation != 0) {
257         sample = (float) (stream.get_bits(samplelength));
258       }
259       if (++samplenumber == 12) {
260         samplenumber = 0;
261         return true;
262       }
263       return false;
264     }
265
266     @METHODDEFAULT("OUT<V,V<THIS,THIS<C,C<IN,C*,THISLOC=THIS,RETURNLOC=OUT")
267     public boolean put_next_sample(@LOC("IN") int channels, @LOC("IN") SynthesisFilter filter1,
268         @LOC("IN") SynthesisFilter filter2) {
269       if ((allocation != 0) && (channels != OutputChannels.RIGHT_CHANNEL)) {
270         @LOC("OUT") float scaled_sample = (sample * factor + offset) * scalefactor;
271         filter1.input_sample(scaled_sample, subbandnumber);
272       }
273       return true;
274     }
275   };
276
277   /**
278    * Class for layer I subbands in joint stereo mode.
279    */
280   @LATTICE("S<L,L<H,H<SH,SH<SH0,SH*")
281   @METHODDEFAULT("OUT<V,V<THIS,THIS<C,C<IN,C*,THISLOC=THIS,RETURNLOC=OUT")
282   static class SubbandLayer1IntensityStereo extends SubbandLayer1 {
283     @LOC("L")
284     protected float channel2_scalefactor;
285
286     /**
287      * Constructor
288      */
289     public SubbandLayer1IntensityStereo(@LOC("IN") int subbandnumber) {
290       super(subbandnumber);
291     }
292
293     /**
294            *
295            */
296     @LATTICE("THIS<IN2,IN2<IN1,IN1<IN0,THISLOC=THIS")
297     public void read_allocation(@LOC("IN1") Bitstream stream, @LOC("IN0") Header header,
298         @LOC("IN2") Crc16 crc) throws DecoderException {
299       super.read_allocation(stream, header, crc);
300     }
301
302     /**
303            *
304            */
305     public void read_scalefactor(@LOC("IN") Bitstream stream, @LOC("IN") Header header) {
306       if (allocation != 0) {
307         scalefactor = scalefactors[stream.get_bits(6)];
308         channel2_scalefactor = scalefactors[stream.get_bits(6)];
309       }
310     }
311
312     public boolean read_sampledata(@LOC("IN") Bitstream stream) {
313       return super.read_sampledata(stream);
314     }
315
316     public boolean put_next_sample(@LOC("IN") int channels, @LOC("IN") SynthesisFilter filter1,
317         @LOC("IN") SynthesisFilter filter2) {
318       if (allocation != 0) {
319         sample = sample * factor + offset; // requantization
320         if (channels == OutputChannels.BOTH_CHANNELS) {
321           @LOC("OUT") float sample1 = sample * scalefactor;
322           @LOC("OUT") float sample2 = sample * channel2_scalefactor;
323           filter1.input_sample(sample1, subbandnumber);
324           filter2.input_sample(sample2, subbandnumber);
325         } else if (channels == OutputChannels.LEFT_CHANNEL) {
326           @LOC("OUT") float sample1 = sample * scalefactor;
327           filter1.input_sample(sample1, subbandnumber);
328         } else {
329           @LOC("OUT") float sample2 = sample * channel2_scalefactor;
330           filter1.input_sample(sample2, subbandnumber);
331         }
332       }
333       return true;
334     }
335   };
336
337   /**
338    * Class for layer I subbands in stereo mode.
339    */
340   @LATTICE("S<L,L<H,H<SH,SH<SH0,SH*,S*")
341   @METHODDEFAULT("OUT<V,V<THIS,THIS<C,C<IN,C*,THISLOC=THIS,RETURNLOC=OUT")
342   static class SubbandLayer1Stereo extends SubbandLayer1 {
343     @LOC("H")
344     protected int channel2_allocation;
345     @LOC("L")
346     protected float channel2_scalefactor;
347     @LOC("L")
348     protected int channel2_samplelength;
349     @LOC("S")
350     protected float channel2_sample;
351     @LOC("L")
352     protected float channel2_factor;
353     @LOC("L")
354     protected float channel2_offset;
355
356     /**
357      * Constructor
358      */
359     public SubbandLayer1Stereo(@LOC("IN") int subbandnumber) {
360       super(subbandnumber);
361     }
362
363     /**
364            *
365            */
366     // ssjava
367     public void read_allocation(@LOC("THIS,LayerIDecoder$SubbandLayer1Stereo.SH") Bitstream stream,
368         @LOC("IN") Header header, @LOC("THIS,LayerIDecoder$SubbandLayer1Stereo.L") Crc16 crc)
369         throws DecoderException {
370       allocation = stream.get_bits(4);
371       channel2_allocation = stream.get_bits(4);
372       if (crc != null) {
373         crc.add_bits(allocation, 4);
374         crc.add_bits(channel2_allocation, 4);
375       }
376       if (allocation != 0) {
377         samplelength = allocation + 1;
378         factor = table_factor[allocation];
379         offset = table_offset[allocation];
380       }
381       if (channel2_allocation != 0) {
382         channel2_samplelength = channel2_allocation + 1;
383         channel2_factor = table_factor[channel2_allocation];
384         channel2_offset = table_offset[channel2_allocation];
385       }
386     }
387
388     /**
389            *
390            */
391     public void read_scalefactor(@LOC("IN") Bitstream stream, @LOC("IN") Header header) {
392       if (allocation != 0)
393         scalefactor = scalefactors[stream.get_bits(6)];
394       if (channel2_allocation != 0)
395         channel2_scalefactor = scalefactors[stream.get_bits(6)];
396     }
397
398     /**
399            *
400            */
401     @RETURNLOC("THIS,LayerIDecoder$SubbandLayer1Stereo.S")
402     public boolean read_sampledata(@LOC("THIS,LayerIDecoder$SubbandLayer1Stereo.S") Bitstream stream) {
403       @LOC("THIS,LayerIDecoder$SubbandLayer1Stereo.S") boolean returnvalue = super.read_sampledata(stream);
404       if (channel2_allocation != 0) {
405         channel2_sample = (float) (stream.get_bits(channel2_samplelength));
406       }
407       return returnvalue;
408     }
409
410     /**
411            *
412            */
413     @RETURNLOC("OUT")
414     public boolean put_next_sample(@LOC("IN") int channels, @LOC("IN") SynthesisFilter filter1,
415         @LOC("IN") SynthesisFilter filter2) {
416       super.put_next_sample(channels, filter1, filter2);
417       if ((channel2_allocation != 0) && (channels != OutputChannels.LEFT_CHANNEL)) {
418         @LOC("OUT") float sample2 =
419             (channel2_sample * channel2_factor + channel2_offset) * channel2_scalefactor;
420         if (channels == OutputChannels.BOTH_CHANNELS)
421           filter2.input_sample(sample2, subbandnumber);
422         else
423           filter1.input_sample(sample2, subbandnumber);
424       }
425       return true;
426     }
427
428   };
429
430 }