Added support for compressed sample files (patch #2815426 by m_kiewitz)

svn-id: r42020
This commit is contained in:
Sven Hesse 2009-07-02 12:15:04 +00:00
parent 630501fe43
commit 341d875cea
3 changed files with 98 additions and 10 deletions

View File

@ -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}
},

View File

@ -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));

View File

@ -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;