From 341d875ceabcccd75d7921777c0158f287089b2f Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 2 Jul 2009 12:15:04 +0000 Subject: Added support for compressed sample files (patch #2815426 by m_kiewitz) svn-id: r42020 --- engines/tinsel/detection.cpp | 2 +- engines/tinsel/sound.cpp | 96 +++++++++++++++++++++++++++++++++++++++----- engines/tinsel/sound.h | 10 +++++ 3 files changed, 98 insertions(+), 10 deletions(-) (limited to 'engines') diff --git a/engines/tinsel/detection.cpp b/engines/tinsel/detection.cpp index a3cd0bc7b7..3ca8adf30d 100644 --- a/engines/tinsel/detection.cpp +++ b/engines/tinsel/detection.cpp @@ -505,7 +505,7 @@ static const TinselGameDescription gameDescriptions[] = { "CD", { {"dw2.scn", 0, "c6d15ce9720a9d8fef06e6582dcf3f34", 103593}, - {"english1.smp", 0, "aa8d05f6fade11e6f066d42c302c8e89", 250926923}, + {"english1.smp", 0, NULL, -1}, {"english1.txt", 0, "b522e19d7b2cd7b85e50e36fe48e36a9", 274444}, {NULL, 0, NULL, 0} }, diff --git a/engines/tinsel/sound.cpp b/engines/tinsel/sound.cpp index a07a417723..c6d30fa222 100644 --- a/engines/tinsel/sound.cpp +++ b/engines/tinsel/sound.cpp @@ -41,6 +41,9 @@ #include "sound/mixer.h" #include "sound/adpcm.h" #include "sound/vag.h" +#include "sound/flac.h" +#include "sound/mp3.h" +#include "sound/vorbis.h" #include "gui/message.h" @@ -52,7 +55,9 @@ extern LANGUAGE sampleLanguage; SoundManager::SoundManager(TinselEngine *vm) : //_vm(vm), // TODO: Enable this once global _vm var is gone - _sampleIndex(0), _sampleIndexLen(0) { + _sampleIndex(0), _sampleIndexLen(0), + _soundMode(kVOCMode) + { for (int i = 0; i < kNumChannels; i++) _channels[i].sampleNum = _channels[i].subSample = -1; @@ -68,6 +73,7 @@ SoundManager::~SoundManager() { * @param type type of sound (voice or sfx) * @param handle sound handle */ +// playSample for DiscWorld 1 bool SoundManager::playSample(int id, Audio::Mixer::SoundType type, Audio::SoundHandle *handle) { // Floppy version has no sample file if (_vm->getFeatures() & GF_FLOPPY) @@ -114,7 +120,7 @@ bool SoundManager::playSample(int id, Audio::Mixer::SoundType type, Audio::Sound _vm->_mixer->playInputStream(type, &curChan.handle, vagStream); } else { // allocate a buffer - void *sampleBuf = malloc(sampleLen); + byte *sampleBuf = (byte *)malloc(sampleLen); assert(sampleBuf); // read all of the sample @@ -126,10 +132,35 @@ bool SoundManager::playSample(int id, Audio::Mixer::SoundType type, Audio::Sound //_vm->_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, soundVolumeMusic); _vm->_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, volVoice); + Common::MemoryReadStream *compressedStream = + new Common::MemoryReadStream(sampleBuf, sampleLen, true); + Audio::AudioStream *sampleStream = 0; // play it - _vm->_mixer->playRaw(type, &curChan.handle, sampleBuf, sampleLen, 22050, - Audio::Mixer::FLAG_AUTOFREE | Audio::Mixer::FLAG_UNSIGNED); + switch (_soundMode) { + case kMP3Mode: + #ifdef USE_MAD + sampleStream = Audio::makeMP3Stream(compressedStream, true); + #endif + break; + case kVorbisMode: + #ifdef USE_VORBIS + sampleStream = Audio::makeVorbisStream(compressedStream, true); + #endif + break; + case kFlacMode: + #ifdef USE_FLAC + sampleStream = Audio::makeFlacStream(compressedStream, true); + #endif + break; + default: + _vm->_mixer->playRaw(type, &curChan.handle, sampleBuf, sampleLen, 22050, + Audio::Mixer::FLAG_AUTOFREE | Audio::Mixer::FLAG_UNSIGNED); + break; + } + if (sampleStream) { + _vm->_mixer->playInputStream(type, &curChan.handle, sampleStream); + } } if (handle) @@ -138,6 +169,7 @@ bool SoundManager::playSample(int id, Audio::Mixer::SoundType type, Audio::Sound return true; } +// playSample for DiscWorld 2 bool SoundManager::playSample(int id, int sub, bool bLooped, int x, int y, int priority, Audio::Mixer::SoundType type, Audio::SoundHandle *handle) { @@ -251,10 +283,30 @@ bool SoundManager::playSample(int id, int sub, bool bLooped, int x, int y, int p if (_sampleStream.read(sampleBuf, sampleLen) != sampleLen) error(FILE_IS_CORRUPT, _vm->getSampleFile(sampleLanguage)); - Common::MemoryReadStream *sampleStream = + Common::MemoryReadStream *compressedStream = new Common::MemoryReadStream(sampleBuf, sampleLen, true); - Audio::AudioStream *_stream = - makeADPCMStream(sampleStream, true, sampleLen, Audio::kADPCMTinsel6, 22050, 1, 24); + Audio::AudioStream *sampleStream = 0; + + switch (_soundMode) { + case kMP3Mode: + #ifdef USE_MAD + sampleStream = Audio::makeMP3Stream(compressedStream, true); + #endif + break; + case kVorbisMode: + #ifdef USE_VORBIS + sampleStream = Audio::makeVorbisStream(compressedStream, true); + #endif + break; + case kFlacMode: + #ifdef USE_FLAC + sampleStream = Audio::makeFlacStream(compressedStream, true); + #endif + break; + default: + sampleStream = Audio::makeADPCMStream(compressedStream, true, sampleLen, Audio::kADPCMTinsel6, 22050, 1, 24); + break; + } // FIXME: Should set this in a different place ;) _vm->_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, volSound); @@ -269,10 +321,12 @@ bool SoundManager::playSample(int id, int sub, bool bLooped, int x, int y, int p curChan->priority = priority; curChan->lastStart = g_system->getMillis(); // /---Compression----\ Milis BytesPerSecond - curChan->timeDuration = (((sampleLen * 64) / 25) * 1000) / (22050 * 2); + // not needed and won't work when using MP3/OGG/FLAC anyway + //curChan->timeDuration = (((sampleLen * 64) / 25) * 1000) / (22050 * 2); // Play it - _vm->_mixer->playInputStream(type, &curChan->handle, _stream); + _vm->_mixer->playInputStream(type, &curChan->handle, sampleStream); + _vm->_mixer->setChannelVolume(curChan->handle, sndVol); _vm->_mixer->setChannelBalance(curChan->handle, getPan(x)); @@ -455,6 +509,30 @@ void SoundManager::openSampleFiles(void) { // convert file size to size in DWORDs _sampleIndexLen /= sizeof(uint32); + + // Detect format of soundfile by looking at 1st sample-index + switch (_sampleIndex[0]) { + case MKID_BE(' 3PM'): + debugC(DEBUG_DETAILED, kTinselDebugSound, "Detected MP3 sound-data"); + _soundMode = kMP3Mode; + break; + + case MKID_BE(' GGO'): + debugC(DEBUG_DETAILED, kTinselDebugSound, "Detected OGG sound-data"); + _soundMode = kVorbisMode; + break; + + case MKID_BE('CLAF'): + debugC(DEBUG_DETAILED, kTinselDebugSound, "Detected FLAC sound-data"); + _soundMode = kFlacMode; + break; + + default: + debugC(DEBUG_DETAILED, kTinselDebugSound, "Detected original sound-data"); + break; + } + // Normally the 1st sample-index points to nothing at all + _sampleIndex[0] = 0; } else { char buf[50]; sprintf(buf, CANNOT_FIND_FILE, _vm->getSampleIndex(sampleLanguage)); diff --git a/engines/tinsel/sound.h b/engines/tinsel/sound.h index 15919f8ec5..9bdd037ff0 100644 --- a/engines/tinsel/sound.h +++ b/engines/tinsel/sound.h @@ -58,6 +58,13 @@ protected: }; static const int kNumChannels = kChannelSFX + kNumSFX; + enum SoundMode { + kVOCMode, + kMP3Mode, + kVorbisMode, + kFlacMode + }; + struct Channel { // Sample handle Audio::SoundHandle handle; @@ -87,6 +94,9 @@ protected: /** Number of entries in the sample index */ long _sampleIndexLen; + /** Specifies if the sample-data is compressed and if yes, how */ + SoundMode _soundMode; + /** file stream for sample file */ TinselFile _sampleStream; -- cgit v1.2.3