[Scummvm-cvs-logs] SF.net SVN: scummvm:[40880] scummvm/trunk/engines/sci

thebluegr at users.sourceforge.net thebluegr at users.sourceforge.net
Mon May 25 12:30:20 CEST 2009


Revision: 40880
          http://scummvm.svn.sourceforge.net/scummvm/?rev=40880&view=rev
Author:   thebluegr
Date:     2009-05-25 10:30:19 +0000 (Mon, 25 May 2009)

Log Message:
-----------
Objectified the AudioResource code (used for speech and digitized music in CD talkie games)

Modified Paths:
--------------
    scummvm/trunk/engines/sci/engine/ksound.cpp
    scummvm/trunk/engines/sci/resource.cpp
    scummvm/trunk/engines/sci/resource.h
    scummvm/trunk/engines/sci/sfx/core.cpp
    scummvm/trunk/engines/sci/sfx/core.h

Modified: scummvm/trunk/engines/sci/engine/ksound.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/ksound.cpp	2009-05-25 07:57:38 UTC (rev 40879)
+++ scummvm/trunk/engines/sci/engine/ksound.cpp	2009-05-25 10:30:19 UTC (rev 40880)
@@ -86,11 +86,6 @@
 #define _K_SCI1_SOUND_REVERB 19 /* Get/Set */
 #define _K_SCI1_SOUND_UPDATE_VOL_PRI 20
 
-Audio::SoundHandle _audioHandle;
-uint16 _audioRate;
-int16 _lang;
-byte *_audioMap;
-
 enum AudioCommands {
 	// TODO: find the difference between kSci1AudioWPlay and kSci1AudioPlay
 	kSci1AudioWPlay = 1, /* Plays an audio stream */
@@ -999,33 +994,6 @@
 		return kDoSound_SCI0(s, funct_nr, argc, argv);
 }
 
