private Residue ReadResidue(BitReader r) { int residueType = (int)r.ReadUnsigned(16); int begin = (int)r.ReadUnsigned(24); int end = (int)r.ReadUnsigned(24); int partitionSize = (int)r.ReadUnsigned(24) + 1; int classifications = (int)r.ReadUnsigned(6) + 1; int classBook = (int)r.ReadUnsigned(8); if (begin > end) throw new VorbisReadException("Residue begin should not be greater than end"); if (classBook >= codebooks.Count) throw new VorbisReadException("Bad codebook index for residue's classBook: {0}", classBook); WriteLine(" Residue type: {0}", residueType); WriteLine(" Begin: {0}", begin); WriteLine(" End: {0}", end); WriteLine(" Partition size: {0}", partitionSize); WriteLine(" Classifications: {0}", classifications); WriteLine(" Class book: {0}", classBook); int[] residueCascade = new int[classifications]; //int[,] residueBooks = new int[classifications, 8]; //bool[,] residueBooksUsed = new bool[classifications, 8]; Codebook[,] residueBooks = new Codebook[classifications, 8]; for (int i = 0; i < classifications; ++i) { int highBits = 0; int lowBits = (int)r.ReadUnsigned(3); bool bitFlag = r.ReadBit(); if (bitFlag) highBits = (int)r.ReadUnsigned(5); residueCascade[i] = highBits * 8 + lowBits; WriteLine(" Residue cascade[{0}] = {1}", i, residueCascade[i]); } for (int i = 0; i < classifications; ++i) { for (int j = 0; j < 8; ++j) { if ((residueCascade[i] & (1 << j)) != 0) { int booknum = (int)r.ReadUnsigned(8); if (booknum >= codebooks.Count) throw new VorbisReadException("Bad codebook index when reading residueBooks[{0}][{1}]: {2}", i, j, booknum); WriteLine(" Residue books[{0},{1}] = {2}", i, j, booknum); residueBooks[i, j] = codebooks[booknum]; } else { WriteLine(" Residue books[{0},{1}] = unused", i, j); } } } Residue residue = new Residue(); residue.Type = residueType; residue.Begin = begin; residue.End = end; residue.PartitionSize = partitionSize; residue.ClassificationCount = classifications; residue.ClassBook = codebooks[classBook]; residue.Cascade = residueCascade; residue.Books = residueBooks; return residue; }
private void DecodeFormat1(BitReader r, Codebook vqbook, int offset, float[] v) { int n = PartitionSize; int i=0; do { float[] entryTemp = vqbook.VectorLookup(r); for (int j = 0; j < vqbook.Dimensions; ++j) { v[offset + i] += entryTemp[j]; ++i; } } while(i <n); }
private Codebook ReadCodebook(BitReader r) { Codebook cb = new Codebook(); cb.Dimensions = (int)r.ReadUnsigned(16); cb.Entries = (int)r.ReadUnsigned(24); int dimensions = cb.Dimensions; int entries = cb.Entries; //Console.WriteLine(" Dimensions: {0}", cb.Dimensions); //Console.WriteLine(" Entries: {0}", cb.Entries); cb.RootNode = ReadHuffman(cb.Entries, r); //root.Dump(); int lookupType = (int)r.ReadUnsigned(4); cb.LookupType = lookupType; //Console.WriteLine(" Lookup type: {0}", lookupType); if (lookupType == 0) { // nothing to do } else if (lookupType == 1 || lookupType == 2) { float minimumValue = r.ReadVorbisFloat(); float deltaValue = r.ReadVorbisFloat(); uint valueBits = r.ReadUnsigned(4) + 1; bool sequenceP = r.ReadBit(); int lookupValues; //Console.WriteLine(" Minimum value: {0}", minimumValue); //Console.WriteLine(" Delta value: {0}", deltaValue); //Console.WriteLine(" Value bits: {0}", valueBits); //Console.WriteLine(" Sequence P: {0}", sequenceP ? 1 : 0); cb.MinimumValue = minimumValue; cb.DeltaValue = deltaValue; cb.SequenceP = sequenceP; if (lookupType == 1) { lookupValues = lookup1_values(entries, dimensions); if (Math.Pow(lookupValues, dimensions) > entries) { // this is actually not a problem w/ the file, it's a problem w/ the decoder if this happens throw new VorbisReadException("lookup1 is busted"); } } else { lookupValues = (int)entries * (int)dimensions; } //Console.WriteLine(" Lookup values: {0}", lookupValues); uint[] multiplicands = new uint[lookupValues]; for (int i = 0; i < lookupValues; ++i) { multiplicands[i] = r.ReadUnsigned((int)valueBits); //Console.WriteLine(" Multiplicands[{0}] = {1}", i, multiplicands[i]); } cb.Multiplicands = multiplicands; } else if (lookupType > 2) { throw new VorbisReadException("Invalid lookup type. Only types 0, 1 and 2 are supported"); } return cb; }