[Scummvm-cvs-logs] SF.net SVN: scummvm: [24288] scummvm/trunk/engines/agos/sound.cpp

eriktorbjorn at users.sourceforge.net eriktorbjorn at users.sourceforge.net
Fri Oct 13 07:06:57 CEST 2006


Revision: 24288
          http://svn.sourceforge.net/scummvm/?rev=24288&view=rev
Author:   eriktorbjorn
Date:     2006-10-12 22:06:53 -0700 (Thu, 12 Oct 2006)

Log Message:
-----------
Added support for playing looped compressed sounds, so that Puzzle Pack can
play music properly, even if the music file has been compressed. I've only
actually tested this with Ogg Vorbis sounds, but I've deliberately written it
so that it should work identically for all the compression types. (Famous last
words.)

Modified Paths:
--------------
    scummvm/trunk/engines/agos/sound.cpp

Modified: scummvm/trunk/engines/agos/sound.cpp
===================================================================
--- scummvm/trunk/engines/agos/sound.cpp	2006-10-13 05:00:19 UTC (rev 24287)
+++ scummvm/trunk/engines/agos/sound.cpp	2006-10-13 05:06:53 UTC (rev 24288)
@@ -55,6 +55,9 @@
 	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 @@
 	_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,21 +249,26 @@
 
 	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
 
 #ifdef USE_VORBIS
 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,21 +278,26 @@
 
 	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
 
 #ifdef USE_FLAC
 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,8 +307,13 @@
 
 	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
 
 Sound::Sound(AGOSEngine *vm, const GameSpecificSettings *gss, Audio::Mixer *mixer)


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list