aboutsummaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorSven Hesse2008-12-02 21:58:48 +0000
committerSven Hesse2008-12-02 21:58:48 +0000
commit30b6294d3834384951417ef2bf459bac5092ca10 (patch)
treea224c2217285d9a262b089c0011f748fdfa8be6c /sound
parenta243d61b6889d455237b08caa117a4793eaba8f5 (diff)
downloadscummvm-rg350-30b6294d3834384951417ef2bf459bac5092ca10.tar.gz
scummvm-rg350-30b6294d3834384951417ef2bf459bac5092ca10.tar.bz2
scummvm-rg350-30b6294d3834384951417ef2bf459bac5092ca10.zip
Apparently, constraining the number of mixing samples to be divisible by 4 is too strict, so I'm changing readBufferTinsel6() around a bit to allow for any number of samples (at the cost of adding 2 variables and a bit complexity ;))
svn-id: r35209
Diffstat (limited to 'sound')
-rw-r--r--sound/adpcm.cpp43
1 files changed, 30 insertions, 13 deletions
diff --git a/sound/adpcm.cpp b/sound/adpcm.cpp
index 5de7ae7152..d3ec7df9a0 100644
--- a/sound/adpcm.cpp
+++ b/sound/adpcm.cpp
@@ -43,6 +43,8 @@ private:
typesADPCM _type;
uint32 _blockAlign;
uint32 _blockPos;
+ uint8 _chunkPos;
+ uint16 _chunkData;
int _blockLen;
int _rate;
@@ -111,6 +113,8 @@ ADPCMInputStream::ADPCMInputStream(Common::SeekableReadStream *stream, bool disp
_endpos = stream->pos() + size;
_blockLen = 0;
_blockPos = _blockAlign; // To make sure first header is read
+ _chunkPos = 0;
+ _chunkData = 0;
if (type == kADPCMMSIma && blockAlign == 0)
error("ADPCMInputStream(): blockAlign isn't specifiled for MS IMA ADPCM");
@@ -332,30 +336,43 @@ int ADPCMInputStream::readBufferTinsel4(int channels, int16 *buffer, const int n
int ADPCMInputStream::readBufferTinsel6(int channels, int16 *buffer, const int numSamples) {
int samples;
- uint16 data;
const double eVal = 1.032226562;
samples = 0;
- assert(numSamples % 4 == 0);
-
while (samples < numSamples && !_stream->eos() && _stream->pos() < _endpos) {
if (_blockPos == _blockAlign) {
readBufferTinselHeader();
_blockPos = 0;
+ _chunkPos = 0;
}
- for (; samples < numSamples && _blockPos < _blockAlign && !_stream->eos() && _stream->pos() < _endpos; samples += 4, _blockPos += 3) {
- // Read 3 bytes = 24 bits = four 6 bit blocks
- data = _stream->readByte();
- buffer[samples] = TO_LE_16(decodeTinsel((data << 8) & 0xFC00, eVal));
- data = (data << 8) | (_stream->readByte());
- buffer[samples+1] = TO_LE_16(decodeTinsel((data << 6) & 0xFC00, eVal));
- data = (data << 8) | (_stream->readByte());
- buffer[samples+2] = TO_LE_16(decodeTinsel((data << 4) & 0xFC00, eVal));
- data = (data << 8);
- buffer[samples+3] = TO_LE_16(decodeTinsel((data << 2) & 0xFC00, eVal));
+ for (; samples < numSamples && _blockPos < _blockAlign && !_stream->eos() && _stream->pos() < _endpos; samples++, _chunkPos = (_chunkPos + 1) % 4) {
+
+ switch (_chunkPos) {
+ case 0:
+ _chunkData = _stream->readByte();
+ buffer[samples] = TO_LE_16(decodeTinsel((_chunkData << 8) & 0xFC00, eVal));
+ break;
+ case 1:
+ _chunkData = (_chunkData << 8) | (_stream->readByte());
+ buffer[samples] = TO_LE_16(decodeTinsel((_chunkData << 6) & 0xFC00, eVal));
+ _blockPos++;
+ break;
+ case 2:
+ _chunkData = (_chunkData << 8) | (_stream->readByte());
+ buffer[samples] = TO_LE_16(decodeTinsel((_chunkData << 4) & 0xFC00, eVal));
+ _blockPos++;
+ break;
+ case 3:
+ _chunkData = (_chunkData << 8);
+ buffer[samples] = TO_LE_16(decodeTinsel((_chunkData << 2) & 0xFC00, eVal));
+ _blockPos++;
+ break;
+ }
+
}
+
}
return samples;