ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

adpcm.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "common/stream.h"
00024 #include "common/textconsole.h"
00025 #include "common/util.h"
00026 
00027 #include "audio/decoders/adpcm.h"
00028 #include "audio/decoders/adpcm_intern.h"
00029 
00030 
00031 namespace Audio {
00032 
00033 // Routines to convert 12 bit linear samples to the
00034 // Dialogic or Oki ADPCM coding format aka VOX.
00035 // See also <http://www.comptek.ru/telephony/tnotes/tt1-13.html>
00036 //
00037 // IMA ADPCM support is based on
00038 //   <http://wiki.multimedia.cx/index.php?title=IMA_ADPCM>
00039 //
00040 // In addition, also MS IMA ADPCM is supported. See
00041 //   <http://wiki.multimedia.cx/index.php?title=Microsoft_IMA_ADPCM>.
00042 
00043 ADPCMStream::ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
00044     : _stream(stream, disposeAfterUse),
00045         _startpos(stream->pos()),
00046         _endpos(_startpos + size),
00047         _channels(channels),
00048         _blockAlign(blockAlign),
00049         _rate(rate) {
00050 
00051     reset();
00052 }
00053 
00054 void ADPCMStream::reset() {
00055     memset(&_status, 0, sizeof(_status));
00056     _blockPos[0] = _blockPos[1] = _blockAlign; // To make sure first header is read
00057 }
00058 
00059 bool ADPCMStream::rewind() {
00060     // TODO: Error checking.
00061     reset();
00062     _stream->seek(_startpos);
00063     return true;
00064 }
00065 
00066 
00067 #pragma mark -
00068 
00069 
00070 int Oki_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) {
00071     int samples;
00072     byte data;
00073 
00074     for (samples = 0; samples < numSamples && !endOfData(); samples++) {
00075         if (_decodedSampleCount == 0) {
00076             data = _stream->readByte();
00077             _decodedSamples[0] = decodeOKI((data >> 4) & 0x0f);
00078             _decodedSamples[1] = decodeOKI((data >> 0) & 0x0f);
00079             _decodedSampleCount = 2;
00080         }
00081 
00082         // (1 - (count - 1)) ensures that _decodedSamples acts as a FIFO of depth 2
00083         buffer[samples] = _decodedSamples[1 - (_decodedSampleCount - 1)];
00084         _decodedSampleCount--;
00085     }
00086 
00087     return samples;
00088 }
00089 
00090 static const int16 okiStepSize[49] = {
00091        16,   17,   19,   21,   23,   25,   28,   31,
00092        34,   37,   41,   45,   50,   55,   60,   66,
00093        73,   80,   88,   97,  107,  118,  130,  143,
00094       157,  173,  190,  209,  230,  253,  279,  307,
00095       337,  371,  408,  449,  494,  544,  598,  658,
00096       724,  796,  876,  963, 1060, 1166, 1282, 1411,
00097      1552
00098 };
00099 
00100 // Decode Linear to ADPCM
00101 int16 Oki_ADPCMStream::decodeOKI(byte code) {
00102     int16 diff, E, samp;
00103 
00104     E = (2 * (code & 0x7) + 1) * okiStepSize[_status.ima_ch[0].stepIndex] / 8;
00105     diff = (code & 0x08) ? -E : E;
00106     samp = _status.ima_ch[0].last + diff;
00107     // Clip the values to +/- 2^11 (supposed to be 12 bits)
00108     samp = CLIP<int16>(samp, -2048, 2047);
00109 
00110     _status.ima_ch[0].last = samp;
00111     _status.ima_ch[0].stepIndex += _stepAdjustTable[code];
00112     _status.ima_ch[0].stepIndex = CLIP<int32>(_status.ima_ch[0].stepIndex, 0, ARRAYSIZE(okiStepSize) - 1);
00113 
00114     // * 16 effectively converts 12-bit input to 16-bit output
00115     return samp * 16;
00116 }
00117 
00118 
00119 #pragma mark -
00120 
00121 
00122 int DVI_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) {
00123     int samples;
00124     byte data;
00125 
00126     for (samples = 0; samples < numSamples && !endOfData(); samples++) {
00127         if (_decodedSampleCount == 0) {
00128             data = _stream->readByte();
00129             _decodedSamples[0] = decodeIMA((data >> 4) & 0x0f, 0);
00130             _decodedSamples[1] = decodeIMA((data >> 0) & 0x0f, _channels == 2 ? 1 : 0);
00131             _decodedSampleCount = 2;
00132         }
00133 
00134         // (1 - (count - 1)) ensures that _decodedSamples acts as a FIFO of depth 2
00135         buffer[samples] = _decodedSamples[1 - (_decodedSampleCount - 1)];
00136         _decodedSampleCount--;
00137     }
00138 
00139     return samples;
00140 }
00141 
00142 #pragma mark -
00143 
00144 
00145 int Apple_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) {
00146     // Need to write at least one samples per channel
00147     assert((numSamples % _channels) == 0);
00148 
00149     // Current sample positions
00150     int samples[2] = { 0, 0};
00151 
00152     // Number of samples per channel
00153     int chanSamples = numSamples / _channels;
00154 
00155     for (int i = 0; i < _channels; i++) {
00156         _stream->seek(_streamPos[i]);
00157 
00158         while ((samples[i] < chanSamples) &&
00159                // Last byte read and a new one needed
00160                !((_stream->eos() || (_stream->pos() >= _endpos)) && (_chunkPos[i] == 0))) {
00161 
00162             if (_blockPos[i] == _blockAlign) {
00163                 // 2 byte header per block
00164                 uint16 temp = _stream->readUint16BE();
00165 
00166                 // First 9 bits are the upper bits of the predictor
00167                 _status.ima_ch[i].last      = (int16) (temp & 0xFF80);
00168                 // Lower 7 bits are the step index
00169                 _status.ima_ch[i].stepIndex =          temp & 0x007F;
00170 
00171                 // Clip the step index
00172                 _status.ima_ch[i].stepIndex = CLIP<int32>(_status.ima_ch[i].stepIndex, 0, 88);
00173 
00174                 _blockPos[i] = 2;
00175             }
00176 
00177             if (_chunkPos[i] == 0) {
00178                 // Decode data
00179                 byte data = _stream->readByte();
00180                 _buffer[i][0] = decodeIMA(data &  0x0F, i);
00181                 _buffer[i][1] = decodeIMA(data >>    4, i);
00182             }
00183 
00184             // The original is interleaved block-wise, we want it sample-wise
00185             buffer[_channels * samples[i] + i] = _buffer[i][_chunkPos[i]];
00186 
00187             if (++_chunkPos[i] > 1) {
00188                 // We're about to decode the next byte, so advance the block position
00189                 _chunkPos[i] = 0;
00190                 _blockPos[i]++;
00191             }
00192 
00193             samples[i]++;
00194 
00195             if (_channels == 2)
00196                 if (_blockPos[i] == _blockAlign)
00197                     // We're at the end of the block.
00198                     // Since the channels are interleaved, skip the next block
00199                     _stream->skip(MIN<uint32>(_blockAlign, _endpos - _stream->pos()));
00200 
00201             _streamPos[i] = _stream->pos();
00202         }
00203     }
00204 
00205     return samples[0] + samples[1];
00206 }
00207 
00208 
00209 #pragma mark -
00210 
00211 
00212 int MSIma_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) {
00213     // Need to write at least one sample per channel
00214     assert((numSamples % _channels) == 0);
00215 
00216     int samples = 0;
00217 
00218     while (samples < numSamples && !_stream->eos() && _stream->pos() < _endpos) {
00219         if (_blockPos[0] == _blockAlign) {
00220             for (int i = 0; i < _channels; i++) {
00221                 // read block header
00222                 _status.ima_ch[i].last = _stream->readSint16LE();
00223                 _status.ima_ch[i].stepIndex = _stream->readSint16LE();
00224             }
00225 
00226             _blockPos[0] = _channels * 4;
00227         }
00228 
00229         // Decode a set of samples
00230         for (int i = 0; i < _channels; i++) {
00231             // The stream encodes four bytes per channel at a time
00232             for (int j = 0; j < 4; j++) {
00233                 byte data = _stream->readByte();
00234                 _blockPos[0]++;
00235                 _buffer[i][j * 2] = decodeIMA(data & 0x0f, i);
00236                 _buffer[i][j * 2 + 1] = decodeIMA((data >> 4) & 0x0f, i);
00237                 _samplesLeft[i] += 2;
00238             }
00239         }
00240 
00241         while (samples < numSamples && _samplesLeft[0] != 0) {
00242             for (int i = 0; i < _channels; i++) {
00243                 buffer[samples + i] = _buffer[i][8 - _samplesLeft[i]];
00244                 _samplesLeft[i]--;
00245             }
00246 
00247             samples += _channels;
00248         }
00249     }
00250 
00251     return samples;
00252 }
00253 
00254 
00255 #pragma mark -
00256 
00257 
00258 static const int MSADPCMAdaptCoeff1[] = {
00259     256, 512, 0, 192, 240, 460, 392
00260 };
00261 
00262 static const int MSADPCMAdaptCoeff2[] = {
00263     0, -256, 0, 64, 0, -208, -232
00264 };
00265 
00266 static const int MSADPCMAdaptationTable[] = {
00267     230, 230, 230, 230, 307, 409, 512, 614,
00268     768, 614, 512, 409, 307, 230, 230, 230
00269 };
00270 
00271 int16 MS_ADPCMStream::decodeMS(ADPCMChannelStatus *c, byte code) {
00272     int32 predictor;
00273 
00274     predictor = (((c->sample1) * (c->coeff1)) + ((c->sample2) * (c->coeff2))) / 256;
00275     predictor += (signed)((code & 0x08) ? (code - 0x10) : (code)) * c->delta;
00276 
00277     predictor = CLIP<int32>(predictor, -32768, 32767);
00278 
00279     c->sample2 = c->sample1;
00280     c->sample1 = predictor;
00281     c->delta = (MSADPCMAdaptationTable[(int)code] * c->delta) >> 8;
00282 
00283     if (c->delta < 16)
00284         c->delta = 16;
00285 
00286     return (int16)predictor;
00287 }
00288 
00289 int MS_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) {
00290     int samples;
00291     byte data;
00292     int i;
00293 
00294     for (samples = 0; samples < numSamples && !endOfData(); samples++) {
00295         if (_decodedSampleCount == 0) {
00296             if (_blockPos[0] == _blockAlign) {
00297                 // read block header
00298                 for (i = 0; i < _channels; i++) {
00299                     _status.ch[i].predictor = CLIP(_stream->readByte(), (byte)0, (byte)6);
00300                     _status.ch[i].coeff1 = MSADPCMAdaptCoeff1[_status.ch[i].predictor];
00301                     _status.ch[i].coeff2 = MSADPCMAdaptCoeff2[_status.ch[i].predictor];
00302                 }
00303 
00304                 for (i = 0; i < _channels; i++)
00305                     _status.ch[i].delta = _stream->readSint16LE();
00306 
00307                 for (i = 0; i < _channels; i++)
00308                     _status.ch[i].sample1 = _stream->readSint16LE();
00309 
00310                 for (i = 0; i < _channels; i++)
00311                     _decodedSamples[_decodedSampleCount++] = _status.ch[i].sample2 = _stream->readSint16LE();
00312 
00313                 for (i = 0; i < _channels; i++)
00314                     _decodedSamples[_decodedSampleCount++] = _status.ch[i].sample1;
00315 
00316                 _blockPos[0] = _channels * 7;
00317             } else {
00318                 data = _stream->readByte();
00319                 _blockPos[0]++;
00320                 _decodedSamples[_decodedSampleCount++] = decodeMS(&_status.ch[0], (data >> 4) & 0x0f);
00321                 _decodedSamples[_decodedSampleCount++] = decodeMS(&_status.ch[_channels - 1], data & 0x0f);
00322             }
00323             _decodedSampleIndex = 0;
00324         }
00325 
00326         // _decodedSamples acts as a FIFO of depth 2 or 4;
00327         buffer[samples] = _decodedSamples[_decodedSampleIndex++];
00328         _decodedSampleCount--;
00329     }
00330 
00331     return samples;
00332 }
00333 
00334 
00335 #pragma mark -
00336 
00337 #define DK3_READ_NIBBLE(channelNo) \
00338 do { \
00339     if (_topNibble) { \
00340         _nibble = _lastByte >> 4; \
00341         _topNibble = false; \
00342     } else { \
00343         _lastByte = _stream->readByte(); \
00344         _nibble = _lastByte & 0xf; \
00345         _topNibble = true; \
00346         --blockBytesLeft; \
00347         --audioBytesLeft; \
00348     } \
00349     decodeIMA(_nibble, channelNo); \
00350 } while(0)
00351 
00352 int DK3_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) {
00353     assert((numSamples % 4) == 0);
00354 
00355     const uint32 startOffset = _stream->pos() % _blockAlign;
00356     uint32 audioBytesLeft = _endpos - _stream->pos();
00357     uint32 blockBytesLeft;
00358     if (startOffset != 0) {
00359         blockBytesLeft = _blockAlign - startOffset;
00360     } else {
00361         blockBytesLeft = 0;
00362     }
00363 
00364     int samples = 0;
00365     while (samples < numSamples && audioBytesLeft) {
00366         if (blockBytesLeft == 0) {
00367             blockBytesLeft = MIN(_blockAlign, audioBytesLeft);
00368             _topNibble = false;
00369 
00370             if (blockBytesLeft < 16) {
00371                 warning("Truncated DK3 ADPCM block header");
00372                 break;
00373             }
00374 
00375             _stream->skip(2);
00376             const uint16 rate = _stream->readUint16LE();
00377             assert(rate == getRate());
00378             _stream->skip(6);
00379 
00380             // Get predictor for both sum/diff channels
00381             _status.ima_ch[0].last = _stream->readSint16LE();
00382             _status.ima_ch[1].last = _stream->readSint16LE();
00383 
00384             // Get index for both sum/diff channels
00385             _status.ima_ch[0].stepIndex = _stream->readByte();
00386             _status.ima_ch[1].stepIndex = _stream->readByte();
00387             assert(_status.ima_ch[0].stepIndex < ARRAYSIZE(_imaTable));
00388             assert(_status.ima_ch[1].stepIndex < ARRAYSIZE(_imaTable));
00389 
00390             blockBytesLeft -= 16;
00391             audioBytesLeft -= 16;
00392         }
00393 
00394         DK3_READ_NIBBLE(0);
00395         DK3_READ_NIBBLE(1);
00396 
00397         *buffer++ = _status.ima_ch[0].last + _status.ima_ch[1].last;
00398         *buffer++ = _status.ima_ch[0].last - _status.ima_ch[1].last;
00399 
00400         DK3_READ_NIBBLE(0);
00401 
00402         *buffer++ = _status.ima_ch[0].last + _status.ima_ch[1].last;
00403         *buffer++ = _status.ima_ch[0].last - _status.ima_ch[1].last;
00404 
00405         samples += 4;
00406 
00407         // if the last sample of a block ends on an odd byte, the encoder adds
00408         // an extra alignment byte
00409         if (!_topNibble && blockBytesLeft == 1) {
00410             _stream->skip(1);
00411             --blockBytesLeft;
00412             --audioBytesLeft;
00413         }
00414     }
00415 
00416     return samples;
00417 }
00418 
00419 #undef DK3_READ_NIBBLE
00420 
00421 #pragma mark -
00422 
00423 
00424 // This table is used to adjust the step for use on the next sample.
00425 // We could half the table, but since the lookup index used is always
00426 // a 4-bit nibble, it's more efficient to just keep it as it is.
00427 const int16 ADPCMStream::_stepAdjustTable[16] = {
00428     -1, -1, -1, -1, 2, 4, 6, 8,
00429     -1, -1, -1, -1, 2, 4, 6, 8
00430 };
00431 
00432 const int16 Ima_ADPCMStream::_imaTable[89] = {
00433         7,    8,    9,   10,   11,   12,   13,   14,
00434        16,   17,   19,   21,   23,   25,   28,   31,
00435        34,   37,   41,   45,   50,   55,   60,   66,
00436        73,   80,   88,   97,  107,  118,  130,  143,
00437       157,  173,  190,  209,  230,  253,  279,  307,
00438       337,  371,  408,  449,  494,  544,  598,  658,
00439       724,  796,  876,  963, 1060, 1166, 1282, 1411,
00440      1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
00441      3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
00442      7132, 7845, 8630, 9493,10442,11487,12635,13899,
00443     15289,16818,18500,20350,22385,24623,27086,29794,
00444     32767
00445 };
00446 
00447 int16 Ima_ADPCMStream::decodeIMA(byte code, int channel) {
00448     int32 E = (2 * (code & 0x7) + 1) * _imaTable[_status.ima_ch[channel].stepIndex] / 8;
00449     int32 diff = (code & 0x08) ? -E : E;
00450     int32 samp = CLIP<int32>(_status.ima_ch[channel].last + diff, -32768, 32767);
00451 
00452     _status.ima_ch[channel].last = samp;
00453     _status.ima_ch[channel].stepIndex += _stepAdjustTable[code];
00454     _status.ima_ch[channel].stepIndex = CLIP<int32>(_status.ima_ch[channel].stepIndex, 0, ARRAYSIZE(_imaTable) - 1);
00455 
00456     return samp;
00457 }
00458 
00459 SeekableAudioStream *makeADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, ADPCMType type, int rate, int channels, uint32 blockAlign) {
00460     // If size is 0, report the entire size of the stream
00461     if (!size)
00462         size = stream->size();
00463 
00464     switch (type) {
00465     case kADPCMOki:
00466         return new Oki_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign);
00467     case kADPCMMSIma:
00468         return new MSIma_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign);
00469     case kADPCMMS:
00470         return new MS_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign);
00471     case kADPCMDVI:
00472         return new DVI_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign);
00473     case kADPCMApple:
00474         return new Apple_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign);
00475     case kADPCMDK3:
00476         return new DK3_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign);
00477     default:
00478         error("Unsupported ADPCM encoding");
00479         break;
00480     }
00481 }
00482 
00483 class PacketizedADPCMStream : public StatelessPacketizedAudioStream {
00484 public:
00485     PacketizedADPCMStream(ADPCMType type, int rate, int channels, uint32 blockAlign) :
00486         StatelessPacketizedAudioStream(rate, channels), _type(type), _blockAlign(blockAlign) {}
00487 
00488 protected:
00489     AudioStream *makeStream(Common::SeekableReadStream *data);
00490 
00491 private:
00492     ADPCMType _type;
00493     uint32 _blockAlign;
00494 };
00495 
00496 AudioStream *PacketizedADPCMStream::makeStream(Common::SeekableReadStream *data) {
00497     return makeADPCMStream(data, DisposeAfterUse::YES, data->size(), _type, getRate(), getChannels(), _blockAlign);
00498 }
00499 
00500 PacketizedAudioStream *makePacketizedADPCMStream(ADPCMType type, int rate, int channels, uint32 blockAlign) {
00501     // Filter out types we can't support (they're not fully stateless)
00502     switch (type) {
00503     case kADPCMOki:
00504     case kADPCMDVI:
00505         return 0;
00506     default:
00507         break;
00508     }
00509 
00510     return new PacketizedADPCMStream(type, rate, channels, blockAlign);
00511 }
00512 
00513 } // End of namespace Audio


Generated on Sat Mar 16 2019 05:01:18 for ResidualVM by doxygen 1.7.1
curved edge   curved edge