xoreos  0.0.5
wwriffvorbis.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 /* Based heavily on the ww2ogg tool by Adam Gashlin (hcs)
22  * (<https://github.com/hcs64/ww2ogg)>, which is licensed under the
23  * terms of the BSD 3-clause license.
24  *
25  * The original copyright note in ww2ogg reads as follows:
26  * Copyright (c) 2002, Xiph.org Foundation
27  * Copyright (c) 2009-2016, Adam Gashlin
28  *
29  * Redistribution and use in source and binary forms, with or without
30  * modification, are permitted provided that the following conditions
31  * are met:
32  *
33  * - Redistributions of source code must retain the above copyright
34  * notice, this list of conditions and the following disclaimer.
35  *
36  * - Redistributions in binary form must reproduce the above copyright
37  * notice, this list of conditions and the following disclaimer in the
38  * documentation and/or other materials provided with the distribution.
39  *
40  * - Neither the name of the Xiph.org Foundation nor the names of its
41  * contributors may be used to endorse or promote products derived from
42  * this software without specific prior written permission.
43  *
44  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
45  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
46  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
47  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
48  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
49  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
50  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
51  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
52  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
53  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
54  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55  */
56 
57 #include <boost/noncopyable.hpp>
58 
59 #include "src/common/types.h"
60 #include "src/common/maths.h"
61 #include "src/common/error.h"
62 #include "src/common/util.h"
63 #include "src/common/strutil.h"
64 #include "src/common/encoding.h"
65 #include "src/common/scopedptr.h"
67 #include "src/common/bitstream.h"
71 
72 #include "src/sound/audiostream.h"
73 
77 
78 namespace Sound {
79 
80 class CodebookLibrary : boost::noncopyable {
81 public:
84 
86 
87  void rebuild(size_t i, Common::BitStreamWriter &bos);
88  void rebuild(Common::BitStream &bis, size_t size, Common::BitStreamWriter &bos);
89 
91 
92 private:
94 
95  size_t _count;
96  size_t _offsetOffset;
97 
99 };
100 
101 static size_t bookMapType1QuantVals(size_t entries, size_t dimensions) {
102  const size_t bits = Common::intLog2(entries) + 1;
103  size_t vals = entries >> ((bits - 1) * (dimensions - 1) / dimensions);
104 
105  while (1) {
106  size_t acc = 1;
107  size_t acc1 = 1;
108 
109  for (size_t i = 0; i < dimensions; i++) {
110  acc *= vals;
111  acc1 *= vals + 1;
112  }
113 
114  if ((acc <= entries) && (acc1 > entries))
115  return vals;
116 
117  if(acc > entries) {
118  vals--;
119  } else {
120  vals++;
121  }
122  }
123 }
124 
125 CodebookLibrary::CodebookLibrary() : _stream(0), _count(0), _offsetOffset(0) {
126 }
127 
129  _stream->seek(_stream->size() - 4);
130 
132  _count = (_stream->size() - _offsetOffset) / 4;
133 }
134 
136  if (!_stream)
137  throw Common::Exception("CodebookLibrary::getCodebook(): No codebook library");
138  if (i >= (_count - 1))
139  throw Common::Exception("CodebookLibrary::getCodebook(): Codebook out of range");
140 
141  _stream->seek(_offsetOffset + i * 4);
142 
143  const size_t offset = _stream->readUint32LE();
144  const size_t next = _stream->readUint32LE();
145 
146  return new Common::SeekableSubReadStream(_stream, offset, next);
147 }
148 
150  Common::BitStream8LSB bitStream(getCodebook(i), true);
151 
152  rebuild(bitStream, bitStream.size() / 8, bos);
153 }
154 
156  const uint32 id = 0x564342;
157  const uint16 dimensions = bis.getBits(4);
158  const uint32 entries = bis.getBits(14);
159 
160  bos.putBits(id, 24);
161  bos.putBits(dimensions, 16);
162  bos.putBits(entries, 24);
163 
164  const bool ordered = bis.getBit();
165  bos.putBit(ordered);
166 
167  if (ordered) {
168  const uint8 initialLength = bis.getBits(5);
169  bos.putBits(initialLength, 5);
170 
171  uint32 currentEntry = 0;
172  while (currentEntry < entries) {
173  const size_t bitCount = Common::intLog2(entries - currentEntry) + 1;
174  const uint32 number = bis.getBits(bitCount);
175  bos.putBits(number, bitCount);
176 
177  currentEntry += number;
178  }
179 
180  if (currentEntry > entries)
181  throw Common::Exception("CodebookLibrary::rebuild(): Current entry out of range");
182 
183  } else {
184 
185  const uint8 codewordLengthLength = bis.getBits(3);
186  const bool sparse = bis.getBit();
187 
188  if ((codewordLengthLength == 0) || (codewordLengthLength > 5))
189  throw Common::Exception("CodebookLibrary::rebuild(): Nonsense codeword length");
190 
191  bos.putBit(sparse);
192 
193  for (size_t i = 0; i < entries; i++) {
194  bool present = true;
195 
196  if (sparse) {
197  present = bis.getBit();
198  bos.putBit(present);
199  }
200 
201  if (present)
202  bos.putBits(bis.getBits(codewordLengthLength), 5);
203  }
204 
205  }
206 
207  const uint8 lookupType = bis.getBits(1);
208  bos.putBits(lookupType, 4);
209 
210  if (lookupType == 0) {
211  } else if (lookupType == 1) {
212 
213  const uint32 min = bis.getBits(32);
214  const uint32 max = bis.getBits(32);
215 
216  const uint8 valueLength = bis.getBits(4) + 1;
217  const bool sequenceFlag = bis.getBit();
218 
219  bos.putBits(min, 32);
220  bos.putBits(max, 32);
221 
222  bos.putBits(valueLength - 1, 4);
223  bos.putBit(sequenceFlag);
224 
225  const size_t quantVals = bookMapType1QuantVals(entries, dimensions);
226  for (size_t i = 0; i < quantVals; i++)
227  bos.putBits(bis.getBits(valueLength), valueLength);
228  }
229 
230  if ((size != 0) && (((bis.pos() / 8) + 1) != size ))
231  throw Common::Exception("CodebookLibrary::rebuild(): Size mismatch: %s != %s",
232  Common::composeString((bis.pos() / 8) + 1).c_str(),
233  Common::composeString(size).c_str());
234 }
235 
237  const uint32 id = bis.getBits(24);
238  const uint16 dimensions = bis.getBits(16);
239  const uint32 entries = bis.getBits(24);
240 
241  if (id != 0x564342)
242  throw Common::Exception("CodebookLibrary::copy(): Invalid codebook identifier");
243 
244  bos.putBits(id, 24);
245  bos.putBits(dimensions, 16);
246  bos.putBits(entries, 24);
247 
248  const bool ordered = bis.getBit();
249  bos.putBit(ordered);
250 
251  if (ordered) {
252 
253  const uint8 initialLength = bis.getBits(5);
254  bos.putBits(initialLength, 5);
255 
256  uint32 currentEntry = 0;
257  while (currentEntry < entries) {
258  const size_t bitCount = Common::intLog2(entries - currentEntry) + 1;
259  const uint32 number = bis.getBits(bitCount);
260  bos.putBits(number, bitCount);
261 
262  currentEntry += number;
263  }
264 
265  if (currentEntry > entries)
266  throw Common::Exception("CodebookLibrary::copy(): Current entry out of range");
267 
268  } else {
269 
270  const bool sparse = bis.getBit();
271  bos.putBit(sparse);
272 
273  for (size_t i = 0; i < entries; i++) {
274  bool present = true;
275 
276  if (sparse) {
277  present = bis.getBit();
278  bos.putBit(present);
279  }
280 
281  if (present)
282  bos.putBits(bis.getBits(5), 5);
283  }
284 
285  }
286 
287  const uint8 lookupType = bis.getBits(4);
288  bos.putBits(lookupType, 4);
289 
290  if (lookupType == 0) {
291  } else if (lookupType == 1) {
292 
293  const uint32 min = bis.getBits(32);
294  const uint32 max = bis.getBits(32);
295 
296  const uint8 valueLength = bis.getBits(4) + 1;
297  const bool sequenceFlag = bis.getBit();
298 
299  bos.putBits(min, 32);
300  bos.putBits(max, 32);
301 
302  bos.putBits(valueLength - 1, 4);
303  bos.putBit(sequenceFlag);
304 
305  const size_t quantVals = bookMapType1QuantVals(entries, dimensions);
306  for (size_t i = 0; i < quantVals; i++)
307  bos.putBits(bis.getBits(valueLength), valueLength);
308 
309  } else
310  throw Common::Exception("CodebookLibrary::copy(): Invalid lookup type %u", lookupType);
311 }
312 
314 public:
315  WwRIFFVorbisStream(Common::SeekableReadStream *inStream, bool disposeStream,
316  Common::SeekableReadStream *codebooks, bool disposeCodebooks,
317  bool fullSetup);
318 
319  size_t readBuffer(int16 *buffer, const size_t numSamples);
320 
321  int getChannels() const;
322  int getRate() const;
323 
324  bool endOfData() const;
325 
326  bool rewind();
327  uint64 getLength() const;
328 
329 private:
331 
334 
340 
341  size_t _dataOffset;
342  size_t _dataSize;
344 
347 
351 
353 
357 
361 
363  size_t _modeBits;
364 
365  bool _end;
366 
367 
368  void init();
369 
373 
375 };
376 
377 /* Modern 2 or 6 byte header */
378 class Packet {
379 public:
380  Packet(Common::SeekableReadStream &i, long o, bool noGranule = false) :
381  _offset(o), _size(SIZE_MAX), _absoluteGranule(0), _noGranule(noGranule) {
382 
383  i.seek(_offset);
384 
385  _size = i.readUint16LE();
386 
387  if (!_noGranule)
389  }
390 
391  size_t headerSize() { return _noGranule ? 2 : 6; }
392  size_t size() { return _size; }
393 
394  size_t offset() { return _offset + headerSize(); }
395  size_t nextOffset() { return _offset + headerSize() + _size; }
396 
398 
399 private:
400  size_t _offset;
401  size_t _size;
404 };
405 
406 
408  Common::SeekableReadStream *codebooks, bool disposeCodebooks,
409  bool fullSetup) :
410  _inStream(inStream, disposeStream), _codebooks(codebooks, disposeCodebooks),
411  _fullSetup(fullSetup), _headerTriadPresent(false), _oldPacketHeaders(false),
412  _noGranule(false), _modPackets(false),
413  _dataOffset(SIZE_MAX), _dataSize(SIZE_MAX), _currentOffset(SIZE_MAX),
414  _setupPacketOffset(SIZE_MAX), _firstAudioPacketOffset(SIZE_MAX),
415  _channels(0), _sampleRate(0), _averageBytesPerSecond(0), _sampleCount(kInvalidLength),
416  _uid(0), _blocksize0Pow(0), _blocksize1Pow(0),
417  _loopCount(0), _loopStart(0), _loopEnd(0),
418  _end(false) {
419 
420  init();
421 
423  throw Common::Exception("WwRIFFVorbisStream: Header with triad");
424 
425  if (_oldPacketHeaders)
426  throw Common::Exception("WwRIFFVorbisStream: Old packet header");
427 
428  if (_modPackets)
429  throw Common::Exception("WwRIFFVorbisStream: Modified packets");
430 
431  rewind();
432 }
433 
435  return _vorbis->getChannels();
436 }
437 
439  return _vorbis->getRate();
440 }
441 
443  return _end;
444 }
445 
447  _end = false;
448 
452 
453  _vorbis.reset(Sound::makePacketizedVorbisStream(*headerIdentification, *headerComment, *headerSetup));
454 
456 
457  return true;
458 }
459 
461  return _sampleCount;
462 }
463 
464 size_t WwRIFFVorbisStream::readBuffer(int16 *buffer, const size_t numSamples) {
465  size_t samples = 0;
466  while (samples < numSamples) {
467  const size_t needSamples = numSamples - samples;
468  const size_t gotSamples = _vorbis->readBuffer(buffer, needSamples);
469 
470  buffer += gotSamples;
471  samples += gotSamples;
472 
473  if (gotSamples < needSamples) {
475  if (!packet) {
476  _end = true;
477  break;
478  }
479 
480  _vorbis->queuePacket(packet.release());
481  }
482  }
483 
484  return samples;
485 }
486 
488  if (_inStream->readUint32BE() != MKTAG('R', 'I', 'F', 'F'))
489  throw Common::Exception("WwRIFFVorbisStream::init(): Missing RIFF");
490 
491  const size_t riffSize = _inStream->readUint32LE() + 8;
492 
493  if (_inStream->readUint32BE() != MKTAG('W', 'A', 'V', 'E'))
494  throw Common::Exception("WwRIFFVorbisStream::init(): Missing WAVE");
495 
496  size_t offsetFMT = SIZE_MAX, offsetSMPL = SIZE_MAX, offsetVORB = SIZE_MAX;
497  size_t sizeFMT = SIZE_MAX, sizeVORB = SIZE_MAX;
498 
499  size_t chunkOffset = 12;
500  while (chunkOffset < riffSize) {
501  _inStream->seek(chunkOffset);
502 
503  if ((chunkOffset + 8) > riffSize)
504  throw Common::Exception("WwRIFFVorbisStream::init(): Chunk header truncated");
505 
507 
508  const size_t chunkSize = _inStream->readUint32LE();
509 
510  if (chunkType == "fmt ") {
511  offsetFMT = chunkOffset + 8;
512  sizeFMT = chunkSize;
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") {
519  _dataOffset = chunkOffset + 8;
520  _dataSize = chunkSize;
521  }
522 
523  chunkOffset = chunkOffset + 8 + chunkSize;
524  }
525 
526  if (chunkOffset > riffSize)
527  throw Common::Exception("WwRIFFVorbisStream::init(): Chunk truncated");
528 
529  if ((offsetFMT == SIZE_MAX) && (_dataOffset == SIZE_MAX))
530  throw Common::Exception("WwRIFFVorbisStream::init(): Expected fmt, data chunks");
531 
532  if ((offsetVORB == SIZE_MAX) && (sizeFMT != 0x42))
533  throw Common::Exception("WwRIFFVorbisStream::init(): Expected 0x42 fmt if vorb missing");
534 
535  if ((offsetVORB != SIZE_MAX) && (sizeFMT != 0x28) && (sizeFMT != 0x18) && (sizeFMT != 0x12))
536  throw Common::Exception("WwRIFFVorbisStream::init(): Bad fmt size");
537 
538  if ((offsetVORB == SIZE_MAX) && (sizeFMT == 0x42))
539  offsetVORB = offsetFMT + 0x18;
540 
541  _inStream->seek(offsetFMT);
542  if (_inStream->readUint16LE() != 0xFFFF)
543  throw Common::Exception("WwRIFFVorbisStream::init(): Bad codec id");
544 
545  _channels = _inStream->readUint16LE();
546  _sampleRate = _inStream->readUint32LE();
547 
548  _averageBytesPerSecond = _inStream->readUint32LE();
549 
550  if (_inStream->readUint16LE() != 0)
551  throw Common::Exception("WwRIFFVorbisStream::init(): Bad block align");
552  if (_inStream->readUint16LE() != 0)
553  throw Common::Exception("WwRIFFVorbisStream::init(): Expected 0 bps");
554 
555  if (_inStream->readUint16LE() != (sizeFMT - 0x12))
556  throw Common::Exception("WwRIFFVorbisStream::init(): Bad extra fmt length");
557 
558  if (offsetSMPL != SIZE_MAX) {
559  _inStream->seek(offsetSMPL + 0x1C);
560  _loopCount = _inStream->readUint32LE();
561 
562  if (_loopCount != 1)
563  throw Common::Exception("WwRIFFVorbisStream::init(): Expected one loop");
564 
565  _inStream->seek(offsetSMPL + 0x2C);
566 
567  _loopStart = _inStream->readUint32LE();
568  _loopEnd = _inStream->readUint32LE();
569  }
570 
571  switch (sizeVORB) {
572  case SIZE_MAX:
573  case 0x28:
574  case 0x2A:
575  case 0x2C:
576  case 0x32:
577  case 0x34:
578  _inStream->seek(offsetVORB);
579  break;
580 
581  default:
582  throw Common::Exception("WwRIFFVorbisStream::init(): Bad vorb size");
583  }
584 
585  _sampleCount = _inStream->readUint32LE();
586 
587  switch (sizeVORB) {
588  case SIZE_MAX:
589  case 0x2A: {
590  _noGranule = true;
591 
592  _inStream->seek(offsetVORB + 0x4);
593  const uint32 modSignal = _inStream->readUint32LE();
594 
595  /* set
596  * D9 11011001
597  * CB 11001011
598  * BC 10111100
599  * B2 10110010
600  * unset
601  * 4A 01001010
602  * 4B 01001011
603  * 69 01101001
604  * 70 01110000
605  * A7 10100111 !!! */
606 
607  /* Seems to be 0xD9 when _modPackets should be set.
608  * Also seen 0xCB, 0xBC, 0xB2. */
609 
610  if ((modSignal != 0x4A) && (modSignal != 0x4B) && (modSignal != 0x69) && (modSignal != 0x70)) {
611  _modPackets = true;
612  }
613 
614  _inStream->seek(offsetVORB + 0x10);
615  break;
616  }
617 
618  default:
619  _inStream->seek(offsetVORB + 0x18);
620  break;
621  }
622 
623  _setupPacketOffset = _inStream->readUint32LE();
624  _firstAudioPacketOffset = _inStream->readUint32LE();
625 
626  switch (sizeVORB) {
627  case SIZE_MAX:
628  case 0x2A:
629  _inStream->seek(offsetVORB + 0x24);
630  break;
631 
632  case 0x32:
633  case 0x34:
634  _inStream->seek(offsetVORB + 0x2C);
635  break;
636  }
637 
638  switch(sizeVORB) {
639  case 0x28:
640  case 0x2C:
641  // Ok to leave _uid, _blocksize0Pow and _blocksize1Pow unset
642  _headerTriadPresent = true;
643  _oldPacketHeaders = true;
644  break;
645 
646  case SIZE_MAX:
647  case 0x2A:
648  case 0x32:
649  case 0x34:
650  _uid = _inStream->readUint32LE();
651  _blocksize0Pow = _inStream->readByte();
652  _blocksize1Pow = _inStream->readByte();
653  break;
654  }
655 
656  if (_loopCount != 0) {
657  _loopEnd = (_loopEnd == 0) ? _sampleCount : (_loopEnd + 1);
658 
660  throw Common::Exception("WwRIFFVorbisStream::init(): Loops out of range");
661  }
662 }
663 
665  stream.putBits('v', 8);
666  stream.putBits('o', 8);
667  stream.putBits('r', 8);
668  stream.putBits('b', 8);
669  stream.putBits('i', 8);
670  stream.putBits('s', 8);
671 }
672 
673 static void putVorbisHeader(Common::BitStreamWriter &stream, uint8 type) {
674  stream.putBits(type, 8);
675  putVorbisString(stream);
676 }
677 
679  Common::MemoryWriteStreamDynamic header(true, 32);
680  Common::BitStreamWriter8LSB bits(header);
681 
682  putVorbisHeader(bits, 1);
683 
684  bits.putBits(0, 32); // Version
685 
686  bits.putBits(_channels, 8);
687  bits.putBits(_sampleRate, 32);
688 
689  // Bitrate: max, nominal, min
690  bits.putBits(0, 32);
691  bits.putBits(_averageBytesPerSecond * 8, 32);
692  bits.putBits(0, 32);
693 
694  bits.putBits(_blocksize0Pow, 4);
695  bits.putBits(_blocksize1Pow, 4);
696 
697  bits.putBits(1, 1); // Framing
698 
699  bits.flush();
700 
701  header.setDisposable(false);
702  return new Common::MemoryReadStream(header.getData(), header.size(), true);
703 }
704 
706  Common::MemoryWriteStreamDynamic header(true, 16);
707  Common::BitStreamWriter8LSB bits(header);
708 
709  putVorbisHeader(bits, 3);
710 
711  bits.putBits(0, 32); // Length of vendor string
712  bits.putBits(0, 32); // Number of user comments
713 
714  bits.putBits(1, 1); // Framing
715 
716  bits.flush();
717 
718  header.setDisposable(false);
719  return new Common::MemoryReadStream(header.getData(), header.size(), true);
720 }
721 
724  Common::BitStreamWriter8LSB bits(header);
725 
726  putVorbisHeader(bits, 5);
727 
729 
730  _inStream->seek(setupPacket.offset());
731 
732  if (setupPacket.granule() != 0)
733  throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
734  "Setup packet granule != 0");
735 
736  const size_t startPos = _inStream->pos() * 8;
738 
739  // Codebook count
740  const size_t codebookCount = in.getBits(8) + 1;
741  bits.putBits(codebookCount - 1, 8);
742 
743  if (!_codebooks) {
744  CodebookLibrary cbl;
745 
746  for (size_t i = 0; i < codebookCount; i++) {
747  if (_fullSetup)
748  cbl.copy(in, bits);
749  else
750  cbl.rebuild(in, 0, bits);
751  }
752 
753  } else {
755 
756  for (size_t i = 0; i < codebookCount; i++) {
757  const uint16 codebookID = in.getBits(10);
758 
759  cbl.rebuild(codebookID, bits);
760  }
761  }
762 
763  // Time-domain transforms (placeholder)
764  bits.putBits(0, 6);
765  bits.putBits(0, 16);
766 
767  if (_fullSetup) {
768  while (in.pos() < (setupPacket.size() * 8))
769  bits.putBit(in.getBit());
770 
771  } else {
772  const size_t floorCount = in.getBits(6) + 1;
773  bits.putBits(floorCount - 1, 6);
774 
775  for (size_t i = 0; i < floorCount; i++) {
776  bits.putBits(1, 16); // Floor type
777 
778  const size_t floor1Partitions = in.getBits(5);
779  bits.putBits(floor1Partitions, 5);
780 
781  Common::ScopedArray<uint8> floor1PartitionClassList(new uint8[floor1Partitions]);
782  uint8 maxClass = 0;
783 
784  for (size_t j = 0; j < floor1Partitions; j++) {
785  floor1PartitionClassList[j] = in.getBits(4);
786  bits.putBits(floor1PartitionClassList[j], 4);
787 
788  maxClass = MAX(maxClass, floor1PartitionClassList[j]);
789  }
790 
791  Common::ScopedArray<uint8> floor1ClassDimensionsList(new uint8[maxClass + 1]);
792  for (size_t j = 0; j <= maxClass; j++) {
793  floor1ClassDimensionsList[j] = in.getBits(3) + 1;
794  bits.putBits(floor1ClassDimensionsList[j] - 1, 3);
795 
796  const uint8 subClasses = in.getBits(2);
797  bits.putBits(subClasses, 2);
798 
799  if (subClasses != 0) {
800  const uint8 masterbook = in.getBits(8);
801  bits.putBits(masterbook, 8);
802 
803  if (masterbook >= codebookCount)
804  throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
805  "Invalid floor1 masterbook");
806  }
807 
808  for (size_t k = 0; k < (1U << subClasses); k++) {
809  const int16 subClassBook = static_cast<int16>(in.getBits(8)) - 1;
810  bits.putBits(static_cast<uint16>(subClassBook + 1), 8);
811 
812  if (subClassBook >= 0 && (static_cast<size_t>(subClassBook) >= codebookCount))
813  throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
814  "Invalid floor1 subclass book");
815  }
816  }
817 
818  const uint8 floor1Multiplier = in.getBits(2) + 1;
819  bits.putBits(floor1Multiplier - 1, 2);
820 
821  const uint8 rangeBits = in.getBits(4);
822  bits.putBits(rangeBits, 4);
823 
824  for (size_t j = 0; j < floor1Partitions; j++) {
825  const uint8 currentClassNumber = floor1PartitionClassList[j];
826 
827  for (size_t k = 0; k < floor1ClassDimensionsList[currentClassNumber]; k++)
828  bits.putBits(in.getBits(rangeBits), rangeBits);
829 
830  }
831  }
832 
833  const size_t residueCount = in.getBits(6) + 1;
834  bits.putBits(residueCount - 1, 6);
835 
836  for (size_t i = 0; i < residueCount; i++) {
837  const uint8 residueType = in.getBits(2);
838  bits.putBits(residueType, 16);
839 
840  if (residueType > 2)
841  throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
842  "Invalid residue type");
843 
844  // Residues: begin, end, partition size
845  bits.putBits(in.getBits(24), 24);
846  bits.putBits(in.getBits(24), 24);
847  bits.putBits(in.getBits(24), 24);
848 
849  const size_t residueClassifications = in.getBits(6) + 1;
850  bits.putBits(residueClassifications - 1, 6);
851 
852  const uint8 residueClassbook = in.getBits(8);
853  bits.putBits(residueClassbook, 8);
854 
855  if (residueClassbook >= codebookCount)
856  throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
857  "Invalid residue classbook");
858 
859  Common::ScopedArray<uint16> residueCascade(new uint16[residueClassifications]);
860  for (size_t j = 0; j < residueClassifications; j++) {
861  const uint8 lowBits = in.getBits(3);
862  bits.putBits(lowBits, 3);
863 
864  const uint8 bitFlag = in.getBit();
865  bits.putBit(bitFlag);
866 
867  uint8 highBits = 0;
868  if (bitFlag) {
869  highBits = in.getBits(5);
870  bits.putBits(highBits, 5);
871  }
872 
873  residueCascade[j] = highBits * 8 + lowBits;
874  }
875 
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);
880  bits.putBits(residueBook, 8);
881 
882  if (residueBook >= codebookCount)
883  throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
884  "Invalid residue book");
885  }
886  }
887  }
888  }
889 
890  const size_t mappingCount = in.getBits(6) + 1;
891  bits.putBits(mappingCount - 1, 6);
892 
893  for (size_t i = 0; i < mappingCount; i++) {
894  bits.putBits(0, 16); // Mapping type
895 
896  const uint8 subMapsFlag = in.getBit();
897  bits.putBit(subMapsFlag);
898 
899  uint8 subMaps = 1;
900  if (subMapsFlag) {
901  subMaps = in.getBits(4) + 1;
902  bits.putBits(subMaps - 1, 4);
903  }
904 
905  const uint8 squarePolarFlag = in.getBit();
906  bits.putBit(squarePolarFlag);
907 
908  if (squarePolarFlag) {
909  const size_t couplingSteps = in.getBits(8) + 1;
910  bits.putBits(couplingSteps - 1, 8);
911 
912  for (size_t j = 0; j < couplingSteps; j++) {
913  const size_t bitCount = Common::intLog2(_channels - 1) + 1;
914 
915  const uint32 magnitude = in.getBits(bitCount);
916  const uint32 angle = in.getBits(bitCount);
917 
918  bits.putBits(magnitude, bitCount);
919  bits.putBits(angle, bitCount);
920 
921  if ((angle == magnitude) || (magnitude >= _channels) || (angle >= _channels))
922  throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
923  "Invalid coupling");
924  }
925  }
926 
927  const uint8 mappingReserved = in.getBits(2);
928  bits.putBits(mappingReserved, 2);
929 
930  if (mappingReserved != 0)
931  throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
932  "Mapping reserved field nonzero");
933 
934  if (subMaps > 1) {
935  for (size_t j = 0; j < _channels; j++) {
936  const uint8 MappingMux = in.getBits(4);
937  bits.putBits(MappingMux, 4);
938 
939  if (MappingMux >= subMaps)
940  throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
941  "MappingMux >= subMaps");
942  }
943  }
944 
945  for (size_t j = 0; j < subMaps; j++) {
946  const uint8 timeConfig = in.getBits(8);
947  const uint8 floorNumber = in.getBits(8);
948  const uint8 residueNumber = in.getBits(8);
949 
950  bits.putBits(timeConfig , 8);
951  bits.putBits(floorNumber , 8);
952  bits.putBits(residueNumber, 8);
953 
954  if (floorNumber >= floorCount)
955  throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
956  "Invalid floor mapping");
957  if (residueNumber >= residueCount)
958  throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
959  "Invalid residue mapping");
960  }
961  }
962 
963  const size_t modeCount = in.getBits(6) + 1;
964  bits.putBits(modeCount - 1, 6);
965 
966  _modeBlockFlags.reset(new bool[modeCount]);
967  _modeBits = Common::intLog2(modeCount - 1) + 1;
968 
969  for (size_t i = 0; i < modeCount; i++) {
970  _modeBlockFlags[i] = in.getBit();
971  bits.putBit(_modeBlockFlags[i]);
972 
973  bits.putBits(0, 16); // Window type
974  bits.putBits(0, 16); // Transform type
975 
976  const uint8 mapping = in.getBits(8);
977  bits.putBits(mapping, 8);
978 
979  if (mapping >= mappingCount)
980  throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
981  "Invalid mode mapping");
982  }
983 
984  }
985 
986  bits.putBits(1, 1); // Framing
987 
988  bits.flush();
989 
990  if (((in.pos() - startPos + 7) / 8) != setupPacket.size())
991  throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
992  "Didn't read the exact size of the setup packet");
993 
994  if (setupPacket.nextOffset() != (_dataOffset + static_cast<size_t>(_firstAudioPacketOffset)))
995  throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
996  "First audio packet doesn't follow setup packet");
997 
998  header.setDisposable(false);
999  return new Common::MemoryReadStream(header.getData(), header.size(), true);
1000 }
1001 
1004  return 0;
1005 
1006  Common::MemoryWriteStreamDynamic header(true);
1007  Common::BitStreamWriter8LSB bits(header);
1008 
1009  Packet audioPacket(*_inStream, _currentOffset, _noGranule);
1010 
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();
1015 
1016  if (_currentOffset + packerHeaderSize > _dataOffset + _dataSize)
1017  throw Common::Exception("WwRIFFVorbisStream::createPacket(): "
1018  "Page header truncated");
1019 
1020  _currentOffset = packetPayloadOffset;
1021  _inStream->seek(_currentOffset);
1022 
1023  Common::ScopedPtr<Common::SeekableReadStream> packetStream(_inStream->readStream(size));
1024 
1025  _currentOffset = nextOffset;
1026 
1028  throw Common::Exception("WwRIFFVorbisStream::createPacket(): "
1029  "Page truncated");
1030 
1031  return packetStream.release();
1032 }
1033 
1034 
1036  bool disposeAfterUse) {
1037 
1038  Common::MemoryReadStream *codebook = new Common::MemoryReadStream(kCodeBook, sizeof(kCodeBook), false);
1039 
1040  return new WwRIFFVorbisStream(wwRIFFVorbis, disposeAfterUse, codebook, true, false);
1041 }
1042 
1043 } // End of namespace Sound
uint64 getLength() const
Estimate the total number of samples per channel in this stream.
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 &#39;DATA&#39;, to ensure portability.
Definition: endianness.h:140
uint16 readUint16LE()
Read an unsigned 16-bit word stored in little endian (LSB first) order from the stream and return it...
Definition: readstream.h:122
A template implementing a bit stream writer for different data memory layouts.
static int intLog2(uint32 v)
Definition: maths.h:83
uint32 readUint32LE()
Read an unsigned 32-bit word stored in little endian (LSB first) order from the stream and return it...
Definition: readstream.h:133
A stream that dynamically grows as it&#39;s written to.
void putBit(bool bit)
Write a bit to the bit stream.
A class holding an UTF-8 string.
Definition: ustring.h:48
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.
Definition: scopedptr.h:87
PointerType release()
Returns the plain pointer value and releases ScopedPtr.
Definition: scopedptr.h:103
UString composeString(T value)
Convert any POD integer, float/double or bool type into a string.
Definition: strutil.cpp:276
uint64_t uint64
Definition: types.h:206
uint8_t uint8
Definition: types.h:200
virtual size_t pos() const =0
Return the stream position in bits.
Mathematical helpers.
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.
size_t headerSize()
PacketizedAudioStream * makePacketizedVorbisStream(Common::SeekableReadStream &extraData)
Create a new PacketizedAudioStream capable of decoding vorbis audio data.
Definition: vorbis.cpp:524
uint32 getBit()
Read a bit from the bit stream.
Definition: bitstream.h:153
uint32 getBits(size_t n)
Read a multi-bit value from the bit stream.
Definition: bitstream.h:178
size_t pos() const
Return the stream position in bits.
Definition: bitstream.h:227
int getChannels() const
Return the number channels in this stream.
Utility templates and functions for working with strings and streams.
int16_t int16
Definition: types.h:201
Sound::RewindableAudioStream * makeWwRIFFVorbisStream(Common::SeekableReadStream *wwRIFFVorbis, bool disposeAfterUse)
Exception that provides a stack of explanations.
Definition: error.h:36
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...
Definition: game.h:37
A bit stream writer.
size_t size() const
Return the number of bytes written to this stream in total.
Basic exceptions to throw.
A rewindable audio stream.
Definition: audiostream.h:125
const char * c_str() const
Return the (utf8 encoded) string data.
Definition: ustring.cpp:249
Common::SeekableReadStream * generateHeaderSetup()
uint16_t uint16
Definition: types.h:202
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.
uint32 _absoluteGranule
Simple memory based &#39;stream&#39;, which implements the ReadStream interface for a plain memory block...
Definition: memreadstream.h:66
Utility functions for working with differing string encodings.
Low-level type definitions to handle fixed width types portably.
StackException Exception
Definition: error.h:59
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.
A bit stream.
A bit stream writer.
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).
Definition: encoding.h:40
A smart pointer with a deletion flag.
size_t size() const
Return the stream size in bits.
Definition: bitstream.h:236
Decoding Ogg Vorbis.
Common::ScopedArray< bool > _modeBlockFlags
void rebuild(size_t i, Common::BitStreamWriter &bos)
uint32_t uint32
Definition: types.h:204
Common::SeekableReadStream * generateHeaderIdentification()
Common::SeekableReadStream * createPacket()
uint32 granule()
virtual void putBit(bool bit)=0
Write a bit to the bit stream.
size_t nextOffset()
Common::ScopedPtr< Sound::PacketizedAudioStream > _vorbis
static void putVorbisString(Common::BitStreamWriter &stream)
void copy(Common::BitStream &bis, Common::BitStreamWriter &bos)
#define SIZE_MAX
Definition: types.h:172
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.
Definition: bitstream.h:85
UString readStringFixed(SeekableReadStream &stream, Encoding encoding, size_t length)
Read length bytes as a string with the given encoding out of a stream.
Definition: encoding.cpp:297
SeekableSubReadStream provides access to a SeekableReadStream restricted to the range [begin...
Definition: readstream.h:359
static const byte kCodeBook[]
T MAX(T a, T b)
Definition: util.h:71
Interface for a seekable & readable data stream.
Definition: readstream.h:265
void putBits(uint32 bits, size_t n)
Write a multi-bit value to the bit stream.
Streaming audio.
A bit stream.
Definition: bitstream.h:40
Common::SeekableReadStream * generateHeaderComment()
Common::SeekableReadStream * getCodebook(size_t i)