summaryrefslogtreecommitdiff
path: root/songdbj/de/jarnbjo/vorbis/CodeBook.java
diff options
context:
space:
mode:
Diffstat (limited to 'songdbj/de/jarnbjo/vorbis/CodeBook.java')
-rw-r--r--songdbj/de/jarnbjo/vorbis/CodeBook.java275
1 files changed, 275 insertions, 0 deletions
diff --git a/songdbj/de/jarnbjo/vorbis/CodeBook.java b/songdbj/de/jarnbjo/vorbis/CodeBook.java
new file mode 100644
index 0000000000..c865b120ca
--- /dev/null
+++ b/songdbj/de/jarnbjo/vorbis/CodeBook.java
@@ -0,0 +1,275 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.2 2004/09/21 06:39:06 shred
22 * Importe reorganisiert, damit Eclipse Ruhe gibt. ;-)
23 *
24 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
25 * First Import
26 *
27 * Revision 1.3 2003/04/10 19:49:04 jarnbjo
28 * no message
29 *
30 * Revision 1.2 2003/03/16 01:11:12 jarnbjo
31 * no message
32 *
33 *
34 */
35
36package de.jarnbjo.vorbis;
37
38import java.io.IOException;
39import java.util.Arrays;
40
41import de.jarnbjo.util.io.BitInputStream;
42import de.jarnbjo.util.io.HuffmanNode;
43
44class CodeBook {
45
46 private HuffmanNode huffmanRoot;
47 private int dimensions, entries;
48
49 private int[] entryLengths;
50 private float[][] valueVector;
51
52 protected CodeBook(BitInputStream source) throws VorbisFormatException, IOException {
53
54 // check sync
55 if(source.getInt(24)!=0x564342) {
56 throw new VorbisFormatException("The code book sync pattern is not correct.");
57 }
58
59 dimensions=source.getInt(16);
60 entries=source.getInt(24);
61
62 entryLengths=new int[entries];
63
64 boolean ordered=source.getBit();
65
66 if(ordered) {
67 int cl=source.getInt(5)+1;
68 for(int i=0; i<entryLengths.length; ) {
69 int num=source.getInt(Util.ilog(entryLengths.length-i));
70 if(i+num>entryLengths.length) {
71 throw new VorbisFormatException("The codebook entry length list is longer than the actual number of entry lengths.");
72 }
73 Arrays.fill(entryLengths, i, i+num, cl);
74 cl++;
75 i+=num;
76 }
77 }
78 else {
79 // !ordered
80 boolean sparse=source.getBit();
81
82 if(sparse) {
83 for(int i=0; i<entryLengths.length; i++) {
84 if(source.getBit()) {
85 entryLengths[i]=source.getInt(5)+1;
86 }
87 else {
88 entryLengths[i]=-1;
89 }
90 }
91 }
92 else {
93 // !sparse
94 for(int i=0; i<entryLengths.length; i++) {
95 entryLengths[i]=source.getInt(5)+1;
96 }
97 }
98 }
99
100 if (!createHuffmanTree(entryLengths)) {
101 throw new VorbisFormatException("An exception was thrown when building the codebook Huffman tree.");
102 }
103
104 int codeBookLookupType=source.getInt(4);
105
106 switch(codeBookLookupType) {
107 case 0:
108 // codebook has no scalar vectors to be calculated
109 break;
110 case 1:
111 case 2:
112 float codeBookMinimumValue=Util.float32unpack(source.getInt(32));
113 float codeBookDeltaValue=Util.float32unpack(source.getInt(32));
114
115 int codeBookValueBits=source.getInt(4)+1;
116 boolean codeBookSequenceP=source.getBit();
117
118 int codeBookLookupValues=0;
119
120 if(codeBookLookupType==1) {
121 codeBookLookupValues=Util.lookup1Values(entries, dimensions);
122 }
123 else {
124 codeBookLookupValues=entries*dimensions;
125 }
126
127 int codeBookMultiplicands[]=new int[codeBookLookupValues];
128
129 for(int i=0; i<codeBookMultiplicands.length; i++) {
130 codeBookMultiplicands[i]=source.getInt(codeBookValueBits);
131 }
132
133 valueVector=new float[entries][dimensions];
134
135 if(codeBookLookupType==1) {
136 for(int i=0; i<entries; i++) {
137 float last=0;
138 int indexDivisor=1;
139 for(int j=0; j<dimensions; j++) {
140 int multiplicandOffset=
141 (i/indexDivisor)%codeBookLookupValues;
142 valueVector[i][j]=
143 codeBookMultiplicands[multiplicandOffset]*codeBookDeltaValue+codeBookMinimumValue+last;
144 if(codeBookSequenceP) {
145 last=valueVector[i][j];
146 }
147 indexDivisor*=codeBookLookupValues;
148 }
149 }
150 }
151 else {
152 throw new UnsupportedOperationException();
153 /** @todo implement */
154 }
155 break;
156 default:
157 throw new VorbisFormatException("Unsupported codebook lookup type: "+codeBookLookupType);
158 }
159 }
160
161 private static long totalTime=0;
162
163 private boolean createHuffmanTree(int[] entryLengths) {
164 huffmanRoot=new HuffmanNode();
165 for(int i=0; i<entryLengths.length; i++) {
166 int el=entryLengths[i];
167 if(el>0) {
168 if(!huffmanRoot.setNewValue(el, i)) {
169 return false;
170 }
171 }
172 }
173 return true;
174 }
175
176 protected int getDimensions() {
177 return dimensions;
178 }
179
180 protected int getEntries() {
181 return entries;
182 }
183
184 protected HuffmanNode getHuffmanRoot() {
185 return huffmanRoot;
186 }
187
188 //public float[] readVQ(ReadableBitChannel source) throws IOException {
189 // return valueVector[readInt(source)];
190 //}
191
192 protected int readInt(final BitInputStream source) throws IOException {
193 return source.getInt(huffmanRoot);
194 /*
195 HuffmanNode node;
196 for(node=huffmanRoot; node.value==null; node=source.getBit()?node.o1:node.o0);
197 return node.value.intValue();
198 */
199 }
200
201 protected void readVvAdd(float[][] a, BitInputStream source, int offset, int length)
202 throws VorbisFormatException, IOException {
203
204 int i,j;//k;//entry;
205 int chptr=0;
206 int ch=a.length;
207
208 if(ch==0) {
209 return;
210 }
211
212 int lim=(offset+length)/ch;
213
214 for(i=offset/ch;i<lim;){
215 final float[] ve=valueVector[source.getInt(huffmanRoot)];
216 for(j=0;j<dimensions;j++){
217 a[chptr++][i]+=ve[j];
218 if(chptr==ch){
219 chptr=0;
220 i++;
221 }
222 }
223 }
224 }
225
226 /*
227 public void readVAdd(double[] a, ReadableBitChannel source, int offset, int length)
228 throws FormatException, IOException {
229
230 int i,j,entry;
231 int t;
232
233 if(dimensions>8){
234 for(i=0;i<length;){
235 entry = readInt(source);
236 //if(entry==-1)return(-1);
237 //t=entry*dimensions;
238 for(j=0;j<dimensions;){
239 a[offset+(i++)]+=valueVector[entry][j++];//valuelist[t+(j++)];
240 }
241 }
242 }
243 else{
244 for(i=0;i<length;){
245 entry=readInt(source);
246 //if(entry==-1)return(-1);
247 //t=entry*dim;
248 j=0;
249 switch(dimensions){
250 case 8:
251 a[offset+(i++)]+=valueVector[entry][j++];//valuelist[t+(j++)];
252 case 7:
253 a[offset+(i++)]+=valueVector[entry][j++];//valuelist[t+(j++)];
254 case 6:
255 a[offset+(i++)]+=valueVector[entry][j++];//valuelist[t+(j++)];
256 case 5:
257 a[offset+(i++)]+=valueVector[entry][j++];//valuelist[t+(j++)];
258 case 4:
259 a[offset+(i++)]+=valueVector[entry][j++];//valuelist[t+(j++)];
260 case 3:
261 a[offset+(i++)]+=valueVector[entry][j++];//valuelist[t+(j++)];
262 case 2:
263 a[offset+(i++)]+=valueVector[entry][j++];//valuelist[t+(j++)];
264 case 1:
265 a[offset+(i++)]+=valueVector[entry][j++];//valuelist[t+(j++)];
266 case 0:
267 break;
268 }
269 }
270 }
271 }
272 */
273
274
275} \ No newline at end of file