diff options
author | Eugene Sandulenko | 2005-05-03 20:36:07 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2005-05-03 20:36:07 +0000 |
commit | a71d60686c529cc4f0fbc19791bfd7b6420e46d7 (patch) | |
tree | 107c7f8d19f704d1db103dc115b53e175f8ecd9c /saga | |
parent | 6101cfd71b8b79146a7d1de5df5d354faa029c46 (diff) | |
download | scummvm-rg350-a71d60686c529cc4f0fbc19791bfd7b6420e46d7.tar.gz scummvm-rg350-a71d60686c529cc4f0fbc19791bfd7b6420e46d7.tar.bz2 scummvm-rg350-a71d60686c529cc4f0fbc19791bfd7b6420e46d7.zip |
Moved Oki ADPCM aka VOX decoder from SAGA engine to common sound/ directory.
Implemented IMA ADPCM decoder.
svn-id: r17903
Diffstat (limited to 'saga')
-rw-r--r-- | saga/sound.cpp | 119 | ||||
-rw-r--r-- | saga/sound.h | 1 |
2 files changed, 10 insertions, 110 deletions
diff --git a/saga/sound.cpp b/saga/sound.cpp index 0a6a2bd061..9c2400fb65 100644 --- a/saga/sound.cpp +++ b/saga/sound.cpp @@ -26,119 +26,12 @@ #include "sound/audiostream.h" #include "sound/mixer.h" +#include "sound/adpcm.h" namespace Saga { -#define BUFFER_SIZE 4096 - -// Routines to convert 12 bit linear samples to the -// Dialogic or Oki ADPCM coding format. -class VOXInputStream : public AudioStream { -private: - const byte *_buf; - uint32 _pos; - uint32 _inputLen; - bool _evenPos; - - struct adpcmStatus { - int16 last; - int16 stepIndex; - } _status; - - int16 stepAdjust(byte); - int16 adpcmDecode(byte); - -public: - VOXInputStream(const byte *input, int inputLen); - ~VOXInputStream() {}; - - int readBuffer(int16 *buffer, const int numSamples); - - bool endOfData() const { return _pos >= _inputLen; } - bool isStereo() const { return false; } - int getRate() const { return 22050; } -}; - - -VOXInputStream::VOXInputStream(const byte *input, int inputLen) - : _buf(input), _pos(0), _inputLen(inputLen), _evenPos(true) { - - _status.last = 0; - _status.stepIndex = 0; -} - -int VOXInputStream::readBuffer(int16 *buffer, const int numSamples) { - int samples = 0; - - while (samples < numSamples && !endOfData()) { - const int len = MIN(numSamples - samples, (int) (_inputLen - _pos)); - - // * 16 effectively converts 12-bit input to 16-bit output - for (int i = 0; i < len; i++) { - if (_evenPos) - buffer[i] = adpcmDecode((_buf[_pos] >> 4) & 0x0f) * 16; - else { - buffer[i] = adpcmDecode(_buf[_pos] & 0x0f) * 16; - _pos++; - } - _evenPos = !_evenPos; - } - - samples += len; - } - return samples; -} - -// adjust the step for use on the next sample. -int16 VOXInputStream::stepAdjust(byte code) { - static int16 adjusts[] = {-1, -1, -1, -1, 2, 4, 6, 8}; - - return adjusts[code & 0x07]; -} - -static int16 stepSize[49] = { 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, - 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, - 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, - 724, 796, 876, 963, 1060, 1166, 1282, 1408, 1552 }; - -// Decode Linear to ADPCM -int16 VOXInputStream::adpcmDecode(byte code) { - int16 diff, E, SS, samp; - - SS = stepSize[_status.stepIndex]; - E = SS/8; - if (code & 0x01) - E += SS/4; - if (code & 0x02) - E += SS/2; - if (code & 0x04) - E += SS; - diff = (code & 0x08) ? -E : E; - samp = _status.last + diff; - - // Clip the values to +/- 2^11 (supposed to be 12 bits) - if(samp > 2048) - samp = 2048; - if(samp < -2048) - samp = -2048; - - _status.last = samp; - _status.stepIndex += stepAdjust(code); - if(_status.stepIndex < 0) - _status.stepIndex = 0; - if(_status.stepIndex > 48) - _status.stepIndex = 48; - - return samp; -} - -AudioStream *makeVOXStream(const byte *input, int size) { - AudioStream *audioStream = new VOXInputStream(input, size); - - return audioStream; -} Sound::Sound(SagaEngine *vm, SoundMixer *mixer, int enabled) : - _vm(vm), _mixer(mixer), _enabled(enabled) { + _vm(vm), _mixer(mixer), _enabled(enabled), _voxStream(0) { _soundInitialized = 1; return; @@ -149,6 +42,7 @@ Sound::~Sound() { return; } + delete _voxStream; _soundInitialized = 0; } @@ -220,7 +114,12 @@ int Sound::playVoice(SOUNDBUFFER *buf) { int Sound::playVoxVoice(SOUNDBUFFER *buf) { AudioStream *audioStream; - audioStream = makeVOXStream(buf->s_buf, buf->s_buf_len); + if (_voxStream) + delete _voxStream; + + _voxStream = new Common::MemoryReadStream(buf->s_buf, buf->s_buf_len); + + audioStream = makeADPCMStream(*_voxStream, kADPCMOki); _mixer->playInputStream(SoundMixer::kSFXSoundType, &_voiceHandle, audioStream); return SUCCESS; diff --git a/saga/sound.h b/saga/sound.h index a0b73d69e0..4418583acb 100644 --- a/saga/sound.h +++ b/saga/sound.h @@ -71,6 +71,7 @@ public: SagaEngine *_vm; SoundMixer *_mixer; + Common::MemoryReadStream *_voxStream; SoundHandle _effectHandle; SoundHandle _voiceHandle; |