57 #include <boost/noncopyable.hpp> 103 size_t vals = entries >> ((bits - 1) * (dimensions - 1) / dimensions);
109 for (
size_t i = 0; i < dimensions; i++) {
114 if ((acc <= entries) && (acc1 > entries))
139 throw Common::Exception(
"CodebookLibrary::getCodebook(): Codebook out of range");
156 const uint32 id = 0x564342;
164 const bool ordered = bis.
getBit();
172 while (currentEntry < entries) {
177 currentEntry += number;
180 if (currentEntry > entries)
181 throw Common::Exception(
"CodebookLibrary::rebuild(): Current entry out of range");
186 const bool sparse = bis.
getBit();
188 if ((codewordLengthLength == 0) || (codewordLengthLength > 5))
193 for (
size_t i = 0; i < entries; i++) {
210 if (lookupType == 0) {
211 }
else if (lookupType == 1) {
217 const bool sequenceFlag = bis.
getBit();
222 bos.
putBits(valueLength - 1, 4);
226 for (
size_t i = 0; i < quantVals; i++)
230 if ((size != 0) && (((bis.
pos() / 8) + 1) != size ))
248 const bool ordered = bis.
getBit();
257 while (currentEntry < entries) {
262 currentEntry += number;
265 if (currentEntry > entries)
270 const bool sparse = bis.
getBit();
273 for (
size_t i = 0; i < entries; i++) {
290 if (lookupType == 0) {
291 }
else if (lookupType == 1) {
297 const bool sequenceFlag = bis.
getBit();
302 bos.
putBits(valueLength - 1, 4);
306 for (
size_t i = 0; i < quantVals; i++)
310 throw Common::Exception(
"CodebookLibrary::copy(): Invalid lookup type %u", lookupType);
410 _inStream(inStream, disposeStream), _codebooks(codebooks, disposeCodebooks),
411 _fullSetup(fullSetup), _headerTriadPresent(false), _oldPacketHeaders(false),
412 _noGranule(false), _modPackets(false),
415 _channels(0), _sampleRate(0), _averageBytesPerSecond(0), _sampleCount(kInvalidLength),
416 _uid(0), _blocksize0Pow(0), _blocksize1Pow(0),
417 _loopCount(0), _loopStart(0), _loopEnd(0),
466 while (samples < numSamples) {
467 const size_t needSamples = numSamples - samples;
468 const size_t gotSamples =
_vorbis->readBuffer(buffer, needSamples);
470 buffer += gotSamples;
471 samples += gotSamples;
473 if (gotSamples < needSamples) {
491 const size_t riffSize =
_inStream->readUint32LE() + 8;
499 size_t chunkOffset = 12;
500 while (chunkOffset < riffSize) {
503 if ((chunkOffset + 8) > riffSize)
508 const size_t chunkSize =
_inStream->readUint32LE();
510 if (chunkType ==
"fmt ") {
511 offsetFMT = chunkOffset + 8;
513 }
else if (chunkType ==
"smpl") {
514 offsetSMPL = chunkOffset + 8;
515 }
else if (chunkType ==
"vorb") {
516 offsetVORB = chunkOffset + 8;
517 sizeVORB = chunkSize;
518 }
else if (chunkType ==
"data") {
523 chunkOffset = chunkOffset + 8 + chunkSize;
526 if (chunkOffset > riffSize)
530 throw Common::Exception(
"WwRIFFVorbisStream::init(): Expected fmt, data chunks");
532 if ((offsetVORB ==
SIZE_MAX) && (sizeFMT != 0x42))
533 throw Common::Exception(
"WwRIFFVorbisStream::init(): Expected 0x42 fmt if vorb missing");
535 if ((offsetVORB !=
SIZE_MAX) && (sizeFMT != 0x28) && (sizeFMT != 0x18) && (sizeFMT != 0x12))
538 if ((offsetVORB ==
SIZE_MAX) && (sizeFMT == 0x42))
539 offsetVORB = offsetFMT + 0x18;
555 if (
_inStream->readUint16LE() != (sizeFMT - 0x12))
610 if ((modSignal != 0x4A) && (modSignal != 0x4B) && (modSignal != 0x69) && (modSignal != 0x70)) {
732 if (setupPacket.
granule() != 0)
734 "Setup packet granule != 0");
736 const size_t startPos =
_inStream->pos() * 8;
740 const size_t codebookCount = in.
getBits(8) + 1;
741 bits.
putBits(codebookCount - 1, 8);
746 for (
size_t i = 0; i < codebookCount; i++) {
756 for (
size_t i = 0; i < codebookCount; i++) {
768 while (in.
pos() < (setupPacket.
size() * 8))
772 const size_t floorCount = in.
getBits(6) + 1;
773 bits.
putBits(floorCount - 1, 6);
775 for (
size_t i = 0; i < floorCount; i++) {
778 const size_t floor1Partitions = in.
getBits(5);
779 bits.
putBits(floor1Partitions, 5);
784 for (
size_t j = 0; j < floor1Partitions; j++) {
785 floor1PartitionClassList[j] = in.
getBits(4);
786 bits.
putBits(floor1PartitionClassList[j], 4);
788 maxClass =
MAX(maxClass, floor1PartitionClassList[j]);
792 for (
size_t j = 0; j <= maxClass; j++) {
793 floor1ClassDimensionsList[j] = in.
getBits(3) + 1;
794 bits.
putBits(floor1ClassDimensionsList[j] - 1, 3);
799 if (subClasses != 0) {
803 if (masterbook >= codebookCount)
805 "Invalid floor1 masterbook");
808 for (
size_t k = 0; k < (1U << subClasses); k++) {
810 bits.
putBits(static_cast<uint16>(subClassBook + 1), 8);
812 if (subClassBook >= 0 && (static_cast<size_t>(subClassBook) >= codebookCount))
814 "Invalid floor1 subclass book");
819 bits.
putBits(floor1Multiplier - 1, 2);
824 for (
size_t j = 0; j < floor1Partitions; j++) {
825 const uint8 currentClassNumber = floor1PartitionClassList[j];
827 for (
size_t k = 0; k < floor1ClassDimensionsList[currentClassNumber]; k++)
833 const size_t residueCount = in.
getBits(6) + 1;
834 bits.
putBits(residueCount - 1, 6);
836 for (
size_t i = 0; i < residueCount; i++) {
842 "Invalid residue type");
849 const size_t residueClassifications = in.
getBits(6) + 1;
850 bits.
putBits(residueClassifications - 1, 6);
853 bits.
putBits(residueClassbook, 8);
855 if (residueClassbook >= codebookCount)
857 "Invalid residue classbook");
860 for (
size_t j = 0; j < residueClassifications; j++) {
873 residueCascade[j] = highBits * 8 + lowBits;
876 for (
size_t j = 0; j < residueClassifications; j++) {
877 for (
uint8 k = 0; k < 8; k++) {
878 if (residueCascade[j] & (1 << k)) {
879 const size_t residueBook = in.
getBits(8);
882 if (residueBook >= codebookCount)
884 "Invalid residue book");
890 const size_t mappingCount = in.
getBits(6) + 1;
891 bits.
putBits(mappingCount - 1, 6);
893 for (
size_t i = 0; i < mappingCount; i++) {
906 bits.
putBit(squarePolarFlag);
908 if (squarePolarFlag) {
909 const size_t couplingSteps = in.
getBits(8) + 1;
910 bits.
putBits(couplingSteps - 1, 8);
912 for (
size_t j = 0; j < couplingSteps; j++) {
918 bits.
putBits(magnitude, bitCount);
928 bits.
putBits(mappingReserved, 2);
930 if (mappingReserved != 0)
932 "Mapping reserved field nonzero");
939 if (MappingMux >= subMaps)
941 "MappingMux >= subMaps");
945 for (
size_t j = 0; j < subMaps; j++) {
952 bits.
putBits(residueNumber, 8);
954 if (floorNumber >= floorCount)
956 "Invalid floor mapping");
957 if (residueNumber >= residueCount)
959 "Invalid residue mapping");
963 const size_t modeCount = in.
getBits(6) + 1;
964 bits.
putBits(modeCount - 1, 6);
969 for (
size_t i = 0; i < modeCount; i++) {
979 if (mapping >= mappingCount)
981 "Invalid mode mapping");
990 if (((in.
pos() - startPos + 7) / 8) != setupPacket.
size())
992 "Didn't read the exact size of the setup packet");
996 "First audio packet doesn't follow setup packet");
1011 const size_t packerHeaderSize = audioPacket.
headerSize();
1012 const size_t size = audioPacket.
size();
1013 const size_t packetPayloadOffset = audioPacket.
offset();
1014 const size_t nextOffset = audioPacket.
nextOffset();
1018 "Page header truncated");
1031 return packetStream.release();
1036 bool disposeAfterUse) {
uint64 getLength() const
Estimate the total number of samples per channel in this stream.
uint32 _averageBytesPerSecond
static size_t bookMapType1QuantVals(size_t entries, size_t dimensions)
int getRate() const
Sample rate of the stream.
#define MKTAG(a0, a1, a2, a3)
A wrapper macro used around four character constants, like 'DATA', to ensure portability.
uint16 readUint16LE()
Read an unsigned 16-bit word stored in little endian (LSB first) order from the stream and return it...
A template implementing a bit stream writer for different data memory layouts.
static int intLog2(uint32 v)
uint32 readUint32LE()
Read an unsigned 32-bit word stored in little endian (LSB first) order from the stream and return it...
A stream that dynamically grows as it's written to.
void putBit(bool bit)
Write a bit to the bit stream.
A class holding an UTF-8 string.
virtual size_t seek(ptrdiff_t offset, Origin whence=kOriginBegin)=0
Sets the stream position indicator for the stream.
void reset(PointerType o=0)
Resets the pointer with the new value.
PointerType release()
Returns the plain pointer value and releases ScopedPtr.
size_t _firstAudioPacketOffset
UString composeString(T value)
Convert any POD integer, float/double or bool type into a string.
virtual size_t pos() const =0
Return the stream position in bits.
Implementing the reading stream interfaces for plain memory blocks.
WwRIFFVorbisStream(Common::SeekableReadStream *inStream, bool disposeStream, Common::SeekableReadStream *codebooks, bool disposeCodebooks, bool fullSetup)
size_t readBuffer(int16 *buffer, const size_t numSamples)
Fill the given buffer with up to numSamples samples.
PacketizedAudioStream * makePacketizedVorbisStream(Common::SeekableReadStream &extraData)
Create a new PacketizedAudioStream capable of decoding vorbis audio data.
uint32 getBit()
Read a bit from the bit stream.
uint32 getBits(size_t n)
Read a multi-bit value from the bit stream.
size_t pos() const
Return the stream position in bits.
int getChannels() const
Return the number channels in this stream.
Utility templates and functions for working with strings and streams.
Sound::RewindableAudioStream * makeWwRIFFVorbisStream(Common::SeekableReadStream *wwRIFFVorbis, bool disposeAfterUse)
Exception that provides a stack of explanations.
A simple scoped smart pointer template.
bool endOfData() const
End of data reached? If this returns true, it means that at this time there is no data available in t...
size_t size() const
Return the number of bytes written to this stream in total.
Basic exceptions to throw.
A rewindable audio stream.
const char * c_str() const
Return the (utf8 encoded) string data.
Common::SeekableReadStream * generateHeaderSetup()
static void putVorbisHeader(Common::BitStreamWriter &stream, uint8 type)
Utility templates and functions.
Implementing the writing stream interfaces for memory blocks.
bool rewind()
Rewinds the stream to its start.
Common::DisposablePtr< Common::SeekableReadStream > _codebooks
virtual uint32 getBit()=0
Read a bit from the bit stream.
Simple memory based 'stream', which implements the ReadStream interface for a plain memory block...
Utility functions for working with differing string encodings.
Low-level type definitions to handle fixed width types portably.
void setDisposable(bool disposeMemory)
virtual size_t size() const =0
Obtains the total size of the stream, measured in bytes.
void flush()
Flush the stream, forcing all cached bits to the written.
size_t _setupPacketOffset
virtual void putBits(uint32 bits, size_t n)=0
Write a multi-bit value to the bit stream.
Common::DisposablePtr< Common::SeekableReadStream > _inStream
Plain, unextended ASCII (7bit clean).
A smart pointer with a deletion flag.
size_t size() const
Return the stream size in bits.
Common::ScopedArray< bool > _modeBlockFlags
void rebuild(size_t i, Common::BitStreamWriter &bos)
Common::SeekableReadStream * generateHeaderIdentification()
Common::SeekableReadStream * createPacket()
virtual void putBit(bool bit)=0
Write a bit to the bit stream.
Common::ScopedPtr< Sound::PacketizedAudioStream > _vorbis
static void putVorbisString(Common::BitStreamWriter &stream)
void copy(Common::BitStream &bis, Common::BitStreamWriter &bos)
virtual uint32 getBits(size_t n)=0
Read a multi-bit value from the bit stream.
Packet(Common::SeekableReadStream &i, long o, bool noGranule=false)
Common::SeekableReadStream * _stream
A template implementing a bit stream for different data memory layouts.
UString readStringFixed(SeekableReadStream &stream, Encoding encoding, size_t length)
Read length bytes as a string with the given encoding out of a stream.
SeekableSubReadStream provides access to a SeekableReadStream restricted to the range [begin...
static const byte kCodeBook[]
Interface for a seekable & readable data stream.
void putBits(uint32 bits, size_t n)
Write a multi-bit value to the bit stream.
Common::SeekableReadStream * generateHeaderComment()
Common::SeekableReadStream * getCodebook(size_t i)