aboutsummaryrefslogtreecommitdiff
path: root/audio
diff options
context:
space:
mode:
Diffstat (limited to 'audio')
-rw-r--r--audio/decoders/adpcm.cpp23
-rw-r--r--audio/decoders/adpcm_intern.h17
2 files changed, 28 insertions, 12 deletions
diff --git a/audio/decoders/adpcm.cpp b/audio/decoders/adpcm.cpp
index 2391bdcab7..43b5a0b3da 100644
--- a/audio/decoders/adpcm.cpp
+++ b/audio/decoders/adpcm.cpp
@@ -110,7 +110,7 @@ int16 Oki_ADPCMStream::decodeOKI(byte code) {
samp = CLIP<int16>(samp, -2048, 2047);
_status.ima_ch[0].last = samp;
- _status.ima_ch[0].stepIndex += stepAdjust(code);
+ _status.ima_ch[0].stepIndex += _stepAdjustTable[code];
_status.ima_ch[0].stepIndex = CLIP<int32>(_status.ima_ch[0].stepIndex, 0, ARRAYSIZE(okiStepSize) - 1);
// * 16 effectively converts 12-bit input to 16-bit output
@@ -404,14 +404,15 @@ int DK3_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) {
#pragma mark -
-// adjust the step for use on the next sample.
-int16 ADPCMStream::stepAdjust(byte code) {
- static const int16 adjusts[] = {-1, -1, -1, -1, 2, 4, 6, 8};
-
- return adjusts[code & 0x07];
-}
+// This table is used to adjust the step for use on the next sample.
+// We could half the table, but since the lookup index used is always
+// a 4-bit nibble, it's more efficient to just keep it as it is.
+const int16 ADPCMStream::_stepAdjustTable[16] = {
+ -1, -1, -1, -1, 2, 4, 6, 8,
+ -1, -1, -1, -1, 2, 4, 6, 8
+};
-static const uint16 imaStepTable[89] = {
+const int16 Ima_ADPCMStream::_imaTable[89] = {
7, 8, 9, 10, 11, 12, 13, 14,
16, 17, 19, 21, 23, 25, 28, 31,
34, 37, 41, 45, 50, 55, 60, 66,
@@ -427,13 +428,13 @@ static const uint16 imaStepTable[89] = {
};
int16 Ima_ADPCMStream::decodeIMA(byte code, int channel) {
- int32 E = (2 * (code & 0x7) + 1) * imaStepTable[_status.ima_ch[channel].stepIndex] / 8;
+ int32 E = (2 * (code & 0x7) + 1) * _imaTable[_status.ima_ch[channel].stepIndex] / 8;
int32 diff = (code & 0x08) ? -E : E;
int32 samp = CLIP<int32>(_status.ima_ch[channel].last + diff, -32768, 32767);
_status.ima_ch[channel].last = samp;
- _status.ima_ch[channel].stepIndex += stepAdjust(code);
- _status.ima_ch[channel].stepIndex = CLIP<int32>(_status.ima_ch[channel].stepIndex, 0, ARRAYSIZE(imaStepTable) - 1);
+ _status.ima_ch[channel].stepIndex += _stepAdjustTable[code];
+ _status.ima_ch[channel].stepIndex = CLIP<int32>(_status.ima_ch[channel].stepIndex, 0, ARRAYSIZE(_imaTable) - 1);
return samp;
}
diff --git a/audio/decoders/adpcm_intern.h b/audio/decoders/adpcm_intern.h
index 8e092e67ad..b566f2c765 100644
--- a/audio/decoders/adpcm_intern.h
+++ b/audio/decoders/adpcm_intern.h
@@ -61,7 +61,6 @@ protected:
} _status;
virtual void reset();
- int16 stepAdjust(byte);
public:
ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign);
@@ -72,6 +71,16 @@ public:
virtual int getRate() const { return _rate; }
virtual bool rewind();
+
+
+ /**
+ * This table is used by some ADPCM variants (IMA and OKI) to adjust the
+ * step for use on the next sample.
+ * The first 8 entries are identical to the second 8 entries. Hence, we
+ * could half the table in size. But since the lookup index is always a
+ * 4-bit nibble, it is more efficient to just keep it as it is.
+ */
+ static const int16 _stepAdjustTable[16];
};
class Oki_ADPCMStream : public ADPCMStream {
@@ -96,6 +105,12 @@ public:
}
virtual int readBuffer(int16 *buffer, const int numSamples);
+
+
+ /**
+ * This table is used by decodeIMA.
+ */
+ static const int16 _imaTable[89];
};
class Apple_ADPCMStream : public Ima_ADPCMStream {