aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorFilippos Karapetis2007-06-25 18:23:01 +0000
committerFilippos Karapetis2007-06-25 18:23:01 +0000
commit23c8240048209cd53d5d12874e28d9f9382f64c5 (patch)
tree95a1fe53464e755bdde541db22a08436ddfb92cb /engines
parent057d26e2f3a3d29f0694a5e9781b700812161430 (diff)
downloadscummvm-rg350-23c8240048209cd53d5d12874e28d9f9382f64c5.tar.gz
scummvm-rg350-23c8240048209cd53d5d12874e28d9f9382f64c5.tar.bz2
scummvm-rg350-23c8240048209cd53d5d12874e28d9f9382f64c5.zip
Add support for compressed sound effects, digital music and speech to the SAGA engine
svn-id: r27713
Diffstat (limited to 'engines')
-rw-r--r--engines/saga/saga.h5
-rw-r--r--engines/saga/sndres.cpp47
-rw-r--r--engines/saga/sound.cpp35
-rw-r--r--engines/saga/sound.h11
4 files changed, 93 insertions, 5 deletions
diff --git a/engines/saga/saga.h b/engines/saga/saga.h
index 9532d2fd56..c5038e5c5d 100644
--- a/engines/saga/saga.h
+++ b/engines/saga/saga.h
@@ -224,7 +224,10 @@ enum GameSoundTypes {
kSoundVOX = 1,
kSoundVOC = 2,
kSoundWAV = 3,
- kSoundMacPCM = 4
+ kSoundMacPCM = 4,
+ kSoundMP3 = 5,
+ kSoundOGG = 6,
+ kSoundFLAC = 7
};
enum TextStringIds {
diff --git a/engines/saga/sndres.cpp b/engines/saga/sndres.cpp
index c0442c75de..39dd9b5c06 100644
--- a/engines/saga/sndres.cpp
+++ b/engines/saga/sndres.cpp
@@ -156,7 +156,6 @@ bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buff
return false;
}
-
_vm->_resource->loadResource(context, resourceId, soundResource, soundResourceLength);
if ((context->fileType & GAME_VOICEFILE) != 0) {
@@ -175,8 +174,19 @@ bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buff
if (soundResourceLength >= 8) {
if (!memcmp(soundResource, "Creative", 8)) {
resourceType = kSoundVOC;
- } else if (!memcmp(soundResource, "RIFF", 4) != 0) {
+ } else if (!memcmp(soundResource, "RIFF", 4) != 0) {
resourceType = kSoundWAV;
+ } else if (soundResource[0] == char(0)) {
+ readS.seek(1);
+ uint16 test = readS.readUint16LE(); // the frequency
+ // the sound's frequency is not supposed to be 0, if it is then it's an empty sound,
+ // so don't treat it as MP3
+ if (test > 0) // Skip compression identifier byte
+ resourceType = kSoundMP3;
+ } else if (soundResource[0] == char(1)) {
+ resourceType = kSoundOGG;
+ } else if (soundResource[0] == char(2)) {
+ resourceType = kSoundFLAC;
}
}
@@ -188,6 +198,7 @@ bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buff
buffer.sampleBits = soundInfo->sampleBits;
buffer.size = soundResourceLength;
buffer.stereo = soundInfo->stereo;
+ buffer.isCompressed = false;
if (onlyHeader) {
buffer.buffer = NULL;
free(soundResource);
@@ -202,6 +213,7 @@ bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buff
buffer.sampleBits = soundInfo->sampleBits;
buffer.size = soundResourceLength - 36;
buffer.stereo = soundInfo->stereo;
+ buffer.isCompressed = false;
if (onlyHeader) {
buffer.buffer = NULL;
} else {
@@ -217,6 +229,7 @@ bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buff
buffer.sampleBits = soundInfo->sampleBits;
buffer.stereo = soundInfo->stereo;
buffer.size = soundResourceLength * 4;
+ buffer.isCompressed = false;
if (onlyHeader) {
buffer.buffer = NULL;
free(soundResource);
@@ -239,6 +252,7 @@ bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buff
buffer.stereo = false;
buffer.isSigned = false;
buffer.size = size;
+ buffer.isCompressed = false;
if (onlyHeader) {
buffer.buffer = NULL;
free(data);
@@ -256,6 +270,7 @@ bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buff
buffer.stereo = ((flags & Audio::Mixer::FLAG_STEREO) != 0);
buffer.isSigned = true;
buffer.size = size;
+ buffer.isCompressed = false;
if (onlyHeader) {
buffer.buffer = NULL;
} else {
@@ -266,6 +281,29 @@ bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buff
}
free(soundResource);
break;
+ case kSoundMP3:
+ case kSoundOGG:
+ case kSoundFLAC:
+ ResourceData *resourceData;
+ resourceData = _vm->_resource->getResourceData(context, resourceId);
+
+ readS.seek(1); // Skip compression identifier byte
+
+ buffer.frequency = readS.readUint16LE();
+ buffer.size = soundResourceLength;
+ buffer.originalSize = readS.readUint32LE();
+ buffer.sampleBits = readS.readByte();
+ buffer.stereo = (readS.readByte() == char(0)) ? false : true;
+ buffer.isCompressed = true;
+ buffer.soundType = resourceType;
+ buffer.soundFile = context->getFile(resourceData);
+ buffer.fileOffset = resourceData->offset;
+
+ buffer.buffer = NULL;
+
+ result = true;
+ free(soundResource);
+ break;
default:
error("SndRes::load Unknown sound type");
}
@@ -286,7 +324,10 @@ int SndRes::getVoiceLength(uint32 resourceId) {
return -1;
}
- msDouble = (double)buffer.size;
+ if (!buffer.isCompressed)
+ msDouble = (double)buffer.size;
+ else
+ msDouble = (double)buffer.originalSize;
if (buffer.sampleBits == 16) {
msDouble /= 2.0;
}
diff --git a/engines/saga/sound.cpp b/engines/saga/sound.cpp
index a4ce79b9c4..b0f4f8319b 100644
--- a/engines/saga/sound.cpp
+++ b/engines/saga/sound.cpp
@@ -80,7 +80,40 @@ void Sound::playSoundBuffer(Audio::SoundHandle *handle, SoundBuffer &buffer, int
if (!buffer.isSigned)
flags |= Audio::Mixer::FLAG_UNSIGNED;
- _mixer->playRaw(Audio::Mixer::kSFXSoundType, handle, buffer.buffer, buffer.size, buffer.frequency, flags, -1, volume);
+ if (!buffer.isCompressed) {
+ _mixer->playRaw(Audio::Mixer::kSFXSoundType, handle, buffer.buffer, buffer.size, buffer.frequency, flags, -1, volume);
+ } else {
+ buffer.soundFile->seek((long)buffer.fileOffset, SEEK_SET);
+ Audio::AudioStream *stream = NULL;
+
+ switch (buffer.soundType) {
+#ifdef USE_MAD
+ case kSoundMP3:
+ debug(1, "Playing MP3 compressed sound");
+ stream = Audio::makeMP3Stream(buffer.soundFile, buffer.size);
+ break;
+#endif
+#ifdef USE_VORBIS
+ case kSoundOGG:
+ debug(1, "Playing OGG compressed sound");
+ stream = Audio::makeVorbisStream(buffer.soundFile, buffer.size);
+ break;
+#endif
+#ifdef USE_FLAC
+ case kSoundFLAC:
+ debug(1, "Playing FLAC compressed sound");
+ stream = Audio::makeFlacStream(buffer.soundFile, buffer.size);
+ break;
+#endif
+ default:
+ // Unknown compression
+ error("Trying to play a compressed sound, but the compression is not known");
+ break;
+ }
+
+ if (stream != NULL)
+ _mixer->playInputStream(Audio::Mixer::kSFXSoundType, handle, stream, -1, volume, 0, true, false);
+ }
}
void Sound::playSound(SoundBuffer &buffer, int volume, bool loop) {
diff --git a/engines/saga/sound.h b/engines/saga/sound.h
index 3abea583ba..b75c194da4 100644
--- a/engines/saga/sound.h
+++ b/engines/saga/sound.h
@@ -28,7 +28,13 @@
#ifndef SAGA_SOUND_H
#define SAGA_SOUND_H
+#include "common/file.h"
#include "sound/mixer.h"
+#include "sound/mp3.h"
+#include "sound/vorbis.h"
+#include "sound/flac.h"
+#include "sound/rate.h"
+#include "sound/wave.h"
namespace Saga {
@@ -46,7 +52,12 @@ struct SoundBuffer {
byte *buffer;
size_t size;
+ size_t originalSize;
bool isBigEndian;
+ bool isCompressed;
+ GameSoundTypes soundType;
+ Common::File *soundFile;
+ size_t fileOffset;
};
enum sndHandleType {