[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