3 Copyright 2008 Tor-Einar Jarnbjo
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
9 http://www.apache.org/licenses/LICENSE-2.0
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.
19 package org.omtk.vorbis {
21 import flash.errors.IllegalOperationError;
22 import org.omtk.util.*;
24 public class CodeBook {
26 private var entries:uint;
27 private var entryLengths:Vector.<int>;
28 private var valueVector:Vector.<Vector.<Number>>;
30 private var codeBookLookupType:int = -1;
32 public var huffmanRoot:HuffmanNode;
33 public var dimensions:uint;
35 public function CodeBook( source: BitByteArray ) {
40 var syncPattern:uint = source.readUnsignedBitwiseInt(24);
41 if(syncPattern !=0x564342) {
42 throw new IllegalOperationError("Illegal codebook sync pattern: "+syncPattern);
45 dimensions = source.readUnsignedBitwiseInt(16);
46 entries = source.readUnsignedBitwiseInt(24);
48 entryLengths = new Vector.<int>(entries);
50 var ordered:Boolean = source.readBit();
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.");
59 for(j=i; j<i+num; j++) {
62 //Arrays.fill(entryLengths, i, i+num, cl);
69 var sparse:Boolean = source.readBit();
72 for(i=0; i<entryLengths.length; i++) {
73 if(source.readBit()) {
74 entryLengths[i]=source.readUnsignedBitwiseInt(5)+1;
83 //Alert.show("entryLengths.length: "+entryLengths.length, "CodeBook");
84 for(i=0; i<entryLengths.length; i++) {
85 entryLengths[i]=source.readUnsignedBitwiseInt(5)+1;
91 if (!createHuffmanTree(entryLengths)) {
92 throw new Error("An exception was thrown when building the codebook Huffman tree.");
95 codeBookLookupType = source.readUnsignedBitwiseInt(4);
97 switch(codeBookLookupType) {
99 // codebook has no scalar vectors to be calculated
103 var codeBookMinimumValue:Number = Util.float32unpack(source.readUnsignedBitwiseInt(32));
104 var codeBookDeltaValue:Number = Util.float32unpack(source.readUnsignedBitwiseInt(32));
106 var codeBookValueBits:uint = source.readUnsignedBitwiseInt(4)+1;
107 var codeBookSequenceP:Boolean = source.readBit();
109 var codeBookLookupValues:uint = 0;
111 if(codeBookLookupType==1) {
112 codeBookLookupValues=Util.lookup1Values(entries, dimensions);
115 codeBookLookupValues=entries*dimensions;
118 var codeBookMultiplicands:Vector.<int> = new Vector.<int>(codeBookLookupValues);
120 for(i=0; i < codeBookMultiplicands.length; i++) {
121 codeBookMultiplicands[i]=source.readUnsignedBitwiseInt(codeBookValueBits);
124 valueVector = new Vector.<Vector.<Number>>(entries);
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;
134 codeBookMultiplicands[multiplicandOffset]*codeBookDeltaValue+codeBookMinimumValue+last;
135 if(codeBookSequenceP) {
136 last = valueVector[i][j];
138 indexDivisor*=codeBookLookupValues;
143 throw new Error("Unsupported codebook lookup type: "+codeBookLookupType);
144 /** @todo implement */
148 throw new Error("Unsupported codebook lookup type: "+codeBookLookupType);
152 private function createHuffmanTree(entryLengths:Vector.<int>):Boolean {
156 huffmanRoot = new HuffmanNode();
157 for(i=0; i<entryLengths.length; i++) {
158 var el:int = entryLengths[i];
160 if(!huffmanRoot.setNewValue(el, i)) {
169 public function readVvAdd(a0:Vector.<Number>, a1:Vector.<Number>, left:Boolean, right:Boolean, source:BitByteArray, offset:int, length:int):void {
174 if (!left && !right) {
180 left && right ? 2 : 1;
184 var ve:Vector.<Number>;
187 lim = (offset + length) / 2;
189 for (i = offset / 2; i < lim;) {
190 ix = source.readUnsignedHuffmanInt(huffmanRoot);
191 ve = valueVector[ix];
192 for (j = 0; j < dimensions; j++) {
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++) {