diff options
author | Max Horn | 2010-01-31 02:13:38 +0000 |
---|---|---|
committer | Max Horn | 2010-01-31 02:13:38 +0000 |
commit | 7f2f9a811743cabd8c07c9a0dc961140569c8071 (patch) | |
tree | 0fa21c1a9c337fcc127498790c291136a6dde2dd | |
parent | f3322bb1c88f4017a1652ed402833d0a7325533d (diff) | |
download | scummvm-rg350-7f2f9a811743cabd8c07c9a0dc961140569c8071.tar.gz scummvm-rg350-7f2f9a811743cabd8c07c9a0dc961140569c8071.tar.bz2 scummvm-rg350-7f2f9a811743cabd8c07c9a0dc961140569c8071.zip |
Rearrange code of ADPCMStream subclasses
svn-id: r47739
-rw-r--r-- | sound/decoders/adpcm.cpp | 134 |
1 files changed, 68 insertions, 66 deletions
diff --git a/sound/decoders/adpcm.cpp b/sound/decoders/adpcm.cpp index 39dc2801b4..53e335e074 100644 --- a/sound/decoders/adpcm.cpp +++ b/sound/decoders/adpcm.cpp @@ -54,7 +54,7 @@ protected: int16 sample2; }; - struct adpcmStatus { + struct { // OKI/IMA struct { int32 last; @@ -160,6 +160,35 @@ int Oki_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) { return samples; } +static const int16 okiStepSize[49] = { + 16, 17, 19, 21, 23, 25, 28, 31, + 34, 37, 41, 45, 50, 55, 60, 66, + 73, 80, 88, 97, 107, 118, 130, 143, + 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, + 724, 796, 876, 963, 1060, 1166, 1282, 1411, + 1552 +}; + +// Decode Linear to ADPCM +int16 Oki_ADPCMStream::decodeOKI(byte code) { + int16 diff, E, samp; + + E = (2 * (code & 0x7) + 1) * okiStepSize[_status.ima_ch[0].stepIndex] / 8; + diff = (code & 0x08) ? -E : E; + samp = _status.ima_ch[0].last + diff; + // Clip the values to +/- 2^11 (supposed to be 12 bits) + samp = CLIP<int16>(samp, -2048, 2047); + + _status.ima_ch[0].last = samp; + _status.ima_ch[0].stepIndex += stepAdjust(code); + _status.ima_ch[0].stepIndex = CLIP<int32>(_status.ima_ch[0].stepIndex, 0, ARRAYSIZE(okiStepSize) - 1); + + // * 16 effectively converts 12-bit input to 16-bit output + return samp * 16; +} + + #pragma mark - @@ -355,6 +384,12 @@ static const int MSADPCMAdaptCoeff2[] = { 0, -256, 0, 64, 0, -208, -232 }; +static const int MSADPCMAdaptationTable[] = { + 230, 230, 230, 230, 307, 409, 512, 614, + 768, 614, 512, 409, 307, 230, 230, 230 +}; + + class MS_ADPCMStream : public ADPCMStream { public: MS_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign) @@ -369,6 +404,24 @@ protected: int16 decodeMS(ADPCMChannelStatus *c, byte); }; +int16 MS_ADPCMStream::decodeMS(ADPCMChannelStatus *c, byte code) { + int32 predictor; + + predictor = (((c->sample1) * (c->coeff1)) + ((c->sample2) * (c->coeff2))) / 256; + predictor += (signed)((code & 0x08) ? (code - 0x10) : (code)) * c->delta; + + predictor = CLIP<int32>(predictor, -32768, 32767); + + c->sample2 = c->sample1; + c->sample1 = predictor; + c->delta = (MSADPCMAdaptationTable[(int)code] * c->delta) >> 8; + + if (c->delta < 16) + c->delta = 16; + + return (int16)predictor; +} + int MS_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) { int samples; byte data; @@ -412,6 +465,7 @@ int MS_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) { } + #pragma mark - @@ -464,6 +518,19 @@ void Tinsel_ADPCMStream::readBufferTinselHeader() { _status.K1 = TinselFilterTable[filterVal][1]; } +int16 Tinsel_ADPCMStream::decodeTinsel(int16 code, double eVal) { + double sample; + + sample = (double) code; + sample *= eVal * _status.predictor; + sample += (_status.d0 * _status.K0) + (_status.d1 * _status.K1); + + _status.d1 = _status.d0; + _status.d0 = sample; + + return (int16) CLIP<double>(sample, -32768.0, 32767.0); +} + class Tinsel4_ADPCMStream : public Tinsel_ADPCMStream { public: Tinsel4_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign) @@ -585,30 +652,6 @@ int Tinsel8_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) { #pragma mark - -static const int MSADPCMAdaptationTable[] = { - 230, 230, 230, 230, 307, 409, 512, 614, - 768, 614, 512, 409, 307, 230, 230, 230 -}; - - -int16 MS_ADPCMStream::decodeMS(ADPCMChannelStatus *c, byte code) { - int32 predictor; - - predictor = (((c->sample1) * (c->coeff1)) + ((c->sample2) * (c->coeff2))) / 256; - predictor += (signed)((code & 0x08) ? (code - 0x10) : (code)) * c->delta; - - predictor = CLIP<int32>(predictor, -32768, 32767); - - c->sample2 = c->sample1; - c->sample1 = predictor; - c->delta = (MSADPCMAdaptationTable[(int)code] * c->delta) >> 8; - - if (c->delta < 16) - c->delta = 16; - - return (int16)predictor; -} - // adjust the step for use on the next sample. int16 ADPCMStream::stepAdjust(byte code) { static const int16 adjusts[] = {-1, -1, -1, -1, 2, 4, 6, 8}; @@ -616,34 +659,6 @@ int16 ADPCMStream::stepAdjust(byte code) { return adjusts[code & 0x07]; } -static const int16 okiStepSize[49] = { - 16, 17, 19, 21, 23, 25, 28, 31, - 34, 37, 41, 45, 50, 55, 60, 66, - 73, 80, 88, 97, 107, 118, 130, 143, - 157, 173, 190, 209, 230, 253, 279, 307, - 337, 371, 408, 449, 494, 544, 598, 658, - 724, 796, 876, 963, 1060, 1166, 1282, 1411, - 1552 -}; - -// Decode Linear to ADPCM -int16 Oki_ADPCMStream::decodeOKI(byte code) { - int16 diff, E, samp; - - E = (2 * (code & 0x7) + 1) * okiStepSize[_status.ima_ch[0].stepIndex] / 8; - diff = (code & 0x08) ? -E : E; - samp = _status.ima_ch[0].last + diff; - // Clip the values to +/- 2^11 (supposed to be 12 bits) - samp = CLIP<int16>(samp, -2048, 2047); - - _status.ima_ch[0].last = samp; - _status.ima_ch[0].stepIndex += stepAdjust(code); - _status.ima_ch[0].stepIndex = CLIP<int32>(_status.ima_ch[0].stepIndex, 0, ARRAYSIZE(okiStepSize) - 1); - - // * 16 effectively converts 12-bit input to 16-bit output - return samp * 16; -} - static const uint16 imaStepTable[89] = { 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, @@ -671,19 +686,6 @@ int16 ADPCMStream::decodeIMA(byte code, int channel) { return samp; } -int16 Tinsel_ADPCMStream::decodeTinsel(int16 code, double eVal) { - double sample; - - sample = (double) code; - sample *= eVal * _status.predictor; - sample += (_status.d0 * _status.K0) + (_status.d1 * _status.K1); - - _status.d1 = _status.d0; - _status.d0 = sample; - - return (int16) CLIP<double>(sample, -32768.0, 32767.0); -} - RewindableAudioStream *makeADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, typesADPCM type, int rate, int channels, uint32 blockAlign) { switch (type) { case kADPCMOki: |