diff options
author | Eugene Sandulenko | 2006-09-21 20:12:16 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2006-09-21 20:12:16 +0000 |
commit | 4e8df88c81d64ad61bcaefd4d7fd0bf2cd402924 (patch) | |
tree | d151297aaf67a76d1b03459fa3f05be7c21df4c2 /sound | |
parent | a857bdeca3f1338fdfbb7e656550794d3767b387 (diff) | |
download | scummvm-rg350-4e8df88c81d64ad61bcaefd4d7fd0bf2cd402924.tar.gz scummvm-rg350-4e8df88c81d64ad61bcaefd4d7fd0bf2cd402924.tar.bz2 scummvm-rg350-4e8df88c81d64ad61bcaefd4d7fd0bf2cd402924.zip |
Fix bug #1501302: "FF: Crackling Audio (Mac version)"
svn-id: r23970
Diffstat (limited to 'sound')
-rw-r--r-- | sound/adpcm.cpp | 67 |
1 files changed, 36 insertions, 31 deletions
diff --git a/sound/adpcm.cpp b/sound/adpcm.cpp index 519d0d738c..c6feb45aee 100644 --- a/sound/adpcm.cpp +++ b/sound/adpcm.cpp @@ -96,7 +96,8 @@ ADPCMInputStream::ADPCMInputStream(Common::SeekableReadStream *stream, uint32 si _status.stepIndex = 0; memset(_status.ch, 0, sizeof(_status.ch)); _endpos = stream->pos() + size; - _blockPos = _blockLen = 0; + _blockLen = 0; + _blockPos = _blockAlign; // To make sure first header is read if (type == kADPCMMSIma && blockAlign == 0) error("ADPCMInputStream(): blockAlign isn't specifiled for MS IMA ADPCM"); @@ -217,18 +218,22 @@ int ADPCMInputStream::readBufferMS(int channels, int16 *buffer, const int numSam if (stereo) _status.ch[1].delta = _stream->readSint16LE(); - buffer[samples++] = _status.ch[0].sample1 = _stream->readSint16LE(); + _status.ch[0].sample1 = _stream->readSint16LE(); if (stereo) - buffer[samples++] = _status.ch[1].sample1 = _stream->readSint16LE(); + _status.ch[1].sample1 = _stream->readSint16LE(); buffer[samples++] = _status.ch[0].sample2 = _stream->readSint16LE(); + if (stereo) buffer[samples++] = _status.ch[1].sample2 = _stream->readSint16LE(); + buffer[samples++] = _status.ch[0].sample1; + if (stereo) + buffer[samples++] = _status.ch[1].sample1; + _blockPos = channels * 7; } - for (; samples < numSamples && _blockPos < _blockAlign && !_stream->eos() && _stream->pos() < _endpos; samples += 2) { data = _stream->readByte(); _blockPos++; @@ -241,6 +246,33 @@ int ADPCMInputStream::readBufferMS(int channels, int16 *buffer, const int numSam } +static const int MSADPCMAdaptationTable[] = { + 230, 230, 230, 230, 307, 409, 512, 614, + 768, 614, 512, 409, 307, 230, 230, 230 +}; + + +int16 ADPCMInputStream::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; + + if (predictor < -0x8000) + predictor = -0x8000; + else if (predictor > 0x7fff) + predictor = 0x7fff; + + 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 ADPCMInputStream::stepAdjust(byte code) { static const int16 adjusts[] = {-1, -1, -1, -1, 2, 4, 6, 8}; @@ -322,33 +354,6 @@ int16 ADPCMInputStream::decodeMSIMA(byte code) { return samp; } -static const int MSADPCMAdaptationTable[] = { - 230, 230, 230, 230, 307, 409, 512, 614, - 768, 614, 512, 409, 307, 230, 230, 230 -}; - - -int16 ADPCMInputStream::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; - - if (predictor < -0x8000) - predictor = -0x8000; - else if (predictor > 0x7fff) - predictor = 0x7fff; - - 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; -} - AudioStream *makeADPCMStream(Common::SeekableReadStream *stream, uint32 size, typesADPCM type, int rate, int channels, uint32 blockAlign) { return new ADPCMInputStream(stream, size, type, rate, channels, blockAlign); } |