-bool findAudEntry(uint16 audioNumber, byte& volume, uint32& offset, uint32& size) {
-	// AUDIO00X.MAP contains 10-byte entries:
-	// w nEntry
-	// dw offset+volume (as in resource.map)
-	// dw size
-	// ending with 10 0xFFs
-	uint16 n;
-	uint32 off;
-
-	if (_audioMap == 0)
-		return false;
-
-	byte *ptr = _audioMap;
-	while ((n = READ_UINT16(ptr)) != 0xFFFF) {
-		if (n == audioNumber) {
-			off = READ_LE_UINT32(ptr + 2);
-			size = READ_LE_UINT32(ptr + 6);
-			volume = off >> 28;
-			offset = off & 0x0FFFFFFF;
-			return true;
-		}
-		ptr += 10;
-	}
-
-	return false;
-}
-
 // Used for speech playback in CD games
 reg_t kDoAudio(EngineState *s, int funct_nr, int argc, reg_t *argv) {
 	Audio::Mixer *mixer = g_system->getMixer();
@@ -1034,94 +1002,50 @@
 	switch (UKPV(0)) {
 	case kSci1AudioWPlay:
 	case kSci1AudioPlay: {
-		mixer->stopHandle(_audioHandle);
+		s->sound.audioResource->stop();
 
+		Audio::AudioStream *audioStream = 0;
+
 		// Try to load from an external patch file first
 		Sci::Resource* audioRes = s->resmgr->findResource(kResourceTypeAudio, UKPV(1), 1);
-		Audio::AudioStream *audioStream = 0;
 
 		if (audioRes) {
-			audioStream = Audio::makeLinearInputStream(audioRes->data, audioRes->size, _audioRate, Audio::Mixer::FLAG_UNSIGNED, 0, 0);
-			sampleLen = audioRes->size * 60 / _audioRate;
+			audioStream = s->sound.audioResource->getAudioStream(audioRes, &sampleLen);
 		} else {
 			// No patch file found, read it from the audio volume
-			byte volume;
-			uint32 offset;
-			uint32 size;
-
-			if (findAudEntry(UKPV(1), volume, offset, size)) {
-				uint32 start = offset * 1000 / _audioRate;
-				uint32 duration = size * 1000 / _audioRate;
-
-				char filename[40];
-				sprintf(filename, "AUDIO%03d.%03d", _lang, volume);
-
-				// Try to load compressed
-				audioStream = Audio::AudioStream::openStreamFile(filename, start, duration);
-				if (!audioStream) {
-					// Compressed file load failed, try to load original raw data
-					byte *soundbuff = (byte *)malloc(size);
-					Common::File* audioFile = new Common::File();
-					if (audioFile->open(filename)) {
-						audioFile->seek(offset);
-						audioFile->read(soundbuff, size);
-						audioFile->close();
-						delete audioFile;
-
-						audioStream = Audio::makeLinearInputStream(soundbuff, size,	_audioRate,
-								Audio::Mixer::FLAG_AUTOFREE | Audio::Mixer::FLAG_UNSIGNED, 0, 0);
-					}
-				}
-
-				sampleLen = size * 60 / _audioRate;
-			}
+			audioStream = s->sound.audioResource->getAudioStream(UKPV(1), &sampleLen);
 		}
 
 		if (audioStream)
-			mixer->playInputStream(Audio::Mixer::kSpeechSoundType, &_audioHandle, audioStream);
-		}
+			mixer->playInputStream(Audio::Mixer::kSpeechSoundType, s->sound.audioResource->getAudioHandle(), audioStream);
 
+		}
 		return make_reg(0, sampleLen);		// return sample length in ticks
 	case kSci1AudioStop:
-		mixer->stopHandle(_audioHandle);
+		s->sound.audioResource->stop();
 		break;
 	case kSci1AudioPause:
-		mixer->pauseHandle(_audioHandle, true);
+		s->sound.audioResource->pause();
 		break;
 	case kSci1AudioResume:
-		mixer->pauseHandle(_audioHandle, false);
+		s->sound.audioResource->resume();
 		break;
 	case kSci1AudioPosition:
-		if (mixer->isSoundHandleActive(_audioHandle)) {
-			return make_reg(0, mixer->getSoundElapsedTime(_audioHandle) * 6 / 100); // return elapsed time in ticks
-		} else {
-			return make_reg(0, -1); // Sound finished
-		}
+		return make_reg(0, s->sound.audioResource->getAudioPosition());
 	case kSci1AudioRate:
-		_audioRate = UKPV(1);
+		s->sound.audioResource->setAudioRate(UKPV(1));
 		break;
 	case kSci1AudioVolume:
 		mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, UKPV(1));
 		break;
 	case kSci1AudioLanguage:
-		// TODO: CD Audio (used for example in the end credits of KQ6CD)
-		if (SKPV(1) != -1) {
-			_lang = UKPV(1);
+		if (s->sound.audioResource)
+			delete s->sound.audioResource;
 
-			char filename[40];
-			sprintf(filename, "AUDIO%03d.MAP", _lang);
+		// The audio resource is freed when freeing all resources
+		s->sound.audioResource = new AudioResource();
+		s->sound.audioResource->setAudioLang(SKPV(1));
 
-			Common::File* audioMapFile = new Common::File();
-			if (audioMapFile->open(filename)) {
-				// TODO: This needs to be freed, right now we got a memory leak here!
-				_audioMap = new byte[audioMapFile->size()];
-				audioMapFile->read(_audioMap, audioMapFile->size());
-				audioMapFile->close();
-				delete audioMapFile;
-			} else {
-				_audioMap = 0;
-			}
-		}
 		break;
 	default:
 		warning("kDoAudio: Unhandled case %d", UKPV(0));

