changes.
[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 /**
29  * Implements decoding of MPEG Audio Layer I frames. 
30  */
31 @LATTICE("L<SH,SH<H,SH*")
32 @METHODDEFAULT("OUT<V,V<SH,SH<IN,SH*,THISLOC=V,GLOBALLOC=IN")
33     class LayerIDecoder implements FrameDecoder
34 {
35     @LOC("H") protected Bitstream                               stream;
36     @LOC("H") protected Header                                  header;
37     @LOC("H") protected SynthesisFilter                         filter1;
38     @LOC("H") protected SynthesisFilter                         filter2;
39     @LOC("H") protected Obuffer                                 buffer;
40     @LOC("H") protected int                                     which_channels;
41     @LOC("H") protected int                                     mode;
42         
43     @LOC("H") protected int                                     num_subbands;
44     @LOC("L") protected Subband[]                               subbands;
45     @LOC("H") protected Crc16                                   crc     = null; // new Crc16[1] to enable CRC checking.
46         
47         public LayerIDecoder()
48         {
49                 crc = new Crc16();
50         }
51         
52     public void create(@LOC("IN") Bitstream stream0, @LOC("IN") Header header0,
53                 @LOC("IN") SynthesisFilter filtera, @LOC("IN") SynthesisFilter filterb,
54                 @LOC("IN") Obuffer buffer0, @LOC("IN") int which_ch0)
55         {               
56                 stream         = stream0;
57                 header         = header0;
58                 filter1        = filtera;
59                 filter2        = filterb;
60                 buffer         = buffer0;
61                 which_channels = which_ch0;
62                   
63         }
64         
65         public void decodeFrame() throws DecoderException
66         {
67                 
68                 num_subbands = header.number_of_subbands();
69                 subbands = new Subband[32];
70                 mode = header.mode();
71                 
72                 createSubbands();
73                 
74                 readAllocation();
75                 readScaleFactorSelection();
76                 
77             if ((crc != null) || header.checksum_ok())
78                 {
79                         readScaleFactors();
80                         
81                         readSampleData();                       
82                 }
83
84         }
85
86         protected void createSubbands()
87         {               
88                 @LOC("V,LayerIDecoder.SH") int i;
89                 if (mode == Header.SINGLE_CHANNEL)
90                   for (i = 0; i < num_subbands; ++i)
91                     subbands[i] = new SubbandLayer1(i);
92                 else if (mode == Header.JOINT_STEREO)
93                 {
94                   for (i = 0; i < header.intensity_stereo_bound(); ++i)
95                     subbands[i] = new SubbandLayer1Stereo(i);
96                   for (; i < num_subbands; ++i)
97                     subbands[i] = new SubbandLayer1IntensityStereo(i);
98                 }
99                 else
100                 {
101                   for (i = 0; i < num_subbands; ++i)
102                     subbands[i] = new SubbandLayer1Stereo(i);
103             }           
104         }
105         
106         protected void readAllocation() throws DecoderException
107         {
108                 // start to read audio data:
109             for (@LOC("V,LayerIDecoder.SH") int i = 0; i < num_subbands; ++i)
110               subbands[i].read_allocation(stream, header, crc);
111                 
112         }
113
114         protected void readScaleFactorSelection()
115         {
116                 // scale factor selection not present for layer I. 
117         }
118         
119         protected void readScaleFactors()
120         {
121               for (@LOC("SH") int i = 0; i < num_subbands; ++i)
122                   subbands[i].read_scalefactor(stream, header);                 
123         }
124         
125         protected void readSampleData()
126         {
127                 @LOC("SH") boolean read_ready = false;
128                 @LOC("SH") boolean write_ready = false;
129                 @LOC("OUT") int mode = header.mode();
130                 @LOC("SH") int i;
131                 do
132                 {
133                   for (i = 0; i < num_subbands; ++i)
134                         read_ready = subbands[i].read_sampledata(stream);
135                   do
136                   {
137                         for (i = 0; i < num_subbands; ++i)
138                                 write_ready = subbands[i].put_next_sample(which_channels,filter1, filter2);
139
140                         filter1.calculate_pcm_samples(buffer);
141                         if ((which_channels == OutputChannels.BOTH_CHANNELS) && (mode != Header.SINGLE_CHANNEL))
142                         filter2.calculate_pcm_samples(buffer);
143                   } while (!write_ready);
144                 } while (!read_ready);
145                 
146         }
147
148 //      /**
149 //       * Abstract base class for subband classes of layer I and II
150 //       */
151 //        @LATTICE("L<H")
152 //      static abstract class Subband
153 //      {
154 //       /*
155 //        *  Changes from version 1.1 to 1.2:
156 //        *    - array size increased by one, although a scalefactor with index 63
157 //        *      is illegal (to prevent segmentation faults)
158 //        */
159 //        // Scalefactors for layer I and II, Annex 3-B.1 in ISO/IEC DIS 11172:
160 //        @LOC("H") public static final float scalefactors[] =
161 //        {
162 //        2.00000000000000f, 1.58740105196820f, 1.25992104989487f, 1.00000000000000f,
163 //        0.79370052598410f, 0.62996052494744f, 0.50000000000000f, 0.39685026299205f,
164 //        0.31498026247372f, 0.25000000000000f, 0.19842513149602f, 0.15749013123686f,
165 //        0.12500000000000f, 0.09921256574801f, 0.07874506561843f, 0.06250000000000f,
166 //        0.04960628287401f, 0.03937253280921f, 0.03125000000000f, 0.02480314143700f,
167 //        0.01968626640461f, 0.01562500000000f, 0.01240157071850f, 0.00984313320230f,
168 //        0.00781250000000f, 0.00620078535925f, 0.00492156660115f, 0.00390625000000f,
169 //        0.00310039267963f, 0.00246078330058f, 0.00195312500000f, 0.00155019633981f,
170 //        0.00123039165029f, 0.00097656250000f, 0.00077509816991f, 0.00061519582514f,
171 //        0.00048828125000f, 0.00038754908495f, 0.00030759791257f, 0.00024414062500f,
172 //        0.00019377454248f, 0.00015379895629f, 0.00012207031250f, 0.00009688727124f,
173 //        0.00007689947814f, 0.00006103515625f, 0.00004844363562f, 0.00003844973907f,
174 //        0.00003051757813f, 0.00002422181781f, 0.00001922486954f, 0.00001525878906f,
175 //        0.00001211090890f, 0.00000961243477f, 0.00000762939453f, 0.00000605545445f,
176 //        0.00000480621738f, 0.00000381469727f, 0.00000302772723f, 0.00000240310869f,
177 //        0.00000190734863f, 0.00000151386361f, 0.00000120155435f, 0.00000000000000f /* illegal scalefactor */
178 //        };
179 //
180 //        public abstract void read_allocation (Bitstream stream, Header header, Crc16 crc) throws DecoderException;
181 //        public abstract void read_scalefactor (Bitstream stream, Header header);
182 //        public abstract boolean read_sampledata (Bitstream stream);
183 //        public abstract boolean put_next_sample (int channels, SynthesisFilter filter1, SynthesisFilter filter2);
184 //      };
185         
186         /**
187          * Class for layer I subbands in single channel mode.
188          * Used for single channel mode
189          * and in derived class for intensity stereo mode
190          */
191      @LATTICE("S<L,L<H,H<SH,SH*,S*")
192         @METHODDEFAULT("OUT<V,V<SH,SH<IN,SH*,THISLOC=V,GLOBALLOC=IN")
193         static class SubbandLayer1 extends Subband
194         {
195
196           // Factors and offsets for sample requantization
197           @LOC("H") public static final float table_factor[] = {
198            0.0f, (1.0f/2.0f) * (4.0f/3.0f), (1.0f/4.0f) * (8.0f/7.0f), (1.0f/8.0f) * (16.0f/15.0f),
199           (1.0f/16.0f) * (32.0f/31.0f), (1.0f/32.0f) * (64.0f/63.0f), (1.0f/64.0f) * (128.0f/127.0f),
200           (1.0f/128.0f) * (256.0f/255.0f), (1.0f/256.0f) * (512.0f/511.0f),
201           (1.0f/512.0f) * (1024.0f/1023.0f), (1.0f/1024.0f) * (2048.0f/2047.0f),
202           (1.0f/2048.0f) * (4096.0f/4095.0f), (1.0f/4096.0f) * (8192.0f/8191.0f),
203           (1.0f/8192.0f) * (16384.0f/16383.0f), (1.0f/16384.0f) * (32768.0f/32767.0f)
204           };
205
206           @LOC("H") public static final float table_offset[] = {
207            0.0f, ((1.0f/2.0f)-1.0f) * (4.0f/3.0f), ((1.0f/4.0f)-1.0f) * (8.0f/7.0f), ((1.0f/8.0f)-1.0f) * (16.0f/15.0f),
208           ((1.0f/16.0f)-1.0f) * (32.0f/31.0f), ((1.0f/32.0f)-1.0f) * (64.0f/63.0f), ((1.0f/64.0f)-1.0f) * (128.0f/127.0f),
209           ((1.0f/128.0f)-1.0f) * (256.0f/255.0f), ((1.0f/256.0f)-1.0f) * (512.0f/511.0f),
210           ((1.0f/512.0f)-1.0f) * (1024.0f/1023.0f), ((1.0f/1024.0f)-1.0f) * (2048.0f/2047.0f),
211           ((1.0f/2048.0f)-1.0f) * (4096.0f/4095.0f), ((1.0f/4096.0f)-1.0f) * (8192.0f/8191.0f),
212           ((1.0f/8192.0f)-1.0f) * (16384.0f/16383.0f), ((1.0f/16384.0f)-1.0f) * (32768.0f/32767.0f)
213           };
214
215           @LOC("H") protected int                subbandnumber;
216           @LOC("SH") protected int               samplenumber;
217           @LOC("H") protected int                allocation;
218           @LOC("L") protected float              scalefactor;
219           @LOC("L") protected int                samplelength;
220           @LOC("S")protected float               sample;
221           @LOC("L") protected float              factor;
222           @LOC("L") protected float              offset;
223
224           /**
225            * Construtor.
226            */
227           public SubbandLayer1(@LOC("IN")int subbandnumber)
228           {
229             this.subbandnumber = subbandnumber;
230             samplenumber = 0;  
231           }
232           
233           /**
234            *
235            */
236             public void read_allocation(@LOC("IN") Bitstream stream, @LOC("IN") Header header, 
237                                         @LOC("IN") Crc16 crc) throws DecoderException
238           {
239             if ((allocation = stream.get_bits(4)) == 15) 
240             {
241                 // CGJ: catch this condition and throw appropriate exception
242                 throw new DecoderException(DecoderErrors.ILLEGAL_SUBBAND_ALLOCATION, null);     
243                 //       cerr << "WARNING: stream contains an illegal allocation!\n";
244                         // MPEG-stream is corrupted!
245             }
246
247                 if (crc != null) crc.add_bits(allocation, 4);
248                 if (allocation != 0)
249             {
250                  samplelength = allocation + 1;
251                  factor = table_factor[allocation];
252                  offset = table_offset[allocation];
253             }
254           }
255
256           /**
257            *
258            */
259             public void read_scalefactor(@LOC("IN") Bitstream stream, @LOC("IN") Header header)
260           {
261             if (allocation != 0) scalefactor = scalefactors[stream.get_bits(6)];
262           }
263
264           /**
265            *
266            */
267           @RETURNLOC("OUT") 
268           public boolean read_sampledata(@LOC("IN") Bitstream stream)
269           {
270             if (allocation != 0)
271             {
272                    sample = (float) (stream.get_bits(samplelength));
273             }
274             if (++samplenumber == 12)
275             {
276                    samplenumber = 0;
277                    return true;
278             }
279             return false;  
280           }
281
282           /**
283            *
284            */
285           @RETURNLOC("OUT")
286           public boolean put_next_sample(@LOC("IN") int channels, @LOC("IN") SynthesisFilter filter1, 
287                                          @LOC("IN") SynthesisFilter filter2)
288           {
289             if ((allocation !=0) && (channels != OutputChannels.RIGHT_CHANNEL))
290             {
291                    @LOC("OUT") float scaled_sample = (sample * factor + offset) * scalefactor;
292                    filter1.input_sample (scaled_sample, subbandnumber);
293             }
294             return true;
295           }
296         };
297         
298         /**
299          * Class for layer I subbands in joint stereo mode.
300          */
301      @LATTICE("S<L,L<H,H<SH,SH*")
302         @METHODDEFAULT("OUT<V,V<SH,SH<IN,SH*,THISLOC=V,GLOBALLOC=IN")
303         static class SubbandLayer1IntensityStereo extends SubbandLayer1
304         {
305           @LOC("L") protected float             channel2_scalefactor;
306
307           /**
308            * Constructor
309            */
310           public SubbandLayer1IntensityStereo(@LOC("IN") int subbandnumber)
311           {
312                 super(subbandnumber);  
313           }
314
315           /**
316            *
317            */
318           public void read_allocation(@LOC("IN") Bitstream stream, @LOC("IN") Header header, 
319                                       @LOC("IN") Crc16 crc) throws DecoderException
320           {
321             super.read_allocation (stream, header, crc);
322           }
323           
324           /**
325            *
326            */
327           public void read_scalefactor (@LOC("IN") Bitstream stream, @LOC("IN") Header header)
328           {
329             if (allocation != 0)
330             {
331                   scalefactor = scalefactors[stream.get_bits(6)];
332                   channel2_scalefactor = scalefactors[stream.get_bits(6)];
333             }
334           }
335
336           /**
337            *
338            */
339           @RETURNLOC("OUT")
340           public boolean read_sampledata(@LOC("IN") Bitstream stream)
341           {
342                  return super.read_sampledata (stream);
343           }
344           
345           /**
346            *
347            */
348           @RETURNLOC("OUT")
349           public boolean put_next_sample(@LOC("IN") int channels, @LOC("IN") SynthesisFilter filter1, 
350                                          @LOC("IN") SynthesisFilter filter2)
351           {
352             if (allocation !=0 )
353             {
354               sample = sample * factor + offset;                // requantization
355                   if (channels == OutputChannels.BOTH_CHANNELS)
356               {
357                         @LOC("OUT") float sample1 = sample * scalefactor;
358                         @LOC("OUT") float sample2 = sample * channel2_scalefactor;
359                         filter1.input_sample(sample1, subbandnumber);
360                         filter2.input_sample(sample2, subbandnumber);
361                   }
362                   else if (channels == OutputChannels.LEFT_CHANNEL)
363                   {
364                         @LOC("OUT") float sample1 = sample * scalefactor;
365                         filter1.input_sample(sample1, subbandnumber);
366                   }
367                   else
368                   {
369                         @LOC("OUT") float sample2 = sample * channel2_scalefactor;
370                         filter1.input_sample(sample2, subbandnumber);
371                   }
372             }
373             return true;
374           }
375         };
376         
377         /**
378          * Class for layer I subbands in stereo mode.
379          */     
380      @LATTICE("S<L,L<H,H<SH,SH*,S*")
381         @METHODDEFAULT("OUT<V,V<SH,SH<IN,SH*,THISLOC=V,GLOBALLOC=IN")
382         static class SubbandLayer1Stereo extends SubbandLayer1
383         {
384           @LOC("H") protected int               channel2_allocation;
385           @LOC("L") protected float             channel2_scalefactor;
386           @LOC("L") protected int               channel2_samplelength;
387           @LOC("S") protected float             channel2_sample;
388           @LOC("L") protected float             channel2_factor;
389           @LOC("L") protected float             channel2_offset;
390
391
392           /**
393            * Constructor
394            */
395           public SubbandLayer1Stereo(@LOC("IN") int subbandnumber)
396           {
397             super(subbandnumber);
398           }
399           
400           /**
401            *
402            */
403           public void read_allocation (@LOC("IN") Bitstream stream, @LOC("IN") Header header, 
404           @LOC("IN") Crc16 crc) throws DecoderException
405           {
406              allocation = stream.get_bits(4);
407              channel2_allocation = stream.get_bits(4);
408              if (crc != null)
409              {
410                 crc.add_bits (allocation, 4);
411                 crc.add_bits (channel2_allocation, 4);
412              }
413              if (allocation != 0)
414              {
415                 samplelength = allocation + 1;
416                 factor = table_factor[allocation];
417                 offset = table_offset[allocation];
418              }
419              if (channel2_allocation != 0)
420              {
421                 channel2_samplelength = channel2_allocation + 1;
422                 channel2_factor = table_factor[channel2_allocation];
423                 channel2_offset = table_offset[channel2_allocation];
424              }
425           }
426           
427           /**
428            *
429            */
430           public void read_scalefactor(@LOC("IN") Bitstream stream, @LOC("IN") Header header)
431           {
432             if (allocation != 0) scalefactor = scalefactors[stream.get_bits(6)];
433             if (channel2_allocation != 0) channel2_scalefactor = scalefactors[stream.get_bits(6)];
434           }
435
436           /**
437            *
438            */
439           @RETURNLOC("OUT")
440           public boolean read_sampledata (@LOC("IN")Bitstream stream)
441           {
442              @LOC("OUT") boolean returnvalue = super.read_sampledata(stream);
443              if (channel2_allocation != 0)
444              {
445                     channel2_sample = (float) (stream.get_bits(channel2_samplelength));
446               }
447             return returnvalue;
448           }
449           
450           /**
451            *
452            */
453           @RETURNLOC("OUT")
454           public boolean put_next_sample(@LOC("IN") int channels, @LOC("IN") SynthesisFilter filter1, 
455                                          @LOC("IN") SynthesisFilter filter2)
456           {
457              super.put_next_sample (channels, filter1, filter2);
458              if ((channel2_allocation != 0) && (channels != OutputChannels.LEFT_CHANNEL))
459              {
460                     @LOC("OUT") float sample2 = (channel2_sample * channel2_factor + channel2_offset) *
461                                           channel2_scalefactor;
462                     if (channels == OutputChannels.BOTH_CHANNELS)
463                            filter2.input_sample (sample2, subbandnumber);
464                     else
465                            filter1.input_sample (sample2, subbandnumber);
466              }
467              return true;
468           }
469         };
470         
471 }