xoreos  0.0.5
adpcm.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 
25 /* Based on ScummVM (<http://scummvm.org>) code, which is released
26  * under the terms of version 2 or later of the GNU General Public
27  * License.
28  *
29  * The original copyright note in ScummVM reads as follows:
30  *
31  * ScummVM is the legal property of its developers, whose names
32  * are too numerous to list here. Please refer to the COPYRIGHT
33  * file distributed with this source distribution.
34  *
35  * This program is free software; you can redistribute it and/or
36  * modify it under the terms of the GNU General Public License
37  * as published by the Free Software Foundation; either version 2
38  * of the License, or (at your option) any later version.
39  *
40  * This program is distributed in the hope that it will be useful,
41  * but WITHOUT ANY WARRANTY; without even the implied warranty of
42  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43  * GNU General Public License for more details.
44  *
45  * You should have received a copy of the GNU General Public License
46  * along with this program; if not, write to the Free Software
47  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
48  */
49 
50 #include <cassert>
51 #include <cstring>
52 
53 #include "src/common/endianness.h"
55 
57 #include "src/sound/audiostream.h"
58 
59 namespace Sound {
60 
62 protected:
64  const size_t _size;
65  const size_t _startpos;
66  const size_t _endpos;
67  const int _channels;
70  const int _rate;
71 
73 
74  struct {
75  // OKI/IMA
76  struct {
79  } ima_ch[2];
80  } _status;
81 
82  virtual void reset();
84 
85 public:
86  ADPCMStream(Common::SeekableReadStream *stream, bool disposeAfterUse, size_t size, int rate, int channels, uint32 blockAlign);
87  ~ADPCMStream();
88 
89  virtual bool endOfData() const { return (_stream->eos() || _stream->pos() >= _endpos); }
90  virtual int getChannels() const { return _channels; }
91  virtual int getRate() const { return _rate; }
92  virtual uint64 getLength() const { return _length; }
93 
94  virtual bool rewind();
95 };
96 
97 
98 // IMA ADPCM support is based on
99 // <http://wiki.multimedia.cx/index.php?title=IMA_ADPCM>
100 //
101 // In addition, also MS IMA ADPCM is supported. See
102 // <http://wiki.multimedia.cx/index.php?title=Microsoft_IMA_ADPCM>.
103 
104 ADPCMStream::ADPCMStream(Common::SeekableReadStream *stream, bool disposeAfterUse, size_t size, int rate, int channels, uint32 blockAlign)
105  : _stream(stream, disposeAfterUse),
106  _size(size),
107  _startpos(stream->pos()),
108  _endpos(_startpos + _size),
109  _channels(channels),
110  _blockAlign(blockAlign),
111  _rate(rate),
112  _length(kInvalidLength) {
113 
114  reset();
115 }
116 
118 }
119 
121  std::memset(&_status, 0, sizeof(_status));
122  _blockPos[0] = _blockPos[1] = _blockAlign; // To make sure first header is read
123 }
124 
126  // TODO: Error checking.
127  reset();
128  _stream->seek(_startpos);
129  return true;
130 }
131 
132 class Ima_ADPCMStream : public ADPCMStream {
133 protected:
134  int16 decodeIMA(byte code, int channel = 0); // Default to using the left channel/using one channel
135 
136 public:
137  Ima_ADPCMStream(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
138  : ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) {
139  std::memset(&_status, 0, sizeof(_status));
140 
141  // 2 samples per input byte
142  _length = _size * 2 / _channels;
143  }
144 
145  virtual size_t readBuffer(int16 *buffer, const size_t numSamples);
146 };
147 
148 size_t Ima_ADPCMStream::readBuffer(int16 *buffer, const size_t numSamples) {
149  size_t samples;
150  byte data;
151 
152  assert(numSamples % 2 == 0);
153 
154  for (samples = 0; samples < numSamples && !_stream->eos() && _stream->pos() < _endpos; samples += 2) {
155  data = _stream->readByte();
156  buffer[samples] = decodeIMA((data >> 4) & 0x0f);
157  buffer[samples + 1] = decodeIMA(data & 0x0f, _channels == 2 ? 1 : 0);
158  }
159  return samples;
160 }
161 
163 protected:
164  // Apple QuickTime IMA ADPCM
165  size_t _streamPos[2];
166  int16 _buffer[2][2];
168 
169  void reset() {
171  _chunkPos[0] = 0;
172  _chunkPos[1] = 0;
173  _streamPos[0] = 0;
174  _streamPos[1] = _blockAlign;
175  }
176 
177 public:
178  Apple_ADPCMStream(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
179  : Ima_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) {
180  _chunkPos[0] = 0;
181  _chunkPos[1] = 0;
182  _streamPos[0] = 0;
183  _streamPos[1] = _blockAlign;
184 
185  // 2 samples per input byte, but 2 byte header per block
186  _length = ((_size / _blockAlign) * (_blockAlign - 2) * 2) / channels;
187  }
188 
189  virtual size_t readBuffer(int16 *buffer, const size_t numSamples);
190 
191 };
192 
193 size_t Apple_ADPCMStream::readBuffer(int16 *buffer, const size_t numSamples) {
194  // Need to write at least one samples per channel
195  assert((numSamples % _channels) == 0);
196 
197  // Current sample positions
198  size_t samples[2] = { 0, 0};
199 
200  // Number of samples per channel
201  size_t chanSamples = numSamples / _channels;
202 
203  for (int i = 0; i < _channels; i++) {
204  _stream->seek(_streamPos[i]);
205 
206  while ((samples[i] < chanSamples) &&
207  // Last byte read and a new one needed
208  !((_stream->eos() || (_stream->pos() >= _endpos)) && (_chunkPos[i] == 0))) {
209 
210  if (_blockPos[i] == _blockAlign) {
211  // 2 byte header per block
212  uint16 temp = _stream->readUint16BE();
213 
214  // First 9 bits are the upper bits of the predictor
215  _status.ima_ch[i].last = (int16) (temp & 0xFF80);
216  // Lower 7 bits are the step index
217  _status.ima_ch[i].stepIndex = temp & 0x007F;
218 
219  // Clip the step index
220  _status.ima_ch[i].stepIndex = CLIP<int32>(_status.ima_ch[i].stepIndex, 0, 88);
221 
222  _blockPos[i] = 2;
223  }
224 
225  if (_chunkPos[i] == 0) {
226  // Decode data
227  byte data = _stream->readByte();
228  _buffer[i][0] = decodeIMA(data & 0x0F, i);
229  _buffer[i][1] = decodeIMA(data >> 4, i);
230  }
231 
232  // The original is interleaved block-wise, we want it sample-wise
233  buffer[_channels * samples[i] + i] = _buffer[i][_chunkPos[i]];
234 
235  if (++_chunkPos[i] > 1) {
236  // We're about to decode the next byte, so advance the block position
237  _chunkPos[i] = 0;
238  _blockPos[i]++;
239  }
240 
241  samples[i]++;
242 
243  if (_channels == 2)
244  if (_blockPos[i] == _blockAlign)
245  // We're at the end of the block.
246  // Since the channels are interleaved, skip the next block
247  _stream->skip(MIN<size_t>(_blockAlign, _endpos - _stream->pos()));
248 
249  _streamPos[i] = _stream->pos();
250  }
251  }
252 
253  return samples[0] + samples[1];
254 }
255 
257 public:
258  MSIma_ADPCMStream(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
259  : Ima_ADPCMStream(stream, disposeAfterUse, size - (size % ((blockAlign == 0) ? 1 : blockAlign)),
260  rate, channels, blockAlign) {
261 
262  if (blockAlign == 0)
263  error("MSIma_ADPCMStream(): blockAlign isn't specified");
264 
265  if (blockAlign % (_channels * 4))
266  error("MSIma_ADPCMStream(): invalid blockAlign");
267 
268  _samplesLeft[0] = 0;
269  _samplesLeft[1] = 0;
270 
271  // 2 samples per input byte, but 4 byte header per block per channel
272  _length = ((_size / _blockAlign) * (_blockAlign - (4 * channels)) * 2) / channels;
273  }
274 
275  size_t readBuffer(int16 *buffer, const size_t numSamples);
276 
277  void reset() {
279  _samplesLeft[0] = 0;
280  _samplesLeft[1] = 0;
281  }
282 
283 private:
284  int16 _buffer[2][8];
285  int _samplesLeft[2];
286 };
287 
288 size_t MSIma_ADPCMStream::readBuffer(int16 *buffer, const size_t numSamples) {
289  // Need to write at least one sample per channel
290  assert((numSamples % _channels) == 0);
291 
292  size_t samples = 0;
293 
294  while (samples < numSamples && !_stream->eos() && _stream->pos() < _endpos) {
295  if (_blockPos[0] == _blockAlign) {
296  for (int i = 0; i < _channels; i++) {
297  // read block header
298  _status.ima_ch[i].last = _stream->readSint16LE();
299  _status.ima_ch[i].stepIndex = _stream->readSint16LE();
300  }
301 
302  _blockPos[0] = _channels * 4;
303  }
304 
305  if (_samplesLeft[0] == 0) {
306  // Decode a set of samples
307  for (int i = 0; i < _channels; i++) {
308  for (int j = 0; j < 4; j++) {
309  byte data = _stream->readByte();
310  _blockPos[0]++;
311  _buffer[i][j * 2] = decodeIMA(data & 0x0f, i);
312  _buffer[i][j * 2 + 1] = decodeIMA((data >> 4) & 0x0f, i);
313  _samplesLeft[i] += 2;
314  }
315  }
316  }
317 
318  while (samples < numSamples && _samplesLeft[0] != 0) {
319  for (int i = 0; i < _channels; i++) {
320  buffer[samples + i] = _buffer[i][8 - _samplesLeft[i]];
321  _samplesLeft[i]--;
322  }
323 
324  samples += _channels;
325  }
326  }
327 
328  return samples;
329 }
330 
331 
332 static const int MSADPCMAdaptCoeff1[] = {
333  256, 512, 0, 192, 240, 460, 392
334 };
335 
336 static const int MSADPCMAdaptCoeff2[] = {
337  0, -256, 0, 64, 0, -208, -232
338 };
339 
340 static const int MSADPCMAdaptationTable[] = {
341  230, 230, 230, 230, 307, 409, 512, 614,
342  768, 614, 512, 409, 307, 230, 230, 230
343 };
344 
345 
346 class MS_ADPCMStream : public ADPCMStream {
347 protected:
355  };
356 
357  struct {
358  // MS ADPCM
360  } _status;
361 
362  void reset() {
364  std::memset(&_status, 0, sizeof(_status));
365  }
366 
367 public:
368  MS_ADPCMStream(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
369  : ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) {
370  if (blockAlign == 0)
371  error("MS_ADPCMStream(): blockAlign isn't specified for MS ADPCM");
372  std::memset(&_status, 0, sizeof(_status));
373 
374  // 2 samples per input byte, but 7 byte header per block per channel
375  _length = ((_size / _blockAlign) * (_blockAlign - (7 * channels)) * 2) / channels;
376  }
377 
378  virtual size_t readBuffer(int16 *buffer, const size_t numSamples);
379 
380 protected:
381  int16 decodeMS(ADPCMChannelStatus *c, byte);
382 };
383 
385  int32 predictor;
386 
387  predictor = (((c->sample1) * (c->coeff1)) + ((c->sample2) * (c->coeff2))) / 256;
388  predictor += (signed)((code & 0x08) ? (code - 0x10) : (code)) * c->delta;
389 
390  predictor = CLIP<int32>(predictor, -32768, 32767);
391 
392  c->sample2 = c->sample1;
393  c->sample1 = predictor;
394  c->delta = (MSADPCMAdaptationTable[(int)code] * c->delta) >> 8;
395 
396  if (c->delta < 16)
397  c->delta = 16;
398 
399  return (int16)predictor;
400 }
401 
402 size_t MS_ADPCMStream::readBuffer(int16 *buffer, const size_t numSamples) {
403  size_t samples;
404  byte data;
405  int i = 0;
406 
407  samples = 0;
408 
409  while (samples < numSamples && !_stream->eos() && _stream->pos() < _endpos) {
410  if (_blockPos[0] == _blockAlign) {
411  // read block header
412  for (i = 0; i < _channels; i++) {
413  _status.ch[i].predictor = CLIP(_stream->readByte(), (byte)0, (byte)6);
414  _status.ch[i].coeff1 = MSADPCMAdaptCoeff1[_status.ch[i].predictor];
415  _status.ch[i].coeff2 = MSADPCMAdaptCoeff2[_status.ch[i].predictor];
416  }
417 
418  for (i = 0; i < _channels; i++)
419  _status.ch[i].delta = _stream->readSint16LE();
420 
421  for (i = 0; i < _channels; i++)
422  _status.ch[i].sample1 = _stream->readSint16LE();
423 
424  for (i = 0; i < _channels; i++)
425  buffer[samples++] = _status.ch[i].sample2 = _stream->readSint16LE();
426 
427  for (i = 0; i < _channels; i++)
428  buffer[samples++] = _status.ch[i].sample1;
429 
430  _blockPos[0] = _channels * 7;
431  }
432 
433  for (; samples < numSamples && _blockPos[0] < _blockAlign && !_stream->eos() && _stream->pos() < _endpos; samples += 2) {
434  data = _stream->readByte();
435  _blockPos[0]++;
436  buffer[samples] = decodeMS(&_status.ch[0], (data >> 4) & 0x0f);
437  buffer[samples + 1] = decodeMS(&_status.ch[_channels - 1], data & 0x0f);
438  }
439  }
440 
441  return samples;
442 }
443 
444 // adjust the step for use on the next sample.
446  static const int16 adjusts[] = {-1, -1, -1, -1, 2, 4, 6, 8};
447 
448  return adjusts[code & 0x07];
449 }
450 
451 static const uint16 imaStepTable[89] = {
452  7, 8, 9, 10, 11, 12, 13, 14,
453  16, 17, 19, 21, 23, 25, 28, 31,
454  34, 37, 41, 45, 50, 55, 60, 66,
455  73, 80, 88, 97, 107, 118, 130, 143,
456  157, 173, 190, 209, 230, 253, 279, 307,
457  337, 371, 408, 449, 494, 544, 598, 658,
458  724, 796, 876, 963, 1060, 1166, 1282, 1411,
459  1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
460  3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
461  7132, 7845, 8630, 9493,10442,11487,12635,13899,
462  15289,16818,18500,20350,22385,24623,27086,29794,
463  32767
464 };
465 
467  int32 E = (2 * (code & 0x7) + 1) * imaStepTable[_status.ima_ch[channel].stepIndex] / 8;
468  int32 diff = (code & 0x08) ? -E : E;
469  int32 samp = CLIP<int32>(_status.ima_ch[channel].last + diff, -32768, 32767);
470 
471  _status.ima_ch[channel].last = samp;
472  _status.ima_ch[channel].stepIndex += stepAdjust(code);
473  _status.ima_ch[channel].stepIndex = CLIP<int32>(_status.ima_ch[channel].stepIndex, 0, ARRAYSIZE(imaStepTable) - 1);
474 
475  return samp;
476 }
477 
478 /* Xbox ADPCM decoder, heavily based on Luigi Auriemma's xbadpdec tool
479  * (<http://aluigi.altervista.org/papers.htm#xbox>), which is licensed
480  * under the terms of the GPLv2.
481  *
482  * xbadpdec in turn is based on the TXboxAdpcmDecoder class by Benjamin
483  * Haisch.
484  *
485  * The original copyright note in xbadpdec reads as follows:
486  *
487  * Copyright 2005,2006 Luigi Auriemma
488  *
489  * This program is free software; you can redistribute it and/or modify
490  * it under the terms of the GNU General Public License as published by
491  * the Free Software Foundation; either version 2 of the License, or
492  * (at your option) any later version.
493  *
494  * This program is distributed in the hope that it will be useful,
495  * but WITHOUT ANY WARRANTY; without even the implied warranty of
496  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
497  * GNU General Public License for more details.
498  *
499  * You should have received a copy of the GNU General Public License
500  * along with this program; if not, write to the Free Software
501  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
502  *
503  * http://www.gnu.org/licenses/gpl.txt
504  */
506 public:
507  Xbox_ADPCMStream(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
508  : ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign == 0 ? 36 : blockAlign) {
509  std::memset(&_status, 0, sizeof(_status));
510 
511  if (_blockAlign != 36)
512  throw Common::Exception("Xbox_ADPCMStream(): invalid blockAlign");
513 
514  if ((channels != 1) && (channels != 2))
515  throw Common::Exception("Xbox_ADPCMStream(): invalid channel count");
516 
517  /* Calculate the length of the audio in samples (for one channel).
518  * For each 4 bytes, 8 samples are produced. Additional, the 4 bytes
519  * header produces 1 sample.
520  *
521  * So with a block align of 36, 65 samples are produced for each full
522  * block. One for the 4 byte header, and 64 for the 32 byte of data.
523  *
524  * If we have overhang, i.e. a non-full block at the end of the stream,
525  * we need to add one for the header, and 8 for each 4 following bytes. */
526 
527  const uint32 wholeBlocks = (_size / (channels * _blockAlign));
528  const uint32 overhang = (_size % (channels * _blockAlign));
529 
530  if ((overhang % 4) != 0)
531  throw Common::Exception("Xbox_ADPCMStream(): unaligned input size");
532 
533  const bool hasOverhang = overhang > 4;
534 
535  const uint32 blockDataSize = wholeBlocks * (_blockAlign - 4) + (hasOverhang ? (overhang - 4) : 0);
536  const uint32 blockCount = wholeBlocks + (hasOverhang ? 1 : 0);
537 
538  _length = (blockDataSize / 4) * 8 + blockCount;
539 
540  reset();
541  }
542 
543  virtual size_t readBuffer(int16 *buffer, const size_t numSamples);
544 
545 protected:
546  void reset() {
548  std::memset(&_status, 0, sizeof(_status));
549 
550  _blockPos[0] = _blockAlign;
551  _blockPos[1] = 8;
552  }
553 
554 private:
559 
561  };
562 
563  struct {
565  } _status;
566 
567  int16 decodeXbox(int code, ADPCMChannelStatus &status);
568 };
569 
570 static const int8 kXboxIndexTable[16] = {
571  -1, -1, -1, -1, 2, 4, 6, 8,
572  -1, -1, -1, -1, 2, 4, 6, 8
573 };
574 
576  int delta = status.stepSize >> 3;
577 
578  if (code & 4)
579  delta += status.stepSize;
580  if (code & 2)
581  delta += status.stepSize >> 1;
582  if (code & 1)
583  delta += status.stepSize >> 2;
584  if (code & 8)
585  delta = -delta;
586 
587  const int16 result = CLIP<int>(status.predictor + delta, -32768, 32767);
588 
589  status.index = CLIP<int>(status.index + kXboxIndexTable[code], 0, 88);
590  status.stepSize = imaStepTable[status.index];
591  status.predictor = result;
592 
593  return result;
594 }
595 
596 size_t Xbox_ADPCMStream::readBuffer(int16 *buffer, const size_t numSamples) {
597  if (_channels == 2)
598  assert(numSamples % 2 == 0);
599 
600  size_t samples = 0;
601 
602  while (samples < numSamples && !_stream->eos() && _stream->pos() < _endpos) {
603  if ((_blockPos[0] == _blockAlign) && (_blockPos[1] == 8)) {
604  for (int c = 0; c < _channels; c++) {
605  _status.ch[c].predictor = _stream->readSint16LE();
606  _status.ch[c].index = _stream->readSint16LE();
607 
608  _status.ch[c].index = CLIP<int16>(_status.ch[c].index, 0, 88);
609  _status.ch[c].stepSize = imaStepTable[_status.ch[c].index];
610 
611  buffer[samples++] = _status.ch[c].predictor;
612  }
613 
614  _blockPos[0] = 4;
615  continue;
616  }
617 
618  if (_blockPos[1] == 8) {
619  for (int c = 0; c < _channels; c++) {
620  uint32 code = _stream->readUint32LE();
621  for (size_t j = 0; j < 8; j++) {
622  _status.ch[c].buffer[j] = decodeXbox(code & 0x0F, _status.ch[c]);
623  code >>= 4;
624  }
625  }
626 
627  _blockPos[0] += 4;
628  _blockPos[1] = 0;
629  }
630 
631  for (int c = 0; c < _channels; c++)
632  buffer[samples++] = _status.ch[c].buffer[_blockPos[1]];
633 
634  _blockPos[1]++;
635  }
636 
637  return samples;
638 }
639 
640 RewindableAudioStream *makeADPCMStream(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 size, ADPCMTypes type, int rate, int channels, uint32 blockAlign) {
641  switch (type) {
642  case kADPCMMSIma:
643  return new MSIma_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign);
644  case kADPCMMS:
645  return new MS_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign);
646  case kADPCMApple:
647  return new Apple_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign);
648  case kADPCMXbox:
649  return new Xbox_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign);
650  default:
651  error("Unsupported ADPCM encoding");
652  break;
653  }
654 }
655 
657 public:
658  PacketizedADPCMStream(ADPCMTypes type, int rate, int channels, uint32 blockAlign) :
659  StatelessPacketizedAudioStream(rate, channels), _type(type), _blockAlign(blockAlign) {}
660 
661 protected:
663 
664 private:
667 };
668 
670  return makeADPCMStream(data, true, data->size(), _type, getRate(), getChannels(), _blockAlign);
671 }
672 
673 PacketizedAudioStream *makePacketizedADPCMStream(ADPCMTypes type, int rate, int channels, uint32 blockAlign) {
674  return new PacketizedADPCMStream(type, rate, channels, blockAlign);
675 }
676 
677 } // End of namespace Sound
size_t readBuffer(int16 *buffer, const size_t numSamples)
Fill the given buffer with up to numSamples samples.
Definition: adpcm.cpp:288
PacketizedAudioStream * makePacketizedADPCMStream(ADPCMTypes type, int rate, int channels, uint32 blockAlign)
Creates a PacketizedAudioStream that will automatically queue packets as individual AudioStreams like...
Definition: adpcm.cpp:673
int getRate() const
Sample rate of the stream.
Definition: audiostream.h:308
int16 _buffer[2][2]
Definition: adpcm.cpp:166
Common::DisposablePtr< Common::SeekableReadStream > _stream
Definition: adpcm.cpp:63
MSIma_ADPCMStream(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
Definition: adpcm.cpp:258
static const int MSADPCMAdaptationTable[]
Definition: adpcm.cpp:340
virtual int getRate() const
Sample rate of the stream.
Definition: adpcm.cpp:91
Ima_ADPCMStream(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
Definition: adpcm.cpp:137
uint64_t uint64
Definition: types.h:206
uint8_t uint8
Definition: types.h:200
struct Sound::Xbox_ADPCMStream::@15 _status
A PacketizedAudioStream that works closer to a QueuingAudioStream.
Definition: audiostream.h:300
Low-level macros and functions to handle different endianness portably.
int16 decodeMS(ADPCMChannelStatus *c, byte)
Definition: adpcm.cpp:384
#define ARRAYSIZE(x)
Macro which determines the number of entries in a fixed size array.
Definition: util.h:131
PacketizedADPCMStream(ADPCMTypes type, int rate, int channels, uint32 blockAlign)
Definition: adpcm.cpp:658
int16_t int16
Definition: types.h:201
Exception that provides a stack of explanations.
Definition: error.h:36
ADPCMChannelStatus ch[2]
Definition: adpcm.cpp:359
int16 _buffer[2][8]
Definition: adpcm.cpp:284
uint32 _blockPos[2]
Definition: adpcm.cpp:69
Definition: game.h:37
Decoding ADPCM (Adaptive Differential Pulse Code Modulation).
A rewindable audio stream.
Definition: audiostream.h:125
virtual uint64 getLength() const
Estimate the total number of samples per channel in this stream.
Definition: adpcm.cpp:92
virtual int getChannels() const
Return the number channels in this stream.
Definition: adpcm.cpp:90
const size_t _size
Definition: adpcm.cpp:64
virtual size_t readBuffer(int16 *buffer, const size_t numSamples)
Fill the given buffer with up to numSamples samples.
Definition: adpcm.cpp:402
int getChannels() const
Return the number channels in this stream.
Definition: audiostream.h:307
Xbox_ADPCMStream(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
Definition: adpcm.cpp:507
uint16_t uint16
Definition: types.h:202
int16 stepAdjust(byte)
Definition: adpcm.cpp:445
int16 decodeIMA(byte code, int channel=0)
Definition: adpcm.cpp:466
RewindableAudioStream * makeADPCMStream(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 size, ADPCMTypes type, int rate, int channels, uint32 blockAlign)
Takes an input stream containing ADPCM compressed sound data and creates an RewindableAudioStream fro...
Definition: adpcm.cpp:640
An AudioStream designed to work in terms of packets.
Definition: audiostream.h:271
struct Sound::MS_ADPCMStream::@14 _status
StackException Exception
Definition: error.h:59
uint64 _length
Definition: adpcm.cpp:72
static const int8 kXboxIndexTable[16]
Definition: adpcm.cpp:570
virtual size_t size() const =0
Obtains the total size of the stream, measured in bytes.
AudioStream * makeStream(Common::SeekableReadStream *data)
Make the AudioStream for a given packet.
Definition: adpcm.cpp:669
ADPCMTypes
Definition: adpcm.h:65
const size_t _startpos
Definition: adpcm.cpp:65
ADPCMStream(Common::SeekableReadStream *stream, bool disposeAfterUse, size_t size, int rate, int channels, uint32 blockAlign)
Definition: adpcm.cpp:104
const int _channels
Definition: adpcm.cpp:67
Generic audio input stream.
Definition: audiostream.h:70
const int _rate
Definition: adpcm.cpp:70
A smart pointer with a deletion flag.
static const int MSADPCMAdaptCoeff1[]
Definition: adpcm.cpp:332
int8_t int8
Definition: types.h:199
virtual size_t readBuffer(int16 *buffer, const size_t numSamples)
Fill the given buffer with up to numSamples samples.
Definition: adpcm.cpp:193
virtual size_t readBuffer(int16 *buffer, const size_t numSamples)
Fill the given buffer with up to numSamples samples.
Definition: adpcm.cpp:148
uint32_t uint32
Definition: types.h:204
Apple_ADPCMStream(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
Definition: adpcm.cpp:178
void status(const char *s,...)
Definition: util.cpp:52
virtual size_t readBuffer(int16 *buffer, const size_t numSamples)
Fill the given buffer with up to numSamples samples.
Definition: adpcm.cpp:596
struct Sound::ADPCMStream::@12::@13 ima_ch[2]
struct Sound::ADPCMStream::@12 _status
virtual void reset()
Definition: adpcm.cpp:120
const uint32 _blockAlign
Definition: adpcm.cpp:68
MS_ADPCMStream(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
Definition: adpcm.cpp:368
int16 decodeXbox(int code, ADPCMChannelStatus &status)
Definition: adpcm.cpp:575
void NORETURN_PRE error(const char *s,...)
Definition: util.cpp:86
T CLIP(T v, T amin, T amax)
Definition: util.h:72
const size_t _endpos
Definition: adpcm.cpp:66
ADPCMChannelStatus ch[2]
Definition: adpcm.cpp:564
virtual bool rewind()
Rewinds the stream to its start.
Definition: adpcm.cpp:125
Interface for a seekable & readable data stream.
Definition: readstream.h:265
Streaming audio.
static const uint16 imaStepTable[89]
Definition: adpcm.cpp:451
uint8 byte
Definition: types.h:209
virtual 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: adpcm.cpp:89
static const int MSADPCMAdaptCoeff2[]
Definition: adpcm.cpp:336
int32_t int32
Definition: types.h:203