here it is ... the upload-api, script-server, js2 (javascript phase2) branch merge...
[lhc/web/wiklou.git] / js2 / mwEmbed / binPlayers / omtk-fx / src / as / org / omtk / vorbis / CodeBook.as
1 /*
2
3 Copyright 2008 Tor-Einar Jarnbjo
4
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16
17 */
18
19 package org.omtk.vorbis {
20
21 import flash.errors.IllegalOperationError;
22 import org.omtk.util.*;
23
24 public class CodeBook {
25
26 private var entries:uint;
27 private var entryLengths:Vector.<int>;
28 private var valueVector:Vector.<Vector.<Number>>;
29
30 private var codeBookLookupType:int = -1;
31
32 public var huffmanRoot:HuffmanNode;
33 public var dimensions:uint;
34
35 public function CodeBook( source: BitByteArray ) {
36
37 var i:int;
38 var j:int;
39
40 var syncPattern:uint = source.readUnsignedBitwiseInt(24);
41 if(syncPattern !=0x564342) {
42 throw new IllegalOperationError("Illegal codebook sync pattern: "+syncPattern);
43 }
44
45 dimensions = source.readUnsignedBitwiseInt(16);
46 entries = source.readUnsignedBitwiseInt(24);
47
48 entryLengths = new Vector.<int>(entries);
49
50 var ordered:Boolean = source.readBit();
51
52 if(ordered) {
53 var cl:int = source.readUnsignedBitwiseInt(5)+1;
54 for(i=0; i<entryLengths.length; ) {
55 var num:int = source.readUnsignedBitwiseInt(Util.ilog(entryLengths.length-i));
56 if(i+num>entryLengths.length) {
57 throw new Error("The codebook entry length list is longer than the actual number of entry lengths.");
58 }
59 for(j=i; j<i+num; j++) {
60 entryLengths[j] = cl;
61 }
62 //Arrays.fill(entryLengths, i, i+num, cl);
63 cl++;
64 i+=num;
65 }
66 }
67 else {
68 // !ordered
69 var sparse:Boolean = source.readBit();
70
71 if(sparse) {
72 for(i=0; i<entryLengths.length; i++) {
73 if(source.readBit()) {
74 entryLengths[i]=source.readUnsignedBitwiseInt(5)+1;
75 }
76 else {
77 entryLengths[i]=-1;
78 }
79 }
80 }
81 else {
82 // !sparse
83 //Alert.show("entryLengths.length: "+entryLengths.length, "CodeBook");
84 for(i=0; i<entryLengths.length; i++) {
85 entryLengths[i]=source.readUnsignedBitwiseInt(5)+1;
86 }
87 }
88
89 }
90
91 if (!createHuffmanTree(entryLengths)) {
92 throw new Error("An exception was thrown when building the codebook Huffman tree.");
93 }
94
95 codeBookLookupType = source.readUnsignedBitwiseInt(4);
96
97 switch(codeBookLookupType) {
98 case 0:
99 // codebook has no scalar vectors to be calculated
100 break;
101 case 1:
102 case 2:
103 var codeBookMinimumValue:Number = Util.float32unpack(source.readUnsignedBitwiseInt(32));
104 var codeBookDeltaValue:Number = Util.float32unpack(source.readUnsignedBitwiseInt(32));
105
106 var codeBookValueBits:uint = source.readUnsignedBitwiseInt(4)+1;
107 var codeBookSequenceP:Boolean = source.readBit();
108
109 var codeBookLookupValues:uint = 0;
110
111 if(codeBookLookupType==1) {
112 codeBookLookupValues=Util.lookup1Values(entries, dimensions);
113 }
114 else {
115 codeBookLookupValues=entries*dimensions;
116 }
117
118 var codeBookMultiplicands:Vector.<int> = new Vector.<int>(codeBookLookupValues);
119
120 for(i=0; i < codeBookMultiplicands.length; i++) {
121 codeBookMultiplicands[i]=source.readUnsignedBitwiseInt(codeBookValueBits);
122 }
123
124 valueVector = new Vector.<Vector.<Number>>(entries);
125
126 if(codeBookLookupType==1) {
127 for(i=0; i<entries; i++) {
128 valueVector[i] = new Vector.<Number>(dimensions);
129 var last:Number = 0.0;
130 var indexDivisor:uint = 1;
131 for(j=0; j<dimensions; j++) {
132 var multiplicandOffset:int = (i/indexDivisor)%codeBookLookupValues;
133 valueVector[i][j]=
134 codeBookMultiplicands[multiplicandOffset]*codeBookDeltaValue+codeBookMinimumValue+last;
135 if(codeBookSequenceP) {
136 last = valueVector[i][j];
137 }
138 indexDivisor*=codeBookLookupValues;
139 }
140 }
141 }
142 else {
143 throw new Error("Unsupported codebook lookup type: "+codeBookLookupType);
144 /** @todo implement */
145 }
146 break;
147 default:
148 throw new Error("Unsupported codebook lookup type: "+codeBookLookupType);
149 }
150 }
151
152 private function createHuffmanTree(entryLengths:Vector.<int>):Boolean {
153
154 var i:int;
155
156 huffmanRoot = new HuffmanNode();
157 for(i=0; i<entryLengths.length; i++) {
158 var el:int = entryLengths[i];
159 if(el>0) {
160 if(!huffmanRoot.setNewValue(el, i)) {
161 return false;
162 }
163 }
164 }
165 return true;
166 }
167
168
169 public function readVvAdd(a0:Vector.<Number>, a1:Vector.<Number>, left:Boolean, right:Boolean, source:BitByteArray, offset:int, length:int):void {
170
171 var i:int;
172 var j:int;
173
174 if (!left && !right) {
175 return;
176 }
177
178 // 1 or 2 channels
179 var ch:int =
180 left && right ? 2 : 1;
181
182 var lim:int;
183 var ix:int;
184 var ve:Vector.<Number>;
185
186 if(left && right) {
187 lim = (offset + length) / 2;
188 var chptr:int = 0;
189 for (i = offset / 2; i < lim;) {
190 ix = source.readUnsignedHuffmanInt(huffmanRoot);
191 ve = valueVector[ix];
192 for (j = 0; j < dimensions; j++) {
193 if(chptr == 0) {
194 a0[i] += ve[j];
195 }
196 else {
197 a1[i] += ve[j];
198 }
199 chptr++;
200 if(chptr == 2) {
201 chptr = 0;
202 i++;
203 }
204 }
205 }
206 }
207 else {
208 var a : Vector.<Number> = left ? a0 : a1;
209 lim = offset + length;
210 for (i = offset; i < lim;) {
211 ve = valueVector[source.readUnsignedHuffmanInt(huffmanRoot)];
212 for (j = 0; j < dimensions; j++) {
213 a[i] += ve[j];
214 i++;
215 }
216 }
217 }
218
219 }
220
221 }
222
223 }