public void Rebuild(int codebookID, BitOggstream os) { long? cbIndexStart = GetCodebook(codebookID); ulong cbSize; { long signedCbSize = GetCodebookSize(codebookID); if (cbIndexStart == null || -1 == signedCbSize) { throw new InvalidID(); } cbSize = (ulong)signedCbSize; } long cbStartIndex = (long)cbIndexStart; long unsignedSize = (long)cbSize; Stream codebookStream = new MemoryStream(); for (long i = cbStartIndex; i < unsignedSize + cbStartIndex; i++) { codebookStream.WriteByte(m_codebookData[i]); } BinaryReader reader = new BinaryReader(codebookStream); BitStream bitStream = new BitStream(reader); reader.BaseStream.Position = 0; // todo: the rest of the stuff Rebuild(bitStream, cbSize, os); }
public void Rebuild(BitStream bis, ulong cbSize, BitOggstream bos) { /* IN: 4 bit dimensions, 14 bit entry count */ BitUint dimensions = new BitUint(4); BitUint entries = new BitUint(14); bis.Read(dimensions); bis.Read(entries); /* OUT: 24 bit identifier, 16 bit dimensions, 24 bit entry count */ bos.Write(new BitUint(24, 0x564342)); bos.Write(new BitUint(16, dimensions)); bos.Write(new BitUint(24, entries)); /* IN/OUT: 1 bit ordered flag */ BitUint ordered = new BitUint(1); bis.Read(ordered); bos.Write(ordered); if (ordered == 1) { /* IN/OUT: 5 bit initial length */ BitUint initialLength = new BitUint(5); bis.Read(initialLength); bos.Write(initialLength); int currentEntry = 0; while (currentEntry < entries) { /* IN/OUT: ilog(entries-current_entry) bit count w/ given length */ BitUint number = new BitUint((uint)Sound.WwiseRIFFVorbis.Ilog((uint)(entries - currentEntry))); bis.Read(number); bos.Write(number); currentEntry = (int)(currentEntry + number); } if (currentEntry > entries) { throw new Exception("current_entry out of range"); } } else { /* IN: 3 bit codeword length length, 1 bit sparse flag */ BitUint codewordLengthLength = new BitUint(3); BitUint sparse = new BitUint(1); bis.Read(codewordLengthLength); bis.Read(sparse); if (0 == codewordLengthLength || 5 < codewordLengthLength) { throw new Exception("nonsense codeword length"); } /* OUT: 1 bit sparse flag */ bos.Write(sparse); //if (sparse) //{ // cout << "Sparse" << endl; //} //else //{ // cout << "Nonsparse" << endl; //} for (int i = 0; i < entries; i++) { bool presentBool = true; if (sparse == 1) { /* IN/OUT 1 bit sparse presence flag */ BitUint present = new BitUint(1); bis.Read(present); bos.Write(present); presentBool = 0 != present; } if (presentBool) { /* IN: n bit codeword length-1 */ BitUint codewordLength = new BitUint(codewordLengthLength); bis.Read(codewordLength); /* OUT: 5 bit codeword length-1 */ bos.Write(new BitUint(5, codewordLength)); } } } // done with lengths // lookup table /* IN: 1 bit lookup type */ BitUint lookupType = new BitUint(1); bis.Read(lookupType); /* OUT: 4 bit lookup type */ bos.Write(new BitUint(4, lookupType)); if (lookupType == 0) { //cout << "no lookup table" << endl; } else if (lookupType == 1) { //cout << "lookup type 1" << endl; /* IN/OUT: 32 bit minimum length, 32 bit maximum length, 4 bit value length-1, 1 bit sequence flag */ BitUint min = new BitUint(32); BitUint max = new BitUint(32); BitUint valueLength = new BitUint(4); BitUint sequenceFlag = new BitUint(1); bis.Read(min); bis.Read(max); bis.Read(valueLength); bis.Read(sequenceFlag); bos.Write(min); bos.Write(max); bos.Write(valueLength); bos.Write(sequenceFlag); uint quantvals = _bookMaptype1Quantvals(entries, dimensions); for (uint i = 0; i < quantvals; i++) { /* IN/OUT: n bit value */ BitUint val = new BitUint(valueLength + 1); bis.Read(val); bos.Write(val); } } /* check that we used exactly all bytes */ /* note: if all bits are used in the last byte there will be one extra 0 byte */ if (0 != cbSize && bis.TotalBitsRead / 8 + 1 != (int)cbSize) { throw new Exception($"{cbSize}, {bis.TotalBitsRead / 8 + 1}"); } }