Modified: scummvm/trunk/engines/sci/resource.cpp
===================================================================
--- scummvm/trunk/engines/sci/resource.cpp	2009-05-25 07:57:38 UTC (rev 40879)
+++ scummvm/trunk/engines/sci/resource.cpp	2009-05-25 10:30:19 UTC (rev 40880)
@@ -1159,4 +1159,113 @@
 	//syncStarted = false;	// not used
 }
 
+
+AudioResource::AudioResource() {
+	_audioRate = 0;
+	_lang = 0;
+	_audioMap = 0;
+}
+
+AudioResource::~AudioResource() { 
+	delete _audioMap;
+	_audioMap = 0;
+}
+
+void AudioResource::setAudioLang(int16 lang) {
+	// TODO: CD Audio (used for example in the end credits of KQ6CD)
+	if (lang != -1) {
+		_lang = lang;
+
+		char filename[40];
+		sprintf(filename, "AUDIO%03d.MAP", _lang);
+
+		Common::File* audioMapFile = new Common::File();
+		if (audioMapFile->open(filename)) {
+			// The audio map is freed in the destructor
+			_audioMap = new byte[audioMapFile->size()];
+			audioMapFile->read(_audioMap, audioMapFile->size());
+			audioMapFile->close();
+			delete audioMapFile;
+		} else {
+			_audioMap = 0;
+		}
+	}
+}
+
+int AudioResource::getAudioPosition() {
+	if (g_system->getMixer()->isSoundHandleActive(_audioHandle)) {
+		return g_system->getMixer()->getSoundElapsedTime(_audioHandle) * 6 / 100; // return elapsed time in ticks
+	} else {
+		return -1; // Sound finished
+	}
+}
+
+bool AudioResource::findAudEntry(uint16 audioNumber, byte& volume, uint32& offset, uint32& size) {
+	// AUDIO00X.MAP contains 10-byte entries:
+	// w nEntry
+	// dw offset+volume (as in resource.map)
+	// dw size
+	// ending with 10 0xFFs
+	uint16 n;
+	uint32 off;
+
+	if (_audioMap == 0)
+		return false;
+
+	byte *ptr = _audioMap;
+	while ((n = READ_UINT16(ptr)) != 0xFFFF) {
+		if (n == audioNumber) {
+			off = READ_LE_UINT32(ptr + 2);
+			size = READ_LE_UINT32(ptr + 6);
+			volume = off >> 28;
+			offset = off & 0x0FFFFFFF;
+			return true;
+		}
+		ptr += 10;
+	}
+
+	return false;
+}
+
+Audio::AudioStream* AudioResource::getAudioStream(uint16 audioNumber, int* sampleLen) {
+	Audio::AudioStream *audioStream = 0;
+	byte volume;
+	uint32 offset;
+	uint32 size;
+
+	if (findAudEntry(audioNumber, volume, offset, size)) {
+		uint32 start = offset * 1000 / _audioRate;
+		uint32 duration = size * 1000 / _audioRate;
+
+		char filename[40];
+		sprintf(filename, "AUDIO%03d.%03d", _lang, volume);
+
+		// Try to load compressed
+		audioStream = Audio::AudioStream::openStreamFile(filename, start, duration); 
+		if (!audioStream) { 
+			// Compressed file load failed, try to load original raw data
+			byte *soundbuff = (byte *)malloc(size);
+			Common::File* audioFile = new Common::File();
+			if (audioFile->open(filename)) {
+				audioFile->seek(offset);
+				audioFile->read(soundbuff, size);
+				audioFile->close();
+				delete audioFile;
+
+				audioStream = Audio::makeLinearInputStream(soundbuff, size,	_audioRate,
+						Audio::Mixer::FLAG_AUTOFREE | Audio::Mixer::FLAG_UNSIGNED, 0, 0);
+			}
+		}
+
+		*sampleLen = size * 60 / _audioRate;
+	}
+
+	return audioStream;
+}
+
+Audio::AudioStream* AudioResource::getAudioStream(Resource* audioRes, int* sampleLen) {
+	*sampleLen = audioRes->size * 60 / _audioRate;
+	return Audio::makeLinearInputStream(audioRes->data, audioRes->size, _audioRate, Audio::Mixer::FLAG_UNSIGNED, 0, 0);
+}
+
 } // End of namespace Sci

