diff options
| author | Strangerke | 2015-05-11 01:04:04 +0200 | 
|---|---|---|
| committer | Strangerke | 2015-05-11 01:04:04 +0200 | 
| commit | 0d3750a768c8f9457530344fa6871b98dd20276b (patch) | |
| tree | 67f80d97e90564d88e0b46e4a2d3feeede7df4ec | |
| parent | eae3ff961001b9ce071873978e29310947d2212b (diff) | |
| download | scummvm-rg350-0d3750a768c8f9457530344fa6871b98dd20276b.tar.gz scummvm-rg350-0d3750a768c8f9457530344fa6871b98dd20276b.tar.bz2 scummvm-rg350-0d3750a768c8f9457530344fa6871b98dd20276b.zip | |
SHERLOCK: Add preliminar sound support
| -rw-r--r-- | engines/sherlock/sherlock.cpp | 2 | ||||
| -rw-r--r-- | engines/sherlock/sound.cpp | 112 | ||||
| -rw-r--r-- | engines/sherlock/sound.h | 13 | 
3 files changed, 119 insertions, 8 deletions
| diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 6bfc7ea7d4..2a5d9ec627 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -89,7 +89,7 @@ void SherlockEngine::initialize() {  	_saves = new SaveManager(this, _targetName);  	_scene = new Scene(this);  	_screen = new Screen(this); -	_sound = new Sound(this); +	_sound = new Sound(this, _mixer);  	_talk = new Talk(this);  	_ui = new UserInterface(this); diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index 24147a0ab9..51563d17a6 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -23,10 +23,14 @@  #include "sherlock/sherlock.h"  #include "sherlock/sound.h"  #include "common/config-manager.h" +#include "audio/audiostream.h" +#include "common/algorithm.h" +#include "audio/mixer.h" +#include "audio/decoders/raw.h"  namespace Sherlock { -Sound::Sound(SherlockEngine *vm): _vm(vm) { +Sound::Sound(SherlockEngine *vm, Audio::Mixer *mixer): _vm(vm), _mixer(mixer) {  	_digitized = false;  	_music = false;  	_voices = 0; @@ -38,6 +42,9 @@ Sound::Sound(SherlockEngine *vm): _vm(vm) {  	_soundOn = true;  	_musicOn = true;  	_speechOn = true; + +	_vm->_res->addToCache("MUSIC.LIB"); +	_vm->_res->addToCache("SND.SND");  }  /** @@ -54,10 +61,91 @@ void Sound::loadSound(const Common::String &name, int priority) {  	warning("TODO: Sound::loadSound");  } +char Sound::decodeSample(char sample, byte& prediction, int& step) { +	char diff = ((sample & 0x07) << step); + +	if (sample & 0x08) { +		if (prediction > diff) +			prediction = prediction - ((sample & 0x07) << step); +		else +			prediction = 0; +	} else { +		if (prediction < 0xff - diff) +			prediction = prediction + ((sample&0x07) << step); +		else +			prediction = 0xff; +	} + + +	if ((sample & 0x07) >= 5 && step < 3) { +		step ++; +	} else if ((sample & 0x07) == 0 && step > 0) { +		step --; +	} + +	return prediction; +} +  bool Sound::playSound(const Common::String &name, WaitType waitType) { -	// TODO -	warning("TODO: Sound::playSound"); -	return true; +	_mixer->stopHandle(_effectsHandle); + +	Common::String filename = name; +	if (!filename.contains('.')) +		filename += ".SND"; +	Common::SeekableReadStream *stream = _vm->_res->load(filename, "TITLE.SND"); + +	stream->skip(2); +	int size = stream->readUint32BE(); +	int rate = stream->readUint16BE(); +	byte *data = (byte *)malloc(size); +	byte *ptr = data; +	stream->read(ptr, size); + +	byte *decoded = (byte *)malloc((size - 1) * 2); + +	// +127 to eliminate the pop when the sound starts (signed vs unsignded PCM). Still does not help with the pop at the end +	byte prediction = (ptr[0] & 0x0f) + 127; +	int step = 0; +	int counter = 0; + +	for(int i = 1; i < size; i++) { +		decoded[counter++] = decodeSample((ptr[i]>>4)&0x0f, prediction, step); +		decoded[counter++] = decodeSample((ptr[i]>>0)&0x0f, prediction, step); +	} + +	free(data); + +	Audio::AudioStream *audioStream = Audio::makeRawStream(decoded, (size - 2) * 2, rate, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES); +	_mixer->playStream(Audio::Mixer::kPlainSoundType, &_effectsHandle, audioStream, -1,  Audio::Mixer::kMaxChannelVolume); +	_soundPlaying = true; + +	if (waitType == WAIT_RETURN_IMMEDIATELY) { +		_diskSoundPlaying = true; +		return true; +	} + +	bool retval = true; +	do { +		_vm->_events->pollEvents(); +		g_system->delayMillis(10); +		if ((waitType == WAIT_KBD_OR_FINISH) && _vm->_events->kbHit()) { +			retval = false; +			break; +		} +	} while (!_vm->shouldQuit() && _mixer->isSoundHandleActive(_effectsHandle)); +	 +	_soundPlaying = false; +	_mixer->stopHandle(_effectsHandle); + +#if 0 +	// Debug : used to dump files +	Common::DumpFile outFile; +	outFile.open(filename); +	outFile.write(decoded, (size - 2) * 2); +	outFile.flush(); +	outFile.close(); +#endif +	return retval;  }  void Sound::cacheSound(const Common::String &name, int index) { @@ -92,7 +180,21 @@ void Sound::stopSound() {  void Sound::playMusic(const Common::String &name) {  	// TODO -	warning("TODO: Sound::playMusic"); +	warning("Sound::playMusic %s", name.c_str()); +	Common::SeekableReadStream *stream = _vm->_res->load(name, "MUSIC.LIB"); + +	byte *data = new byte[stream->size()]; +	byte *ptr = data; +	stream->read(ptr, stream->size()); +	Common::DumpFile outFile; +	outFile.open(name + ".RAW"); +	outFile.write(data, stream->size()); +	outFile.flush(); +	outFile.close(); +	delete[] data; + +	stopMusic(); +	startSong();  }  void Sound::stopMusic() { diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index 56cd4ed0a8..213a6f7a1e 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -25,6 +25,11 @@  #include "common/scummsys.h"  #include "common/str.h" +#include "audio/audiostream.h" +#include "audio/mixer.h" +#include "access/files.h" +#include "audio/midiplayer.h" +#include "audio/midiparser.h"  namespace Sherlock { @@ -37,6 +42,10 @@ enum WaitType {  class Sound {  private:  	SherlockEngine *_vm; +	Audio::Mixer *_mixer; +	Audio::SoundHandle _effectsHandle; + +	char decodeSample(char sample, byte& prediction, int& step);  public:  	bool _digitized;  	bool _music; @@ -50,7 +59,7 @@ public:  	bool *_soundIsOn;  	byte *_digiBuf;  public: -	Sound(SherlockEngine *vm); +	Sound(SherlockEngine *vm, Audio::Mixer *mixer);  	void syncSoundSettings();  	void loadSound(const Common::String &name, int priority); @@ -64,7 +73,7 @@ public:  	int loadSong(int songNumber);  	void startSong();  	void freeSong(); - +	  	void playMusic(const Common::String &name);  	void stopMusic();  	void stopSndFuncPtr(int v1, int v2); | 
