aboutsummaryrefslogtreecommitdiff
path: root/engines/agos
diff options
context:
space:
mode:
Diffstat (limited to 'engines/agos')
-rw-r--r--engines/agos/sound.cpp95
1 files changed, 83 insertions, 12 deletions
diff --git a/engines/agos/sound.cpp b/engines/agos/sound.cpp
index 182722cf17..e9484ca994 100644
--- a/engines/agos/sound.cpp
+++ b/engines/agos/sound.cpp
@@ -55,6 +55,9 @@ public:
BaseSound(Audio::Mixer *mixer, File *file, uint32 *offsets, bool bigendian = false);
virtual ~BaseSound();
virtual void playSound(uint sound, Audio::SoundHandle *handle, byte flags) = 0;
+#if defined(USE_MAD) || defined(USE_VORBIS) || defined(USE_FLAC)
+ virtual Audio::AudioStream *makeAudioStream(uint sound) { return NULL; }
+#endif
};
class WavSound : public BaseSound {
@@ -173,17 +176,70 @@ void RawSound::playSound(uint sound, Audio::SoundHandle *handle, byte flags) {
_mixer->playRaw(handle, buffer, size, 22050, flags | Audio::Mixer::FLAG_AUTOFREE);
}
+#if defined(USE_MAD) || defined(USE_VORBIS) || defined(USE_FLAC)
+class CompAudioStream : public Audio::AudioStream {
+private:
+ BaseSound *_parent;
+ Audio::AudioStream *_stream;
+ bool _loop;
+ uint _sound;
+public:
+ CompAudioStream(BaseSound *parent, uint sound, bool loop);
+ int readBuffer(int16 *buffer, const int numSamples);
+ bool isStereo() const { return _stream ? _stream->isStereo() : 0; }
+ bool endOfData() const;
+ int getRate() const { return _stream ? _stream->getRate() : 22050; }
+};
+
+CompAudioStream::CompAudioStream(BaseSound *parent, uint sound, bool loop) {
+ _parent = parent;
+ _sound = sound;
+ _loop = loop;
+
+ _stream = _parent->makeAudioStream(sound);
+}
+
+int CompAudioStream::readBuffer(int16 *buffer, const int numSamples) {
+ if (!_loop) {
+ return _stream->readBuffer(buffer, numSamples);
+ }
+
+ int16 *buf = buffer;
+ int samplesLeft = numSamples;
+
+ while (samplesLeft > 0) {
+ int len = _stream->readBuffer(buf, samplesLeft);
+ if (len < samplesLeft) {
+ delete _stream;
+ _stream = _parent->makeAudioStream(_sound);
+ }
+ samplesLeft -= len;
+ buf += len;
+ }
+
+ return numSamples;
+}
+
+bool CompAudioStream::endOfData() const {
+ if (!_stream)
+ return true;
+ if (_loop)
+ return false;
+ return _stream->endOfData();
+}
+#endif
+
#ifdef USE_MAD
class MP3Sound : public BaseSound {
public:
MP3Sound(Audio::Mixer *mixer, File *file, uint32 base = 0) : BaseSound(mixer, file, base) {};
+ Audio::AudioStream *makeAudioStream(uint sound);
void playSound(uint sound, Audio::SoundHandle *handle, byte flags);
};
-void MP3Sound::playSound(uint sound, Audio::SoundHandle *handle, byte flags)
-{
+Audio::AudioStream *MP3Sound::makeAudioStream(uint sound) {
if (_offsets == NULL)
- return;
+ return NULL;
_file->seek(_offsets[sound], SEEK_SET);
@@ -193,7 +249,12 @@ void MP3Sound::playSound(uint sound, Audio::SoundHandle *handle, byte flags)
uint32 size = _offsets[sound + i] - _offsets[sound];
- _mixer->playInputStream(Audio::Mixer::kSFXSoundType, handle, Audio::makeMP3Stream(_file, size));
+ return Audio::makeMP3Stream(_file, size);
+}
+
+void MP3Sound::playSound(uint sound, Audio::SoundHandle *handle, byte flags)
+{
+ _mixer->playInputStream(Audio::Mixer::kSFXSoundType, handle, new CompAudioStream(this, sound, (flags & Audio::Mixer::FLAG_LOOP) != 0));
}
#endif
@@ -201,13 +262,13 @@ void MP3Sound::playSound(uint sound, Audio::SoundHandle *handle, byte flags)
class VorbisSound : public BaseSound {
public:
VorbisSound(Audio::Mixer *mixer, File *file, uint32 base = 0) : BaseSound(mixer, file, base) {};
+ Audio::AudioStream *makeAudioStream(uint sound);
void playSound(uint sound, Audio::SoundHandle *handle, byte flags);
};
-void VorbisSound::playSound(uint sound, Audio::SoundHandle *handle, byte flags)
-{
+Audio::AudioStream *VorbisSound::makeAudioStream(uint sound) {
if (_offsets == NULL)
- return;
+ return NULL;
_file->seek(_offsets[sound], SEEK_SET);
@@ -217,7 +278,12 @@ void VorbisSound::playSound(uint sound, Audio::SoundHandle *handle, byte flags)
uint32 size = _offsets[sound + i] - _offsets[sound];
- _mixer->playInputStream(Audio::Mixer::kSFXSoundType, handle, Audio::makeVorbisStream(_file, size));
+ return Audio::makeVorbisStream(_file, size);
+}
+
+void VorbisSound::playSound(uint sound, Audio::SoundHandle *handle, byte flags)
+{
+ _mixer->playInputStream(Audio::Mixer::kSFXSoundType, handle, new CompAudioStream(this, sound, (flags & Audio::Mixer::FLAG_LOOP) != 0));
}
#endif
@@ -225,13 +291,13 @@ void VorbisSound::playSound(uint sound, Audio::SoundHandle *handle, byte flags)
class FlacSound : public BaseSound {
public:
FlacSound(Audio::Mixer *mixer, File *file, uint32 base = 0) : BaseSound(mixer, file, base) {};
+ Audio::AudioStream *makeAudioStream(uint sound);
void playSound(uint sound, Audio::SoundHandle *handle, byte flags);
};
-void FlacSound::playSound(uint sound, Audio::SoundHandle *handle, byte flags)
-{
+Audio::AudioStream *FlacSound::makeAudioStream(uint sound) {
if (_offsets == NULL)
- return;
+ return NULL;
_file->seek(_offsets[sound], SEEK_SET);
@@ -241,7 +307,12 @@ void FlacSound::playSound(uint sound, Audio::SoundHandle *handle, byte flags)
uint32 size = _offsets[sound + i] - _offsets[sound];
- _mixer->playInputStream(Audio::Mixer::kSFXSoundType, handle, Audio::makeFlacStream(_file, size));
+ return Audio::makeFlacStream(_file, size);
+}
+
+void FlacSound::playSound(uint sound, Audio::SoundHandle *handle, byte flags)
+{
+ _mixer->playInputStream(Audio::Mixer::kSFXSoundType, handle, new CompAudioStream(this, sound, (flags & Audio::Mixer::FLAG_LOOP) != 0));
}
#endif