[Scummvm-cvs-logs] scummvm master -> 62d87e30f4dcdd78dc43747a5cdb1cc450bf4d3b

digitall dgturner at iee.org
Mon Dec 10 17:31:26 CET 2012


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
62d87e30f4 AUDIO: Fix MS ADPCM to work with Mono streams using odd sized buffers.


Commit: 62d87e30f4dcdd78dc43747a5cdb1cc450bf4d3b
    https://github.com/scummvm/scummvm/commit/62d87e30f4dcdd78dc43747a5cdb1cc450bf4d3b
Author: D G Turner (digitall at scummvm.org)
Date: 2012-12-10T08:29:16-08:00

Commit Message:
AUDIO: Fix MS ADPCM to work with Mono streams using odd sized buffers.

Changed paths:
    audio/decoders/adpcm.cpp
    audio/decoders/adpcm_intern.h



diff --git a/audio/decoders/adpcm.cpp b/audio/decoders/adpcm.cpp
index 2fe509e..f069ee3 100644
--- a/audio/decoders/adpcm.cpp
+++ b/audio/decoders/adpcm.cpp
@@ -268,7 +268,6 @@ static const int MSADPCMAdaptationTable[] = {
 	768, 614, 512, 409, 307, 230, 230, 230
 };
 
-
 int16 MS_ADPCMStream::decodeMS(ADPCMChannelStatus *c, byte code) {
 	int32 predictor;
 
@@ -290,40 +289,42 @@ int16 MS_ADPCMStream::decodeMS(ADPCMChannelStatus *c, byte code) {
 int MS_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) {
 	int samples;
 	byte data;
-	int i = 0;
-
-	samples = 0;
+	int i;
 
-	while (samples < numSamples && !_stream->eos() && _stream->pos() < _endpos) {
-		if (_blockPos[0] == _blockAlign) {
-			// read block header
-			for (i = 0; i < _channels; i++) {
-				_status.ch[i].predictor = CLIP(_stream->readByte(), (byte)0, (byte)6);
-				_status.ch[i].coeff1 = MSADPCMAdaptCoeff1[_status.ch[i].predictor];
-				_status.ch[i].coeff2 = MSADPCMAdaptCoeff2[_status.ch[i].predictor];
-			}
+	for (samples = 0; samples < numSamples && !endOfData(); samples++) {
+		if (_decodedSampleCount == 0) {
+			if (_blockPos[0] == _blockAlign) {
+				// read block header
+				for (i = 0; i < _channels; i++) {
+					_status.ch[i].predictor = CLIP(_stream->readByte(), (byte)0, (byte)6);
+					_status.ch[i].coeff1 = MSADPCMAdaptCoeff1[_status.ch[i].predictor];
+					_status.ch[i].coeff2 = MSADPCMAdaptCoeff2[_status.ch[i].predictor];
+				}
 
-			for (i = 0; i < _channels; i++)
-				_status.ch[i].delta = _stream->readSint16LE();
+				for (i = 0; i < _channels; i++)
+					_status.ch[i].delta = _stream->readSint16LE();
 
-			for (i = 0; i < _channels; i++)
-				_status.ch[i].sample1 = _stream->readSint16LE();
+				for (i = 0; i < _channels; i++)
+					_status.ch[i].sample1 = _stream->readSint16LE();
 
-			for (i = 0; i < _channels; i++)
-				buffer[samples++] = _status.ch[i].sample2 = _stream->readSint16LE();
+				for (i = 0; i < _channels; i++)
+					_decodedSamples[_decodedSampleCount++] = _status.ch[i].sample2 = _stream->readSint16LE();
 
-			for (i = 0; i < _channels; i++)
-				buffer[samples++] = _status.ch[i].sample1;
+				for (i = 0; i < _channels; i++)
+					_decodedSamples[_decodedSampleCount++] = _status.ch[i].sample1;
 
-			_blockPos[0] = _channels * 7;
+				_blockPos[0] = _channels * 7;
+			} else {
+				data = _stream->readByte();
+				_blockPos[0]++;
+				_decodedSamples[_decodedSampleCount++] = decodeMS(&_status.ch[0], (data >> 4) & 0x0f);
+				_decodedSamples[_decodedSampleCount++] = decodeMS(&_status.ch[_channels - 1], data & 0x0f);
+			}
 		}
 
-		for (; samples < numSamples && _blockPos[0] < _blockAlign && !_stream->eos() && _stream->pos() < _endpos; samples += 2) {
-			data = _stream->readByte();
-			_blockPos[0]++;
-			buffer[samples] = decodeMS(&_status.ch[0], (data >> 4) & 0x0f);
-			buffer[samples + 1] = decodeMS(&_status.ch[_channels - 1], data & 0x0f);
-		}
+		// (1 - (count - 1)) ensures that _decodedSamples acts as a FIFO of depth 2
+		buffer[samples] = _decodedSamples[1 - (_decodedSampleCount - 1)];
+		_decodedSampleCount--;
 	}
 
 	return samples;
diff --git a/audio/decoders/adpcm_intern.h b/audio/decoders/adpcm_intern.h
index 3b8d8c7..66a1aa6 100644
--- a/audio/decoders/adpcm_intern.h
+++ b/audio/decoders/adpcm_intern.h
@@ -206,12 +206,19 @@ public:
 		if (blockAlign == 0)
 			error("MS_ADPCMStream(): blockAlign isn't specified for MS ADPCM");
 		memset(&_status, 0, sizeof(_status));
+		_decodedSampleCount = 0;
 	}
 
+	virtual bool endOfData() const { return (_stream->eos() || _stream->pos() >= _endpos) && (_decodedSampleCount == 0); }
+
 	virtual int readBuffer(int16 *buffer, const int numSamples);
 
 protected:
 	int16 decodeMS(ADPCMChannelStatus *c, byte);
+
+private:
+	uint8 _decodedSampleCount;
+	int16 _decodedSamples[4];
 };
 
 // Duck DK3 IMA ADPCM Decoder






More information about the Scummvm-git-logs mailing list