diff options
| -rw-r--r-- | audio/decoders/xa.cpp | 75 | 
1 files changed, 35 insertions, 40 deletions
| diff --git a/audio/decoders/xa.cpp b/audio/decoders/xa.cpp index 9b4f27f9fc..ab7fd66481 100644 --- a/audio/decoders/xa.cpp +++ b/audio/decoders/xa.cpp @@ -32,7 +32,7 @@ public:  	~XAStream();  	bool isStereo() const { return false; } -	bool endOfData() const { return _stream->pos() == _stream->size(); } +	bool endOfData() const { return _endOfData && _samplesRemaining == 0; }  	int getRate() const { return _rate; }  	int readBuffer(int16 *buffer, const int numSamples); @@ -47,6 +47,7 @@ private:  	int _rate;  	double _s1, _s2;  	uint _loopPoint; +	bool _endOfData;  };  XAStream::XAStream(Common::SeekableReadStream *stream, int rate, DisposeAfterUse::Flag disposeAfterUse) @@ -56,6 +57,7 @@ XAStream::XAStream(Common::SeekableReadStream *stream, int rate, DisposeAfterUse  	_s1 = _s2 = 0.0;  	_rate = rate;  	_loopPoint = 0; +	_endOfData = false;  } @@ -64,40 +66,30 @@ XAStream::~XAStream() {  		delete _stream;  } -static const double s_xaDataTable[5][2] = -	{ -		{  0.0, 0.0 }, -		{  60.0 / 64.0,  0.0 }, -		{  115.0 / 64.0, -52.0 / 64.0 }, -		{  98.0 / 64.0, -55.0 / 64.0 }, -		{  122.0 / 64.0, -60.0 / 64.0 } -	}; +static const double s_xaDataTable[5][2] = { +	{  0.0, 0.0 }, +	{  60.0 / 64.0,  0.0 }, +	{  115.0 / 64.0, -52.0 / 64.0 }, +	{  98.0 / 64.0, -55.0 / 64.0 }, +	{  122.0 / 64.0, -60.0 / 64.0 } +};  int XAStream::readBuffer(int16 *buffer, const int numSamples) {  	int32 samplesDecoded = 0; -	if (_samplesRemaining) { -		byte i = 0; - -		for (i = 28 - _samplesRemaining; i < 28 && samplesDecoded < numSamples; i++) { -			_samples[i] = _samples[i] + _s1 * s_xaDataTable[_predictor][0] + _s2 * s_xaDataTable[_predictor][1]; -			_s2 = _s1; -			_s1 = _samples[i]; -			int16 d = (int) (_samples[i] + 0.5); -			buffer[samplesDecoded] = d; -			samplesDecoded++; -		} - -#if 0 -		assert(i == 28); // We're screwed if this fails :P -#endif -		// This might mean the file is corrupted, or that the stream has -		// been closed. -		if (i != 28) return 0; - -		_samplesRemaining = 0; +	for (int i = 28 - _samplesRemaining; i < 28 && samplesDecoded < numSamples; i++) { +		_samples[i] = _samples[i] + _s1 * s_xaDataTable[_predictor][0] + _s2 * s_xaDataTable[_predictor][1]; +		_s2 = _s1; +		_s1 = _samples[i]; +		int16 d = (int) (_samples[i] + 0.5); +		buffer[samplesDecoded] = d; +		samplesDecoded++; +		_samplesRemaining--;  	} +	if (endOfData()) +		return samplesDecoded; +  	while (samplesDecoded < numSamples) {  		byte i = 0; @@ -106,18 +98,17 @@ int XAStream::readBuffer(int16 *buffer, const int numSamples) {  		_predictor >>= 4;  		byte flags = _stream->readByte(); -		if (flags & 0x1) { -			if (flags == 3) { -				// Loop -				rewind(); -				continue; -			} else { -				// End of stream -				return samplesDecoded; -			} -		} else if (flags & 0x4) { +		if (flags == 3) { +			// Loop +			rewind(); +			continue; +		} else if (flags == 6) {  			// Set loop point  			_loopPoint = _stream->pos() - 2; +		} else if (flags == 7) { +			// End of stream +			_endOfData = true; +			return samplesDecoded;  		}  		for (i = 0; i < 28; i += 2) { @@ -141,8 +132,11 @@ int XAStream::readBuffer(int16 *buffer, const int numSamples) {  			samplesDecoded++;  		} -		if (i != 27) +		if (i != 28)  			_samplesRemaining = 28 - i; + +		if (_stream->pos() >= _stream->size()) +			_endOfData = true;  	}  	return samplesDecoded; @@ -153,6 +147,7 @@ bool XAStream::rewind() {  	_samplesRemaining = 0;  	_predictor = 0;  	_s1 = _s2 = 0.0; +	_endOfData = false;  	return true;  } | 
