[Scummvm-cvs-logs] CVS: scummvm/sound adpcm.cpp,1.1,1.2 adpcm.h,1.1,1.2 wave.cpp,1.3,1.4 wave.h,1.2,1.3

Eugene Sandulenko sev at users.sourceforge.net
Tue May 3 15:13:12 CEST 2005


Update of /cvsroot/scummvm/scummvm/sound
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4506/sound

Modified Files:
	adpcm.cpp adpcm.h wave.cpp wave.h 
Log Message:
o Fixed ADPCM decoder length bug
o Plugged IMA ADPCM into SCUMM engine so latter HE titles now have speech
  though it is somewhat noisy don't know why as decoder is based on ADPCM
   reference implementation.


Index: adpcm.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/adpcm.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- adpcm.cpp	3 May 2005 20:36:07 -0000	1.1
+++ adpcm.cpp	3 May 2005 22:12:23 -0000	1.2
@@ -33,6 +33,7 @@
 	bool _evenPos;
 	Common::SeekableReadStream *_stream;
 	typesADPCM _type;
+	uint32 _endpos;
 
 	struct adpcmStatus {
 		int16 last;
@@ -47,22 +48,23 @@
 	int readIMABuffer(int16 *buffer, const int numSamples);
 
 public:
-	ADPCMInputStream(Common::SeekableReadStream *stream, typesADPCM type);
+	ADPCMInputStream(Common::SeekableReadStream *stream, uint32 size, typesADPCM type);
 	~ADPCMInputStream() {};
 
 	int readBuffer(int16 *buffer, const int numSamples);
 
-	bool endOfData() const { return _stream->eos(); }
+	bool endOfData() const { return (_stream->eos() || _stream->pos() >= _endpos); }
 	bool isStereo() const	{ return false; }
 	int getRate() const	{ return 22050; }
 };
 
 