Modified: scummvm/trunk/engines/sci/resource.h
===================================================================
--- scummvm/trunk/engines/sci/resource.h	2009-05-25 07:57:38 UTC (rev 40879)
+++ scummvm/trunk/engines/sci/resource.h	2009-05-25 10:30:19 UTC (rev 40880)
@@ -30,6 +30,9 @@
 #include "common/file.h"
 #include "common/archive.h"
 
+#include "sound/audiostream.h"
+#include "sound/mixer.h"			// for SoundHandle
+
 #include "sci/engine/vm.h"          // for Object
 #include "sci/decompressor.h"
 
@@ -299,6 +302,32 @@
 	//bool _syncStarted;	// not used
 };
 
+class AudioResource {
+public:
+	AudioResource();
+	~AudioResource();
+
+	void setAudioRate(uint16 audioRate) { _audioRate = audioRate; }
+	void setAudioLang(int16 lang);
+
+	Audio::SoundHandle* getAudioHandle() { return &_audioHandle; }
+	int getAudioPosition();
+	Audio::AudioStream* getAudioStream(uint16 audioNumber, int* sampleLen);
+	Audio::AudioStream* getAudioStream(Resource* audioRes, int* sampleLen);
+
+	void stop() { g_system->getMixer()->stopHandle(_audioHandle); }
+	void pause() { g_system->getMixer()->pauseHandle(_audioHandle, true); }
+	void resume() { g_system->getMixer()->pauseHandle(_audioHandle, false); }
+
+private:
+	Audio::SoundHandle _audioHandle;
+	uint16 _audioRate;
+	int16 _lang;
+	byte *_audioMap;
+
+	bool findAudEntry(uint16 audioNumber, byte& volume, uint32& offset, uint32& size);
+};
+
 } // End of namespace Sci
 
 #endif // SCI_SCICORE_RESOURCE_H

Modified: scummvm/trunk/engines/sci/sfx/core.cpp
===================================================================
--- scummvm/trunk/engines/sci/sfx/core.cpp	2009-05-25 07:57:38 UTC (rev 40879)
+++ scummvm/trunk/engines/sci/sfx/core.cpp	2009-05-25 10:30:19 UTC (rev 40880)
@@ -367,6 +367,7 @@
 	self->flags = flags;
 	self->debug = 0; /* Disable all debugging by default */
 	self->soundSync = NULL;
+	self->audioResource = NULL;
 
 	if (flags & SFX_STATE_FLAG_NOSOUND) {
 		player = NULL;
@@ -443,6 +444,12 @@
 
 	if (strcmp(player->name, "new") == 0)
 		g_system->getMixer()->stopAll();
+
+	// Delete audio resources for CD talkie games
+	if (self->audioResource) {
+		delete self->audioResource;
+		self->audioResource = 0;
+	}
 }
 
 void sfx_suspend(sfx_state_t *self, int suspend) {

Modified: scummvm/trunk/engines/sci/sfx/core.h
===================================================================
--- scummvm/trunk/engines/sci/sfx/core.h	2009-05-25 07:57:38 UTC (rev 40879)
+++ scummvm/trunk/engines/sci/sfx/core.h	2009-05-25 10:30:19 UTC (rev 40880)
@@ -55,7 +55,8 @@
 	song_t *song; /* Active song, or start of active song chain */
 	int suspended; /* Whether we are suspended */
 	unsigned int debug; /* Debug flags */
-	ResourceSync *soundSync; /* Used by kDoSync for speech syncing in talkie games */
+	ResourceSync *soundSync; /* Used by kDoSync for speech syncing in CD talkie games */
+	AudioResource *audioResource; /* Used for audio resources in CD talkie games */
 };
 
 /***********/


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