2 * 11/19/04 1.0 moved to LGPL.
\r
4 * 12/12/99 0.0.7 Implementation stores single bits
\r
5 * as ints for better performance. mdm@techie.com.
\r
7 * 02/28/99 0.0 Java Conversion by E.B, javalayer@javazoom.net
\r
9 * Adapted from the public c code by Jeff Tsay.
\r
11 *-----------------------------------------------------------------------
\r
12 * This program is free software; you can redistribute it and/or modify
\r
13 * it under the terms of the GNU Library General Public License as published
\r
14 * by the Free Software Foundation; either version 2 of the License, or
\r
15 * (at your option) any later version.
\r
17 * This program is distributed in the hope that it will be useful,
\r
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
20 * GNU Library General Public License for more details.
\r
22 * You should have received a copy of the GNU Library General Public
\r
23 * License along with this program; if not, write to the Free Software
\r
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
\r
25 *----------------------------------------------------------------------
\r
28 package javazoom.jl.decoder;
\r
31 * Implementation of Bit Reservoir for Layer III.
\r
33 * The implementation stores single bits as a word in the buffer. If
\r
34 * a bit is set, the corresponding word in the buffer will be non-zero.
\r
35 * If a bit is clear, the corresponding word is zero. Although this
\r
36 * may seem waseful, this can be a factor of two quicker than
\r
37 * packing 8 bits to a byte and extracting.
\r
41 // REVIEW: there is no range checking, so buffer underflow or overflow
\r
42 // can silently occur.
\r
43 final class BitReserve
\r
46 * Size of the internal buffer to store the reserved bits.
\r
47 * Must be a power of 2. And x8, as each bit is stored as a single
\r
50 private static final int BUFSIZE = 4096*8;
\r
53 * Mask that can be used to quickly implement the
\r
54 * modulus operation on BUFSIZE.
\r
56 private static final int BUFSIZE_MASK = BUFSIZE-1;
\r
58 private int offset, totbit, buf_byte_idx;
\r
59 private final int[] buf = new int[BUFSIZE];
\r
60 private int buf_bit_idx;
\r
72 * Return totbit Field.
\r
74 public int hsstell()
\r
80 * Read a number bits from the bit stream.
\r
81 * @param N the number of
\r
83 public int hgetbits(int N)
\r
89 int pos = buf_byte_idx;
\r
90 if (pos+N < BUFSIZE)
\r
95 val |= ((buf[pos++]!=0) ? 1 : 0);
\r
103 val |= ((buf[pos]!=0) ? 1 : 0);
\r
104 pos = (pos+1) & BUFSIZE_MASK;
\r
107 buf_byte_idx = pos;
\r
114 * Read 1 bit from the bit stream.
\r
117 public int hget1bit_old()
\r
121 if (buf_bit_idx == 0)
\r
126 // BUFSIZE = 4096 = 2^12, so
\r
127 // buf_byte_idx%BUFSIZE == buf_byte_idx & 0xfff
\r
128 val = buf[buf_byte_idx & BUFSIZE_MASK] & putmask[buf_bit_idx];
\r
130 val = val >>> buf_bit_idx;
\r
135 * Returns next bit from reserve.
\r
136 * @returns 0 if next bit is reset, or 1 if next bit is set.
\r
138 public int hget1bit()
\r
141 int val = buf[buf_byte_idx];
\r
142 buf_byte_idx = (buf_byte_idx+1) & BUFSIZE_MASK;
\r
147 * Retrieves bits from the reserve.
\r
150 public int readBits(int[] out, int len)
\r
152 if (buf_bit_idx == 0)
\r
156 current = buf[buf_byte_idx & BUFSIZE_MASK];
\r
161 // save total number of bits returned
\r
170 out[count--] = (b & 0x1);
\r
180 * Write 8 bits into the bit stream.
\r
182 public void hputbuf(int val)
\r
185 buf[ofs++] = val & 0x80;
\r
186 buf[ofs++] = val & 0x40;
\r
187 buf[ofs++] = val & 0x20;
\r
188 buf[ofs++] = val & 0x10;
\r
189 buf[ofs++] = val & 0x08;
\r
190 buf[ofs++] = val & 0x04;
\r
191 buf[ofs++] = val & 0x02;
\r
192 buf[ofs++] = val & 0x01;
\r
202 * Rewind N bits in Stream.
\r
204 public void rewindNbits(int N)
\r
208 if (buf_byte_idx<0)
\r
209 buf_byte_idx += BUFSIZE;
\r
213 * Rewind N bytes in Stream.
\r
215 public void rewindNbytes(int N)
\r
217 int bits = (N << 3);
\r
219 buf_byte_idx -= bits;
\r
220 if (buf_byte_idx<0)
\r
221 buf_byte_idx += BUFSIZE;
\r