diff options
Diffstat (limited to 'sound/adpcm.cpp')
| -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);  } | 
