2 * 09/26/08 throw exception on subbband alloc error: Christopher G. Jennings (cjennings@acm.org)
4 * 11/19/04 1.0 moved to LGPL.
6 * 12/12/99 Initial version. Adapted from javalayer.java
7 * and Subband*.java. mdm@techie.com
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.
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.
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 *----------------------------------------------------------------------
28 * Implements decoding of MPEG Audio Layer I frames.
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 {
35 protected Bitstream stream;
37 protected Header header;
39 protected SynthesisFilter filter1;
41 protected SynthesisFilter filter2;
43 protected Obuffer buffer;
45 protected int which_channels;
50 protected int num_subbands;
52 protected Subband[] subbands;
55 protected Crc16 crc = null; // new Crc16[1] to enable CRC checking.
57 public LayerIDecoder() {
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) {
69 which_channels = which_ch0;
73 public void decodeFrame() throws DecoderException {
75 num_subbands = header.number_of_subbands();
76 subbands = new Subband[32];
82 readScaleFactorSelection();
84 if ((crc != null) || header.checksum_ok()) {
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);
98 } else if (mode == Header.JOINT_STEREO) {
99 for (i = 0; i < header.intensity_stereo_bound(); ++i) {
100 subbands[i] = new SubbandLayer1Stereo(i);
102 for (; i < num_subbands; ++i) {
103 subbands[i] = new SubbandLayer1IntensityStereo(i);
106 for (i = 0; i < num_subbands; ++i) {
107 subbands[i] = new SubbandLayer1Stereo(i);
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);
119 protected void readScaleFactorSelection() {
120 // scale factor selection not present for layer I.
123 protected void readScaleFactors() {
124 for (@LOC("THIS,LayerIDecoder.SB") int i = 0; i < num_subbands; ++i)
125 subbands[i].read_scalefactor(stream, header);
128 @LATTICE("MODE<THIS,THIS<C,THISLOC=THIS,C*")
129 protected void readSampleData() {
131 @LOC("THIS,LayerIDecoder.SB1") boolean read_ready = false;
132 @LOC("THIS,LayerIDecoder.SB1") boolean write_ready = false;
134 @LOC("MODE") int mode = header.mode(); // header.mode() will return
137 @LOC("THIS,LayerIDecoder.SB1") int i;
140 for (i = 0; i < num_subbands; ++i) {
141 read_ready = subbands[i].read_sampledata(stream); // DELTA[Loc[readSampleData.V],Loc[LayerIDecoder.L]]
145 for (i = 0; i < num_subbands; ++i) {
146 write_ready = subbands[i].put_next_sample(which_channels, filter1, filter2);
149 filter1.calculate_pcm_samples(buffer);
150 if ((which_channels == OutputChannels.BOTH_CHANNELS) && (mode != Header.SINGLE_CHANNEL)) {
151 filter2.calculate_pcm_samples(buffer);
154 } while (!write_ready);
156 } while (!read_ready);
161 * Class for layer I subbands in single channel mode. Used for single channel
162 * mode and in derived class for intensity stereo mode
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 {
168 // Factors and offsets for sample requantization
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) };
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) };
193 protected int subbandnumber;
195 protected int samplenumber;
197 protected int allocation;
199 protected float scalefactor;
201 protected int samplelength;
203 protected float sample;
205 protected float factor;
207 protected float offset;
212 public SubbandLayer1(@LOC("IN") int subbandnumber) {
213 this.subbandnumber = subbandnumber;
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 {
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!
234 crc.add_bits(allocation, 4); // allocation has [THIS,H]
237 if (allocation != 0) {
238 samplelength = allocation + 1;
239 factor = table_factor[allocation];
240 offset = table_offset[allocation];
247 public void read_scalefactor(@LOC("IN") Bitstream stream, @LOC("IN") Header header) {
249 scalefactor = scalefactors[stream.get_bits(6)];
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));
259 if (++samplenumber == 12) {
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);
278 * Class for layer I subbands in joint stereo mode.
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 {
284 protected float channel2_scalefactor;
289 public SubbandLayer1IntensityStereo(@LOC("IN") int subbandnumber) {
290 super(subbandnumber);
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);
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)];
312 public boolean read_sampledata(@LOC("IN") Bitstream stream) {
313 return super.read_sampledata(stream);
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);
329 @LOC("OUT") float sample2 = sample * channel2_scalefactor;
330 filter1.input_sample(sample2, subbandnumber);
338 * Class for layer I subbands in stereo mode.
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 {
344 protected int channel2_allocation;
346 protected float channel2_scalefactor;
348 protected int channel2_samplelength;
350 protected float channel2_sample;
352 protected float channel2_factor;
354 protected float channel2_offset;
359 public SubbandLayer1Stereo(@LOC("IN") int subbandnumber) {
360 super(subbandnumber);
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);
373 crc.add_bits(allocation, 4);
374 crc.add_bits(channel2_allocation, 4);
376 if (allocation != 0) {
377 samplelength = allocation + 1;
378 factor = table_factor[allocation];
379 offset = table_offset[allocation];
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];
391 public void read_scalefactor(@LOC("IN") Bitstream stream, @LOC("IN") Header header) {
393 scalefactor = scalefactors[stream.get_bits(6)];
394 if (channel2_allocation != 0)
395 channel2_scalefactor = scalefactors[stream.get_bits(6)];
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));
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);
423 filter1.input_sample(sample2, subbandnumber);