89eb5decf432062c9b6125d050f913d9b75bc4ce
[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 //compiler cannot do interfaces
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("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("L<H,H<SH,SH*")
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              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 }