[Scummvm-cvs-logs] SF.net SVN: scummvm: [32516] scummvm/trunk/engines/kyra

lordhoto at users.sourceforge.net lordhoto at users.sourceforge.net
Tue Jun 3 20:12:21 CEST 2008


Revision: 32516
          http://scummvm.svn.sourceforge.net/scummvm/?rev=32516&view=rev
Author:   lordhoto
Date:     2008-06-03 11:12:21 -0700 (Tue, 03 Jun 2008)

Log Message:
-----------
Added support for compressed kyra3 audio files.

Modified Paths:
--------------
    scummvm/trunk/engines/kyra/kyra_mr.cpp
    scummvm/trunk/engines/kyra/resource.cpp
    scummvm/trunk/engines/kyra/resource.h
    scummvm/trunk/engines/kyra/sound.cpp
    scummvm/trunk/engines/kyra/sound.h
    scummvm/trunk/engines/kyra/sound_digital.cpp

Modified: scummvm/trunk/engines/kyra/kyra_mr.cpp
===================================================================
--- scummvm/trunk/engines/kyra/kyra_mr.cpp	2008-06-03 17:36:45 UTC (rev 32515)
+++ scummvm/trunk/engines/kyra/kyra_mr.cpp	2008-06-03 18:12:21 UTC (rev 32516)
@@ -59,7 +59,7 @@
 KyraEngine_MR::KyraEngine_MR(OSystem *system, const GameFlags &flags) : KyraEngine_v2(system, flags, _mrEngineDesc) {
 	_soundDigital = 0;
 	_musicSoundChannel = -1;
-	_menuAudioFile = "TITLE1.AUD";
+	_menuAudioFile = "TITLE1";
 	_lastMusicCommand = -1;
 	_itemBuffer1 = _itemBuffer2 = 0;
 	_scoreFile = 0;
@@ -425,7 +425,7 @@
 		assert(track < _soundListSize && track >= 0);
 
 		char file[13];
-		sprintf(file, "%s.AUD", _soundList[track]);
+		sprintf(file, "%s", _soundList[track]);
 		_musicSoundChannel = _soundDigital->playSound(file, 0xFF, Audio::Mixer::kMusicSoundType);
 	}
 
@@ -483,7 +483,7 @@
 	if (_sfxFileMap[item*2+0] != 0xFF) {
 		char filename[16];
 		assert(_sfxFileMap[item*2+0] < _sfxFileListSize);
-		snprintf(filename, 16, "%s.AUD", _sfxFileList[_sfxFileMap[item*2+0]]);
+		snprintf(filename, 16, "%s", _sfxFileList[_sfxFileMap[item*2+0]]);
 		uint8 priority = _sfxFileMap[item*2+1];
 
 		_soundDigital->playSound(filename, priority, Audio::Mixer::kSFXSoundType, volume);
@@ -498,7 +498,7 @@
 void KyraEngine_MR::snd_playVoiceFile(int file) {
 	debugC(9, kDebugLevelMain, "KyraEngine_MR::snd_playVoiceFile(%d)", file);
 	char filename[16];
-	snprintf(filename, 16, "%u.AUD", (uint)file);
+	snprintf(filename, 16, "%.08u", (uint)file);
 
 	_voiceSoundChannel = _soundDigital->playSound(filename, 0xFE, Audio::Mixer::kSpeechSoundType, 255);
 }

Modified: scummvm/trunk/engines/kyra/resource.cpp
===================================================================
--- scummvm/trunk/engines/kyra/resource.cpp	2008-06-03 17:36:45 UTC (rev 32515)
+++ scummvm/trunk/engines/kyra/resource.cpp	2008-06-03 18:12:21 UTC (rev 32516)
@@ -543,6 +543,20 @@
 	return true;
 }
 
+namespace {
+
+Common::String readString(Common::SeekableReadStream &stream) {
+	Common::String result;
+	char c = 0;
+
+	while ((c = stream.readByte()) != 0)
+			result += c;
+
+	return result;
+}
+
+} // end of anonymous namespace
+
 bool ResLoaderPak::loadFile(const Common::String &filename, Common::SeekableReadStream &stream, FileList &files) const {
 	uint32 filesize = stream.size();
 	
@@ -610,6 +624,33 @@
 		startoffset = endoffset;
 	}
 
