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("SB<H,H<SH,SH*,SB*")
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.SB") 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.SB") boolean read_ready = false;
132 @LOC("THIS,LayerIDecoder.SB") boolean write_ready = false;
134 @LOC("MODE") int mode = header.mode(); // header.mode() will return
137 @LOC("THIS,LayerIDecoder.SB") 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*,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 public void read_allocation(@LOC("IN") Bitstream stream, @LOC("IN") Header header,
221 @LOC("IN") Crc16 crc) throws DecoderException {
222 if ((allocation = stream.get_bits(4)) == 15) {
223 // CGJ: catch this condition and throw appropriate exception
224 throw new DecoderException(DecoderErrors.ILLEGAL_SUBBAND_ALLOCATION, null);
225 // cerr << "WARNING: stream contains an illegal allocation!\n";
226 // MPEG-stream is corrupted!
230 crc.add_bits(allocation, 4);
231 if (allocation != 0) {
232 samplelength = allocation + 1;
233 factor = table_factor[allocation];
234 offset = table_offset[allocation];
241 public void read_scalefactor(@LOC("IN") Bitstream stream, @LOC("IN") Header header) {
243 scalefactor = scalefactors[stream.get_bits(6)];
246 public boolean read_sampledata(@LOC("IN") Bitstream stream) {
247 if (allocation != 0) {
248 sample = (float) (stream.get_bits(samplelength));
250 if (++samplenumber == 12) {
257 public boolean put_next_sample(@LOC("IN") int channels, @LOC("IN") SynthesisFilter filter1,
258 @LOC("IN") SynthesisFilter filter2) {
259 if ((allocation != 0) && (channels != OutputChannels.RIGHT_CHANNEL)) {
260 @LOC("OUT") float scaled_sample = (sample * factor + offset) * scalefactor;
261 filter1.input_sample(scaled_sample, subbandnumber);
268 * Class for layer I subbands in joint stereo mode.
270 @LATTICE("S<L,L<H,H<SH,SH*")
271 @METHODDEFAULT("OUT<V,V<THIS,THIS<C,C<IN,C*,THISLOC=THIS,RETURNLOC=OUT")
272 static class SubbandLayer1IntensityStereo extends SubbandLayer1 {
274 protected float channel2_scalefactor;
279 public SubbandLayer1IntensityStereo(@LOC("IN") int subbandnumber) {
280 super(subbandnumber);
286 public void read_allocation(@LOC("IN") Bitstream stream, @LOC("IN") Header header,
287 @LOC("IN") Crc16 crc) throws DecoderException {
288 super.read_allocation(stream, header, crc);
294 public void read_scalefactor(@LOC("IN") Bitstream stream, @LOC("IN") Header header) {
295 if (allocation != 0) {
296 scalefactor = scalefactors[stream.get_bits(6)];
297 channel2_scalefactor = scalefactors[stream.get_bits(6)];
301 public boolean read_sampledata(@LOC("IN") Bitstream stream) {
302 return super.read_sampledata(stream);
305 public boolean put_next_sample(@LOC("IN") int channels, @LOC("IN") SynthesisFilter filter1,
306 @LOC("IN") SynthesisFilter filter2) {
307 if (allocation != 0) {
308 sample = sample * factor + offset; // requantization
309 if (channels == OutputChannels.BOTH_CHANNELS) {
310 @LOC("OUT") float sample1 = sample * scalefactor;
311 @LOC("OUT") float sample2 = sample * channel2_scalefactor;
312 filter1.input_sample(sample1, subbandnumber);
313 filter2.input_sample(sample2, subbandnumber);
314 } else if (channels == OutputChannels.LEFT_CHANNEL) {
315 @LOC("OUT") float sample1 = sample * scalefactor;
316 filter1.input_sample(sample1, subbandnumber);
318 @LOC("OUT") float sample2 = sample * channel2_scalefactor;
319 filter1.input_sample(sample2, subbandnumber);
327 * Class for layer I subbands in stereo mode.
329 @LATTICE("S<L,L<H,H<SH,SH*,S*")
330 @METHODDEFAULT("OUT<V,V<THIS,THIS<C,C<IN,C*,THISLOC=THIS,RETURNLOC=OUT")
331 static class SubbandLayer1Stereo extends SubbandLayer1 {
333 protected int channel2_allocation;
335 protected float channel2_scalefactor;
337 protected int channel2_samplelength;
339 protected float channel2_sample;
341 protected float channel2_factor;
343 protected float channel2_offset;
348 public SubbandLayer1Stereo(@LOC("IN") int subbandnumber) {
349 super(subbandnumber);
355 public void read_allocation(@LOC("IN") Bitstream stream, @LOC("IN") Header header,
356 @LOC("IN") Crc16 crc) throws DecoderException {
357 allocation = stream.get_bits(4);
358 channel2_allocation = stream.get_bits(4);
360 crc.add_bits(allocation, 4);
361 crc.add_bits(channel2_allocation, 4);
363 if (allocation != 0) {
364 samplelength = allocation + 1;
365 factor = table_factor[allocation];
366 offset = table_offset[allocation];
368 if (channel2_allocation != 0) {
369 channel2_samplelength = channel2_allocation + 1;
370 channel2_factor = table_factor[channel2_allocation];
371 channel2_offset = table_offset[channel2_allocation];
378 public void read_scalefactor(@LOC("IN") Bitstream stream, @LOC("IN") Header header) {
380 scalefactor = scalefactors[stream.get_bits(6)];
381 if (channel2_allocation != 0)
382 channel2_scalefactor = scalefactors[stream.get_bits(6)];
389 public boolean read_sampledata(@LOC("IN") Bitstream stream) {
390 @LOC("OUT") boolean returnvalue = super.read_sampledata(stream);
391 if (channel2_allocation != 0) {
392 channel2_sample = (float) (stream.get_bits(channel2_samplelength));
401 public boolean put_next_sample(@LOC("IN") int channels, @LOC("IN") SynthesisFilter filter1,
402 @LOC("IN") SynthesisFilter filter2) {
403 super.put_next_sample(channels, filter1, filter2);
404 if ((channel2_allocation != 0) && (channels != OutputChannels.LEFT_CHANNEL)) {
405 @LOC("OUT") float sample2 =
406 (channel2_sample * channel2_factor + channel2_offset) * channel2_scalefactor;
407 if (channels == OutputChannels.BOTH_CHANNELS)
408 filter2.input_sample(sample2, subbandnumber);
410 filter1.input_sample(sample2, subbandnumber);