[Scummvm-cvs-logs] CVS: scummvm/sound adpcm.cpp,1.11,1.12 adpcm.h,1.6,1.7 wave.cpp,1.10,1.11 wave.h,1.5,1.6
Eugene Sandulenko
sev at users.sourceforge.net
Thu Oct 20 19:01:13 CEST 2005
Update of /cvsroot/scummvm/scummvm/sound
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30371/sound
Modified Files:
adpcm.cpp adpcm.h wave.cpp wave.h
Log Message:
Fix MS IMA ADPCM decoder. I like Microsoft so much for reinventing another
standard.
Index: adpcm.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/adpcm.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- adpcm.cpp 19 Oct 2005 04:59:18 -0000 1.11
+++ adpcm.cpp 21 Oct 2005 02:00:12 -0000 1.12
@@ -30,12 +30,15 @@
//
// In addition, also IMA ADPCM is supported.
-ADPCMInputStream::ADPCMInputStream(Common::SeekableReadStream *stream, uint32 size, typesADPCM type, int channels)
- : _stream(stream), _channels(channels), _type(type) {
+ADPCMInputStream::ADPCMInputStream(Common::SeekableReadStream *stream, uint32 size, typesADPCM type, int channels, uint32 blockAlign)
+ : _stream(stream), _channels(channels), _type(type), _blockAlign(blockAlign) {
_status.last = 0;
_status.stepIndex = 0;
_endpos = stream->pos() + size;
+
+ if (type == kADPCMIma && blockAlign == 0)
+ error("ADPCMInputStream(): blockAlign isn't specifiled for MS ADPCM IMA");
}
int ADPCMInputStream::readBuffer(int16 *buffer, const int numSamples) {
@@ -62,12 +65,10 @@
assert(numSamples % 2 == 0);
- // Since we process high and low nibbles separately never check buffer end
- // on low nibble
for (samples = 0; samples < numSamples && !_stream->eos() && _stream->pos() < _endpos; samples += 2) {
data = _stream->readByte();
- buffer[samples] = decodeOKI((data >> 4) & 0x0f);
- buffer[samples + 1] = decodeOKI(data & 0x0f);
+ buffer[samples] = TO_LE_16(decodeOKI((data >> 4) & 0x0f));
+ buffer[samples + 1] = TO_LE_16(decodeOKI(data & 0x0f));
}
return samples;
}
@@ -76,15 +77,25 @@
int ADPCMInputStream::readBufferMSIMA1(int16 *buffer, const int numSamples) {
int samples;
byte data;
+ int blockLen;
+ int i;
assert(numSamples % 2 == 0);
- // Since we process high and low nibbles separately never check buffer end
- // on low nibble
- for (samples = 0; samples < numSamples && !_stream->eos() && _stream->pos() < _endpos; samples += 2) {
- data = _stream->readByte();
- buffer[samples] = decodeMSIMA(data & 0x0f);
- buffer[samples + 1] = decodeMSIMA((data >> 4) & 0x0f);
+ samples = 0;
+
+ while (samples < numSamples && !_stream->eos() && _stream->pos() < _endpos) {
+ // read block header
+ _status.last = _stream->readSint16LE();
+ _status.stepIndex = _stream->readSint16LE();
+
+ blockLen = MIN(_endpos - _stream->pos(), _blockAlign - 4);
+
+ for (i = 0; i < blockLen && !_stream->eos() && _stream->pos() < _endpos; i++, samples += 2) {
+ data = _stream->readByte();
+ buffer[samples] = TO_LE_16(decodeMSIMA(data & 0x0f));
+ buffer[samples + 1] = TO_LE_16(decodeMSIMA((data >> 4) & 0x0f));
+ }
}
return samples;
}
@@ -103,7 +114,7 @@
for (nibble = 0; nibble < 8; nibble++) {
byte k = ((data & 0xf0000000) >> 28);
- buffer[samples + channel + nibble * 2] = decodeMSIMA(k);
+ buffer[samples + channel + nibble * 2] = TO_LE_16(decodeMSIMA(k));
data <<= 4;
}
}
@@ -181,22 +192,23 @@
int32 diff, E, SS, samp;
SS = imaStepTable[_status.stepIndex];
- E = SS/8;
- if (code & 0x01)
- E += SS/4;
- if (code & 0x02)
- E += SS/2;
+ E = SS >> 3;
if (code & 0x04)
E += SS;
+ if (code & 0x02)
+ E += SS >> 1;
+ if (code & 0x01)
+ E += SS >> 2;
diff = (code & 0x08) ? -E : E;
samp = _status.last + diff;
- if (samp < -32768)
- samp = -32768;
- else if (samp > 32767)
- samp = 32767;
+ if (samp < -0x8000)
+ samp = -0x8000;
+ else if (samp > 0x7fff)
+ samp = 0x7fff;
_status.last = samp;
+
_status.stepIndex += stepAdjust(code);
if (_status.stepIndex < 0)
_status.stepIndex = 0;
Index: adpcm.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/adpcm.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- adpcm.h 19 Oct 2005 04:59:18 -0000 1.6
+++ adpcm.h 21 Oct 2005 02:00:12 -0000 1.7
@@ -43,10 +43,11 @@
uint32 _endpos;
int _channels;
typesADPCM _type;
+ uint32 _blockAlign;
struct adpcmStatus {
- int16 last;
- int16 stepIndex;
+ int32 last;
+ int32 stepIndex;
} _status;
int16 stepAdjust(byte);
@@ -54,7 +55,7 @@
int16 decodeMSIMA(byte);
public:
- ADPCMInputStream(Common::SeekableReadStream *stream, uint32 size, typesADPCM type, int channels = 2);
+ ADPCMInputStream(Common::SeekableReadStream *stream, uint32 size, typesADPCM type, int channels = 2, uint32 blockAlign = 0);
~ADPCMInputStream() {};
int readBuffer(int16 *buffer, const int numSamples);
Index: wave.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/wave.cpp,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- wave.cpp 19 Oct 2005 04:59:18 -0000 1.10
+++ wave.cpp 21 Oct 2005 02:00:12 -0000 1.11
@@ -28,7 +28,7 @@
#include "sound/wave.h"
#include "sound/adpcm.h"
-bool loadWAVFromStream(Common::SeekableReadStream &stream, int &size, int &rate, byte &flags, uint16 *wavType) {
+bool loadWAVFromStream(Common::SeekableReadStream &stream, int &size, int &rate, byte &flags, uint16 *wavType, int *blockAlign_) {
const uint32 initialPos = stream.pos();
byte buf[4+1];
@@ -79,6 +79,9 @@
if (wavType != 0)
*wavType = type;
+
+ if (blockAlign_ != 0)
+ *blockAlign_ = blockAlign;
#if 0
printf("WAVE information:\n");
printf(" total size: %d\n", wavLength);
Index: wave.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/wave.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- wave.h 18 Oct 2005 01:30:23 -0000 1.5
+++ wave.h 21 Oct 2005 02:00:12 -0000 1.6
@@ -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, uint16 *wavType = 0);
+extern bool loadWAVFromStream(Common::SeekableReadStream &stream, int &size, int &rate, byte &flags, uint16 *wavType = 0, int *blockAlign = 0);
AudioStream *makeWAVStream(Common::SeekableReadStream &stream);
More information about the Scummvm-git-logs
mailing list