+	FileList::const_iterator iter = Common::find(files.begin(), files.end(), Common::String("LINKLIST"));
+	if (iter != files.end()) {
+		stream.seek(iter->entry.offset, SEEK_SET);
+
+		uint32 magic = stream.readUint32BE();
+
+		if (magic != MKID_BE('SCVM'))
+			error("LINKLIST file does not contain 'SCVM' header");
+
+		uint32 links = stream.readUint32BE();
+		for (uint i = 0; i < links; ++i) {
+			Common::String linksTo = readString(stream);
+			uint32 sources = stream.readUint32BE();
+
+			iter = Common::find(files.begin(), files.end(), linksTo);
+			if (iter == files.end())
+				error("PAK file link destination '%s' not found", linksTo.c_str());
+
+			for (uint j = 0; j < sources; ++j) {
+				Common::String dest = readString(stream);
+				files.push_back(File(dest, iter->entry));
+				// Better safe than sorry, we update the 'iter' value, in case push_back invalidated it
+				iter = Common::find(files.begin(), files.end(), linksTo);
+			}
+		}
+	}
+
 	return true;
 }
 
@@ -767,7 +808,7 @@
 		entry.offset = resOffset+4;
 
 		char realFilename[20];
-		snprintf(realFilename, 20, "%u.AUD", resFilename);
+		snprintf(realFilename, 20, "%.08u.AUD", resFilename);
 
 		uint32 curOffset = stream.pos();
 		stream.seek(resOffset, SEEK_SET);

Modified: scummvm/trunk/engines/kyra/resource.h
===================================================================
--- scummvm/trunk/engines/kyra/resource.h	2008-06-03 17:36:45 UTC (rev 32515)
+++ scummvm/trunk/engines/kyra/resource.h	2008-06-03 18:12:21 UTC (rev 32516)
@@ -75,6 +75,10 @@
 		File() : filename(), entry() {}
 		File(const Common::String &f, const ResFileEntry &e) : filename(f), entry(e) {}
 
+		bool operator ==(const Common::String &r) const {
+			return filename.equalsIgnoreCase(r);
+		}
+
 		Common::String filename;
 		ResFileEntry entry;
 	};