-ADPCMInputStream::ADPCMInputStream(Common::SeekableReadStream *stream, typesADPCM type)
+ADPCMInputStream::ADPCMInputStream(Common::SeekableReadStream *stream, uint32 size, typesADPCM type)
 	: _stream(stream), _evenPos(true), _type(type) {
 
 	_status.last = 0;
 	_status.stepIndex = 0;
+	_endpos = stream->pos() + size;
 }
 
 int ADPCMInputStream::readBuffer(int16 *buffer, const int numSamples) {
@@ -83,7 +85,7 @@
 int ADPCMInputStream::readOkiBuffer(int16 *buffer, const int numSamples) {
 	int samples;
 
-	for (samples = 0; samples < numSamples && !_stream->eos(); samples++) {
+	for (samples = 0; samples < numSamples && !_stream->eos() && _stream->pos() < _endpos; samples++) {
 		// * 16 effectively converts 12-bit input to 16-bit output
 		if (_evenPos) {
 			buffer[samples] = okiADPCMDecode((_stream->readByte() >> 4) & 0x0f) * 16;
@@ -100,7 +102,7 @@
 int ADPCMInputStream::readIMABuffer(int16 *buffer, const int numSamples) {
 	int samples;
 
-	for (samples = 0; samples < numSamples && !_stream->eos(); samples++) {
+	for (samples = 0; samples < numSamples && !_stream->eos() && _stream->pos() < _endpos; samples++) {
 		if (_evenPos) {
 			buffer[samples] = imaADPCMDecode((_stream->readByte() >> 4) & 0x0f);
 			// Rewind back so we will reget byte later
@@ -161,8 +163,8 @@
 	return samp;
 }
 
-AudioStream *makeADPCMStream(Common::SeekableReadStream &stream, typesADPCM type) {
-	AudioStream *audioStream = new ADPCMInputStream(&stream, type);
+AudioStream *makeADPCMStream(Common::SeekableReadStream &stream, uint32 size, typesADPCM type) {
+	AudioStream *audioStream = new ADPCMInputStream(&stream, size, type);
 
 	return audioStream;
 }
@@ -183,12 +185,10 @@
 	32767
 };
 
-
 int16 ADPCMInputStream::imaADPCMDecode(byte code) {
-	int diff, E, SS, samp;
+	int32 diff, E, SS, samp;
 
 	SS = imaStepTable[_status.stepIndex];
-
 	E = SS/8;
 	if (code & 0x01)
 		E += SS/4;
@@ -196,13 +196,14 @@
 		E += SS/2;
 	if (code & 0x04)
 		E += SS;
+
 	diff = (code & 0x08) ? -E : E;
 	samp = _status.last + diff;
 
-	if(samp < -0x8000)
-		samp = -0x8000;
-	else if(samp > 0x7fff)
-		samp = 0x7fff;
+	if(samp < -32768)
+		samp = -32768;
+	else if(samp > 32767)
+		samp = 32767;
 
 	_status.last = samp;
 	_status.stepIndex += stepAdjust(code);

Index: adpcm.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/adpcm.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- adpcm.h	3 May 2005 20:36:07 -0000	1.1
+++ adpcm.h	3 May 2005 22:12:23 -0000	1.2
@@ -32,6 +32,6 @@
 	kADPCMIma
 };
 
-AudioStream *makeADPCMStream(Common::SeekableReadStream &stream, typesADPCM type);
+AudioStream *makeADPCMStream(Common::SeekableReadStream &stream, uint32 size, typesADPCM type);
 
 #endif

Index: wave.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/wave.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- wave.cpp	11 Jan 2005 08:30:28 -0000	1.3
+++ wave.cpp	3 May 2005 22:12:23 -0000	1.4
@@ -26,8 +26,9 @@
 #include "sound/audiostream.h"
 #include "sound/mixer.h"
 #include "sound/wave.h"
+#include "sound/adpcm.h"
 
-bool loadWAVFromStream(Common::SeekableReadStream &stream, int &size, int &rate, byte &flags) {
+bool loadWAVFromStream(Common::SeekableReadStream &stream, int &size, int &rate, byte &flags, uint16 *wavType) {
 	const uint32 initialPos = stream.pos();
 	byte buf[4+1];
 
@@ -62,7 +63,8 @@
 
 	// Next comes the "type" field of the fmt header. Some typical
 	// values for it:
-	// 1  -> uncompressed PCM 
+	// 1  -> uncompressed PCM
+	// 17 -> IMA ADPCM compressed WAVE
 	// See <http://www.sonicspot.com/guide/wavefiles.html> for a more complete
 	// list of common WAVE compression formats...
 	uint16 type = stream.readUint16LE();	// == 1 for PCM data
@@ -74,6 +76,9 @@
 	uint16 bitsPerSample = stream.readUint16LE();	// 8, 16 ...
 	// 8 bit data is unsigned, 16 bit data signed
 
+
+	if (wavType != 0)
+		*wavType = type;
 #if 0	
 	printf("WAVE information:\n");
 	printf("  total size: %d\n", wavLength);
@@ -86,8 +91,8 @@
 	printf("  bitsPerSample: %d\n", bitsPerSample);
 #endif
 
-	if (type != 1) {
-		warning("getWavInfo: only PCM data is supported (type %d)", type);
+	if (type != 1 && type != 17) {
+		warning("getWavInfo: only PCM or IMA ADPCM data is supported (type %d)", type);
 		return false;
 	}
 
@@ -107,6 +112,8 @@
 		flags |= SoundMixer::FLAG_UNSIGNED;
 	else if (bitsPerSample == 16)	// 16 bit data is signed little endian
 		flags |= (SoundMixer::FLAG_16BITS | SoundMixer::FLAG_LITTLE_ENDIAN);
+	else if (bitsPerSample == 4 && type == 17)	// IDA ADPCM compressed. We decompress it
+		flags |= (SoundMixer::FLAG_16BITS | SoundMixer::FLAG_LITTLE_ENDIAN);
 	else {
 		warning("getWavInfo: unsupported bitsPerSample %d", bitsPerSample);
 		return false;
@@ -148,10 +155,14 @@
 AudioStream *makeWAVStream(Common::SeekableReadStream &stream) {
 	int size, rate;
 	byte flags;
+	uint16 type;
 	
-	if (!loadWAVFromStream(stream, size, rate, flags))
+	if (!loadWAVFromStream(stream, size, rate, flags, &type))
 		return 0;
 	
+	if (type == 17) // IMA ADPCM
+		return makeADPCMStream(stream, size, kADPCMIma);
+
 	byte *data = (byte *)malloc(size);
 	assert(data);
 	stream.read(data, size);

Index: wave.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/wave.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- wave.h	9 Jan 2005 16:14:55 -0000	1.2
+++ wave.h	3 May 2005 22:12:23 -0000	1.3
@@ -34,7 +34,7 @@
  * all information about the data necessary for playback.
  * Currently this only support uncompressed raw PCM data.
  */
-extern bool loadWAVFromStream(Common::SeekableReadStream &stream, int &size, int &rate, byte &flags);
+extern bool loadWAVFromStream(Common::SeekableReadStream &stream, int &size, int &rate, byte &flags, uint16 *wavType = 0);
 
 AudioStream *makeWAVStream(Common::SeekableReadStream &stream);
 





More information about the Scummvm-git-logs mailing list