~gryle-devel/gryle/trunk-deleted

« back to all changes in this revision

Viewing changes to src/javazoom/jl/decoder/BitReserve.java

  • Committer: Richard Leo Marsh Warburton
  • Date: 2007-01-13 22:08:02 UTC
  • mto: (1.1.6 gryle)
  • mto: This revision was merged to the branch mainline in revision 9.
  • Revision ID: rlmw@viglab-28-20070113220802-6cjjur0hdk1rce47
added src files

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * 11/19/04                     1.0 moved to LGPL.
 
3
 * 
 
4
 * 12/12/99 0.0.7       Implementation stores single bits 
 
5
 *                                      as ints for better performance. mdm@techie.com.
 
6
 *
 
7
 * 02/28/99 0.0     Java Conversion by E.B, javalayer@javazoom.net
 
8
 *
 
9
 *                  Adapted from the public c code by Jeff Tsay.
 
10
 *
 
11
 *-----------------------------------------------------------------------
 
12
 *   This program is free software; you can redistribute it and/or modify
 
13
 *   it under the terms of the GNU Library General Public License as published
 
14
 *   by the Free Software Foundation; either version 2 of the License, or
 
15
 *   (at your option) any later version.
 
16
 *
 
17
 *   This program is distributed in the hope that it will be useful,
 
18
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
19
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
20
 *   GNU Library General Public License for more details.
 
21
 *
 
22
 *   You should have received a copy of the GNU Library General Public
 
23
 *   License along with this program; if not, write to the Free Software
 
24
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
25
 *----------------------------------------------------------------------
 
26
 */
 
27
 
 
28
package javazoom.jl.decoder;
 
29
 
 
30
/**
 
31
 * Implementation of Bit Reservoir for Layer III.
 
32
 * <p>
 
33
 * The implementation stores single bits as a word in the buffer. If a bit is
 
34
 * set, the corresponding word in the buffer will be non-zero. If a bit is
 
35
 * clear, the corresponding word is zero. Although this may seem waseful, this
 
36
 * can be a factor of two quicker than packing 8 bits to a byte and extracting.
 
37
 * <p>
 
38
 */
 
39
 
 
40
// REVIEW: there is no range checking, so buffer underflow or overflow
 
41
// can silently occur.
 
