public override void ReadSetupData( VorbisCodec codec, BitReader reader ) { int syncPattern = reader.ReadBits( 24 ); if( syncPattern != 0x564342 ) { throw new InvalidDataException( "Invalid codebook sync pattern: " + syncPattern ); } int dimensions = reader.ReadBits( 16 ); int entries = reader.ReadBits( 24 ); int ordered = reader.ReadBit(); codewordLengths = new byte[entries]; if( ordered == 0 ) { int sparse = reader.ReadBit(); for( int i = 0; i < entries; i++ ) { if( sparse == 0 || ( reader.ReadBit() == 1 ) ) { codewordLengths[i] = (byte)( reader.ReadBits( 5 ) + 1 ); } } } else { int curEntry = 0; int curLength = reader.ReadBits( 5 ) + 1; while( curEntry < entries ) { int number = reader.ReadBits( VorbisUtils.iLog( entries - curEntry ) ); for( int i = curEntry; i < curEntry + number; i++ ) { codewordLengths[i] = (byte)curLength; } curEntry += number; curLength++; } } BuildHuffmanTree(); int lookupType = reader.ReadBits( 4 ); if( lookupType == 1 || lookupType == 2 ) { float minValue = VorbisUtils.Unpack( reader.ReadBitsU( 32 ) ); float deltaValue = VorbisUtils.Unpack( reader.ReadBitsU( 32 ) ); int valueBits = reader.ReadBits( 4 ) + 1; int sequenceP = reader.ReadBit(); int lookupValues = 0; if( lookupType == 1 ) { lookupValues = VorbisUtils.lookup1_values( entries, dimensions ); } else { lookupValues = entries * dimensions; } multiplicands = new ushort[lookupValues]; for( int i = 0; i < multiplicands.Length; i++ ) { multiplicands[i] = (ushort)reader.ReadBits( valueBits ); } VQ = new float[entries][]; for( int i = 0; i < entries; i++ ) { float[] vector = new float[dimensions]; if( lookupType == 1 ) { float last = 0; int indexDivisor = 1; for( int j = 0; j < dimensions; j++ ) { int multiplicandOffset = ( i / indexDivisor ) % lookupValues; vector[j] = multiplicands[multiplicandOffset] * deltaValue + minValue + last; if( sequenceP != 0 ) last = vector[j]; indexDivisor *= lookupValues; } } else { float last = 0; int mulitiplicandOffset = i * dimensions; for( int j = 0; j < dimensions; j++ ) { vector[j] = multiplicands[mulitiplicandOffset] * deltaValue + minValue + last; if( sequenceP != 0 ) last = vector[j]; mulitiplicandOffset++; } } VQ[i] = vector; } } }