Modified: scummvm/trunk/engines/kyra/sound.cpp
===================================================================
--- scummvm/trunk/engines/kyra/sound.cpp	2008-06-03 17:36:45 UTC (rev 32515)
+++ scummvm/trunk/engines/kyra/sound.cpp	2008-06-03 18:12:21 UTC (rev 32516)
@@ -50,9 +50,9 @@
 
 bool Sound::voiceFileIsPresent(const char *file) {
 	char filenamebuffer[25];
-	for (int i = 0; _supportedCodes[i].fileext; ++i) {
+	for (int i = 0; _supportedCodecs[i].fileext; ++i) {
 		strcpy(filenamebuffer, file);
-		strcat(filenamebuffer, _supportedCodes[i].fileext);
+		strcat(filenamebuffer, _supportedCodecs[i].fileext);
 		if (_vm->resource()->getFileSize(filenamebuffer) > 0)
 			return true;
 	}
@@ -77,14 +77,14 @@
 
 	Audio::AudioStream *audioStream = 0;
 
-	for (int i = 0; _supportedCodes[i].fileext; ++i) {
+	for (int i = 0; _supportedCodecs[i].fileext; ++i) {
 		strcpy(filenamebuffer, file);
-		strcat(filenamebuffer, _supportedCodes[i].fileext);
+		strcat(filenamebuffer, _supportedCodecs[i].fileext);
 
 		Common::SeekableReadStream *stream = _vm->resource()->getFileStream(filenamebuffer);
 		if (!stream)
 			continue;
-		audioStream = _supportedCodes[i].streamFunc(stream, true, 0, 0, 1);
+		audioStream = _supportedCodecs[i].streamFunc(stream, true, 0, 0, 1);
 		break;
 	}
 
@@ -551,7 +551,7 @@
 
 // static res
 
-const Sound::SpeechCodecs Sound::_supportedCodes[] = {
+const Sound::SpeechCodecs Sound::_supportedCodecs[] = {
 #ifdef USE_FLAC
 	{ ".VOF", Audio::makeFlacStream },
 #endif // USE_FLAC

Modified: scummvm/trunk/engines/kyra/sound.h
===================================================================
--- scummvm/trunk/engines/kyra/sound.h	2008-06-03 17:36:45 UTC (rev 32515)
+++ scummvm/trunk/engines/kyra/sound.h	2008-06-03 18:12:21 UTC (rev 32516)
@@ -232,7 +232,7 @@
 			uint numLoops);
 	};
 
-	static const SpeechCodecs _supportedCodes[];
+	static const SpeechCodecs _supportedCodecs[];
 };
 
 class AdlibDriver;
@@ -498,6 +498,7 @@
 
 // Digital Audio
 class AUDStream;
+class KyraAudioStream;
 class KyraEngine_MR;
 
 /**
@@ -564,8 +565,20 @@
 
 		char filename[16];
 		uint8 priority;
-		AUDStream *stream;
+		KyraAudioStream *stream;
 	} _sounds[4];
+
+	struct AudioCodecs {
+		const char *fileext;
+		Audio::AudioStream *(*streamFunc)(
+			Common::SeekableReadStream *stream,
+			bool disposeAfterUse,
+			uint32 startTime,
+			uint32 duration,
+			uint numLoops);
+	};
+
+	static const AudioCodecs _supportedCodecs[];
 };
 
 } // end of namespace Kyra

Modified: scummvm/trunk/engines/kyra/sound_digital.cpp
===================================================================
--- scummvm/trunk/engines/kyra/sound_digital.cpp	2008-06-03 17:36:45 UTC (rev 32515)
+++ scummvm/trunk/engines/kyra/sound_digital.cpp	2008-06-03 18:12:21 UTC (rev 32516)
@@ -29,8 +29,79 @@
 
 #include "sound/audiostream.h"
 
+#include "sound/mp3.h"
+#include "sound/vorbis.h"
+#include "sound/flac.h"
+
 namespace Kyra {
 
+class KyraAudioStream : public Audio::AudioStream {
+public:
+	KyraAudioStream(Audio::AudioStream *impl) : _impl(impl), _rate(impl->getRate()), _fadeSamples(0), _fadeCount(0), _fading(0), _endOfData(false) {}
+	~KyraAudioStream() { delete _impl; _impl = 0; }
+
+	int readBuffer(int16 *buffer, const int numSamples);
+	bool isStereo() const { return _impl->isStereo(); }
+	bool endOfData() const { return _impl->endOfData() | _endOfData; }
+	int getRate() const { return _rate; }
+	int32 getTotalPlayTime() const { return _impl->getTotalPlayTime(); }
+
+	void setRate(int newRate) { _rate = newRate; }
+	void beginFadeOut(uint32 millis);
+private:
+	Audio::AudioStream *_impl;
+
+	int _rate;
+
+	int32 _fadeSamples;
+	int32 _fadeCount;
+	int _fading;
+	
+	bool _endOfData;
+};
+
+void KyraAudioStream::beginFadeOut(uint32 millis) {
+	_fadeSamples = (millis * getRate()) / 1000;
+	if (_fading == 0)
+		_fadeCount = _fadeSamples;
+	_fading = -1;
+}
+
+int KyraAudioStream::readBuffer(int16 *buffer, const int numSamples) {
+	int samplesRead = _impl->readBuffer(buffer, numSamples);
+	
+	if (_fading) {
+		int samplesProcessed = 0;
+		for (; samplesProcessed < samplesRead; ++samplesProcessed) {
+			// To help avoid overflows for long fade times, we divide both
+			// _fadeSamples and _fadeCount when calculating the new sample.
+	
+			int32 div = _fadeSamples / 256;
+			if (_fading) {
+				*buffer = (*buffer * (_fadeCount / 256)) / div;
+				++buffer;
+
+				_fadeCount += _fading;
+
+				if (_fadeCount < 0) {
+					_fadeCount = 0;
+					_endOfData = true;
+				} else if (_fadeCount > _fadeSamples) {
+					_fadeCount = _fadeSamples;
+					_fading = 0;
+				}
+			}
+		}
+
+		if (_endOfData) {
+			memset(buffer, 0, (samplesRead - samplesProcessed) * sizeof(int16));
+			samplesRead = samplesProcessed;
+		}
+	}
+
+	return samplesRead;
+}
+
 // Thanks to Torbjorn Andersson (eriktorbjorn) for his aud player on which
 // this code is based on
 
@@ -46,11 +117,7 @@
 	bool isStereo() const { return false; }
 	bool endOfData() const { return _endOfData; }
 
-	void setRate(int newRate) { _rate = newRate; }
 	int getRate() const { return _rate; }
-
-	void beginFadeIn(uint32 millis);
-	void beginFadeOut(uint32 millis);
 private:
 	Common::SeekableReadStream *_stream;
 	bool _loop;
@@ -69,10 +136,6 @@
 	byte *_inBuffer;
 	uint _inBufferSize;
 
-	int32 _fadeSamples;
-	int32 _fadeCount;
-	int _fading;
-
 	int readChunk(int16 *buffer, const int maxSamples);
 
 	static const int8 WSTable2Bit[];
@@ -93,9 +156,6 @@
 	_totalSize = _stream->readUint32LE();
 	_loop = loop;
 
-	_fadeSamples = 0;
-	_fading = 0;
-
 	// TODO?: add checks
 	int flags = _stream->readByte();	// flags
 	int type = _stream->readByte();	// type
@@ -114,20 +174,6 @@
 	delete _stream;
 }
 
-void AUDStream::beginFadeIn(uint32 millis) {
-	_fadeSamples = (millis * getRate()) / 1000;
-	if (_fading == 0)
-		_fadeCount = 0;
-	_fading = 1;
-}
-
-void AUDStream::beginFadeOut(uint32 millis) {
-	_fadeSamples = (millis * getRate()) / 1000;
-	if (_fading == 0)
-		_fadeCount = _fadeSamples;
-	_fading = -1;
-}
-
 int AUDStream::readBuffer(int16 *buffer, const int numSamples) {
 	int samplesRead = 0, samplesLeft = numSamples;
 
@@ -288,34 +334,13 @@
 		samplesProcessed += samples;
 		_bytesLeft -= samples;
 
-		// To help avoid overflows for long fade times, we divide both
-		// _fadeSamples and _fadeCount when calculating the new sample.
-
-		int32 div = _fadeSamples / 256;
-
 		while (samples--) {
 			int16 sample = (_outBuffer[_outBufferOffset++] << 8) ^ 0x8000;
 
-			if (_fading) {
-				sample = (sample * (_fadeCount / 256)) / div;
-				_fadeCount += _fading;
-
-				if (_fadeCount < 0) {
-					_fadeCount = 0;
-					_endOfData = true;
-				} else if (_fadeCount > _fadeSamples) {
-					_fadeCount = _fadeSamples;
-					_fading = 0;
-				}
-			}
-
 			*buffer++ = sample;
 		}
 	}
 
-	if (_fading < 0 && _fadeCount == 0)
-		_fading = 0;
-
 	return samplesProcessed;
 }
 
@@ -367,7 +392,19 @@
 		}
 	}
 
-	Common::SeekableReadStream *stream = _vm->resource()->getFileStream(filename);
+	Common::SeekableReadStream *stream = 0;
+	int usedCodec = -1;
+	for (int i = 0; _supportedCodecs[i].fileext; ++i) {
+		Common::String file = filename;
+		file += _supportedCodecs[i].fileext;
+
+		if (!_vm->resource()->exists(file.c_str()))
+			continue;
+
+		stream = _vm->resource()->getFileStream(file);
+		usedCodec = i;
+	}
+
 	if (!stream) {
 		warning("Couldn't find soundfile '%s'", filename);
 		return -1;
@@ -375,7 +412,13 @@
 
 	strncpy(use->filename, filename, sizeof(use->filename));
 	use->priority = priority;
-	use->stream = new AUDStream(stream, loop);
+	Audio::AudioStream *audioStream = _supportedCodecs[usedCodec].streamFunc(stream, true, 0, 0, loop ? 0 : 1);
+	if (!audioStream) {
+		warning("Couldn't create audio stream for file '%s'", filename);
+		return -1;
+	}
+	use->stream = new KyraAudioStream(audioStream);
+	assert(use->stream);
 	if (use->stream->endOfData()) {
 		delete use->stream;
 		use->stream = 0;
@@ -428,5 +471,30 @@
 		_sounds[channel].stream->beginFadeOut(ticks * _vm->tickLength());
 }
 
+// static res
+
+namespace {
+
+Audio::AudioStream *makeAUDStream(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 startTime, uint32 duration, uint numLoops) {
+	return new AUDStream(stream, numLoops == 0 ? true : false);
+}
+
+} // end of anonymous namespace
+
+const SoundDigital::AudioCodecs SoundDigital::_supportedCodecs[] = {
+#ifdef USE_FLAC
+	{ ".FLA", Audio::makeFlacStream },
+#endif // USE_FLAC
+#ifdef USE_VORBIS
+	{ ".OGG", Audio::makeVorbisStream },
+#endif // USE_VORBIS
+#ifdef USE_MAD
+	{ ".MP3", Audio::makeMP3Stream },
+#endif // USE_MAD
+	{ ".AUD", makeAUDStream },
+	{ 0, 0 }
+};
+
+
 } // end of namespace Kyra
 


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