diff options
| author | Eugene Sandulenko | 2004-11-15 03:03:48 +0000 | 
|---|---|---|
| committer | Eugene Sandulenko | 2004-11-15 03:03:48 +0000 | 
| commit | 4295a17c2323d025aad8ccd7084a8c3bdedfcaa6 (patch) | |
| tree | 41382d001ca51502103e788f1beabc511661186f /saga/sound.cpp | |
| parent | 183a11153e680a1b6cd399da09deff7a690304dc (diff) | |
| download | scummvm-rg350-4295a17c2323d025aad8ccd7084a8c3bdedfcaa6.tar.gz scummvm-rg350-4295a17c2323d025aad8ccd7084a8c3bdedfcaa6.tar.bz2 scummvm-rg350-4295a17c2323d025aad8ccd7084a8c3bdedfcaa6.zip | |
o Make GAME_GetFileContext() more object-like
o Font::loadFont() now normally survives zero-length fonts as used in demos
o Removed unused SndRes::ITEVOC_Resample()
o Fixed playing of voice #4 on old DOS targets
o Implemented playing voices in VOX (Oki ADPCM) format
o Support of Win32 and Linux demos. There was old-style Win32 demo, which
  is not supported yet, same is with DOS demo.
svn-id: r15814
Diffstat (limited to 'saga/sound.cpp')
| -rw-r--r-- | saga/sound.cpp | 118 | 
1 files changed, 118 insertions, 0 deletions
| diff --git a/saga/sound.cpp b/saga/sound.cpp index a6859134ae..e63f675ca0 100644 --- a/saga/sound.cpp +++ b/saga/sound.cpp @@ -25,9 +25,118 @@  #include "saga/sound.h"  #include "saga/game_mod.h" +#include "sound/audiostream.h"  #include "sound/mixer.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) { @@ -119,6 +228,15 @@ int Sound::playVoice(SOUNDBUFFER *buf) {  	return playSoundBuffer(&_voiceHandle, buf, 255, false);  } +int Sound::playVoxVoice(SOUNDBUFFER *buf) { +	AudioStream *audioStream; + +	audioStream = makeVOXStream(buf->s_buf, buf->s_buf_len); +	_mixer->playInputStream(&_voiceHandle, audioStream, false); + +	return SUCCESS; +} +  int Sound::pauseVoice() {  	if (!_soundInitialized) {  		return FAILURE; | 
