diff options
author | Sven Hesse | 2008-12-02 21:58:48 +0000 |
---|---|---|
committer | Sven Hesse | 2008-12-02 21:58:48 +0000 |
commit | 30b6294d3834384951417ef2bf459bac5092ca10 (patch) | |
tree | a224c2217285d9a262b089c0011f748fdfa8be6c /sound | |
parent | a243d61b6889d455237b08caa117a4793eaba8f5 (diff) | |
download | scummvm-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.cpp | 43 |
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; |