42
final class BitReserve {
 
43
        /**
 
44
         * Size of the internal buffer to store the reserved bits. Must be a power
 
45
         * of 2. And x8, as each bit is stored as a single entry.
 
46
         */
 
47
        private static final int BUFSIZE = 4096 * 8;
 
48
 
 
49
        /**
 
50
         * Mask that can be used to quickly implement the modulus operation on
 
51
         * BUFSIZE.
 
52
         */
 
53
        private static final int BUFSIZE_MASK = BUFSIZE - 1;
 
54
 
 
55
        private int offset, totbit, buf_byte_idx;
 
56
 
 
57
        private final int[] buf = new int[BUFSIZE];
 
58
 
 
59
        private int buf_bit_idx;
 
60
 
 
61
        BitReserve() {
 
62
 
 
63
                offset = 0;
 
64
                totbit = 0;
 
65
                buf_byte_idx = 0;
 
66
        }
 
67
 
 
68
        /**
 
69
         * Return totbit Field.
 
70
         */
 
71
        public int hsstell() {
 
72
                return (totbit);
 
73
        }
 
74
 
 
75
        /**
 
76
         * Read a number bits from the bit stream.
 
77
         * 
 
78
         * @param N
 
79
         *            the number of
 
80
         */
 
81
        public int hgetbits(int N) {
 
82
                totbit += N;
 
83
 
 
84
                int val = 0;
 
85
 
 
86
                int pos = buf_byte_idx;
 
87
                if (pos + N < BUFSIZE) {
 
88
                        while (N-- > 0) {
 
89
                                val <<= 1;
 
90
                                val |= ((buf[pos++] != 0) ? 1 : 0);
 
91
                        }
 
92
                } else {
 
93
                        while (N-- > 0) {
 
94
                                val <<= 1;
 
95
                                val |= ((buf[pos] != 0) ? 1 : 0);
 
96
                                pos = (pos + 1) & BUFSIZE_MASK;
 
97
                        }
 
98
                }
 
99
                buf_byte_idx = pos;
 
100
                return val;
 
101
        }
 
102
 
 
103
        /**
 
104
         * Read 1 bit from the bit stream.
 
105
         */
 
106
        /*
 
107
         * public int hget1bit_old() { int val; totbit++; if (buf_bit_idx == 0) {
 
108
         * buf_bit_idx = 8; buf_byte_idx++; } // BUFSIZE = 4096 = 2^12, so //
 
109
         * buf_byte_idx%BUFSIZE == buf_byte_idx & 0xfff val = buf[buf_byte_idx &
 
110
         * BUFSIZE_MASK] & putmask[buf_bit_idx]; buf_bit_idx--; val = val >>>
 
111
         * buf_bit_idx; return val; }
 
112
         */
 
113
        /**
 
114
         * Returns next bit from reserve.
 
115
         * 
 
116
         * @returns 0 if next bit is reset, or 1 if next bit is set.
 
117
         */
 
118
        public int hget1bit() {
 
119
                totbit++;
 
120
                int val = buf[buf_byte_idx];
 
121
                buf_byte_idx = (buf_byte_idx + 1) & BUFSIZE_MASK;
 
122
                return val;
 
123
        }
 
124
 
 
125
        /**
 
126
         * Retrieves bits from the reserve.
 
127
         */
 
128
        /*
 
129
         * public int readBits(int[] out, int len) { if (buf_bit_idx == 0) {
 
130
         * buf_bit_idx = 8; buf_byte_idx++; current = buf[buf_byte_idx &
 
131
         * BUFSIZE_MASK]; }
 
132
         * 
 
133
         * 
 
134
         *  // save total number of bits returned len = buf_bit_idx; buf_bit_idx =
 
135
         * 0;
 
136
         * 
 
137
         * int b = current; int count = len-1;
 
138
         * 
 
139
         * while (count >= 0) { out[count--] = (b & 0x1); b >>>= 1; }
 
140
         * 
 
141
         * totbit += len; return len; }
 
142
         */
 
143
 
 
144
        /**
 
145
         * Write 8 bits into the bit stream.
 
146
         */
 
147
        public void hputbuf(int val) {
 
148
                int ofs = offset;
 
149
                buf[ofs++] = val & 0x80;
 
150
                buf[ofs++] = val & 0x40;
 
151
                buf[ofs++] = val & 0x20;
 
152
                buf[ofs++] = val & 0x10;
 
153
                buf[ofs++] = val & 0x08;
 
154
                buf[ofs++] = val & 0x04;
 
155
                buf[ofs++] = val & 0x02;
 
156
                buf[ofs++] = val & 0x01;
 
157
 
 
158
                if (ofs == BUFSIZE)
 
159
                        offset = 0;
 
160
                else
 
161
                        offset = ofs;
 
162
 
 
163
        }
 
164
 
 
165
        /**
 
166
         * Rewind N bits in Stream.
 
167
         */
 
168
        public void rewindNbits(int N) {
 
169
                totbit -= N;
 
170
                buf_byte_idx -= N;
 
171
                if (buf_byte_idx < 0)
 
172
                        buf_byte_idx += BUFSIZE;
 
173
        }
 
174
 
 
175
        /**
 
176
         * Rewind N bytes in Stream.
 
177
         */
 
178
        public void rewindNbytes(int N) {
 
179
                int bits = (N << 3);
 
180
                totbit -= bits;
 
181
                buf_byte_idx -= bits;
 
182
                if (buf_byte_idx < 0)
 
183
                        buf_byte_idx += BUFSIZE;
 
184
        }
 
185
}