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

eriktorbjorn at users.sourceforge.net eriktorbjorn at users.sourceforge.net
Thu May 25 02:55:03 CEST 2006


Revision: 22624
Author:   eriktorbjorn
Date:     2006-05-25 02:53:51 -0700 (Thu, 25 May 2006)
ViewCVS:  http://svn.sourceforge.net/scummvm/?rev=22624&view=rev

Log Message:
-----------
Added support for fading digital music in or out.

Modified Paths:
--------------
    scummvm/trunk/engines/kyra/kyra3.cpp
    scummvm/trunk/engines/kyra/sound.h
    scummvm/trunk/engines/kyra/sound_digital.cpp
Modified: scummvm/trunk/engines/kyra/kyra3.cpp
===================================================================
--- scummvm/trunk/engines/kyra/kyra3.cpp	2006-05-25 08:07:20 UTC (rev 22623)
+++ scummvm/trunk/engines/kyra/kyra3.cpp	2006-05-25 09:53:51 UTC (rev 22624)
@@ -183,7 +183,7 @@
 	uint32 temp = 0;
 	_res->fileHandle(_menuAudioFile, &temp, *handle);
 	if (handle->isOpen()) {
-		_musicSoundChannel = _soundDigital->playSound(handle, true, -1);
+		_musicSoundChannel = _soundDigital->playSound(handle, true);
 	}
 }
 

Modified: scummvm/trunk/engines/kyra/sound.h
===================================================================
--- scummvm/trunk/engines/kyra/sound.h	2006-05-25 08:07:20 UTC (rev 22623)
+++ scummvm/trunk/engines/kyra/sound.h	2006-05-25 09:53:51 UTC (rev 22624)
@@ -39,6 +39,8 @@
 
 namespace Kyra {
 
+class AUDStream;
+
 class Sound {
 public:
 	Sound(KyraEngine *engine, Audio::Mixer *mixer);
@@ -221,9 +223,10 @@
 
 	bool init();
 	
-	int playSound(Common::File *fileHandle, bool loop = false, int channel = -1);
+	int playSound(Common::File *fileHandle, bool loop = false, bool fadeIn = false, int channel = -1);
 	bool isPlaying(int channel);
 	void stopSound(int channel);
+	void beginFadeOut(int channel);
 private:
 	KyraEngine *_vm;
 	Audio::Mixer *_mixer;
@@ -231,6 +234,7 @@
 	struct Sound {
 		Common::File *fileHandle;
 		Audio::SoundHandle handle;
+		AUDStream *stream;
 	} _sounds[SOUND_STREAMS];
 };
 

Modified: scummvm/trunk/engines/kyra/sound_digital.cpp
===================================================================
--- scummvm/trunk/engines/kyra/sound_digital.cpp	2006-05-25 08:07:20 UTC (rev 22623)
+++ scummvm/trunk/engines/kyra/sound_digital.cpp	2006-05-25 09:53:51 UTC (rev 22624)
@@ -42,6 +42,9 @@
 	bool endOfData() const { return _endOfData; }
 	
 	int getRate() const { return _rate; }
+
+	void beginFadeIn();
+	void beginFadeOut();
 private:
 	Common::File *_file;
 	bool _loop;
@@ -53,12 +56,16 @@
 	
 	int _bytesLeft;
 	
-	uint8 *_outBuffer;
+	byte *_outBuffer;
 	int _outBufferOffset;
 	uint _outBufferSize;
 	
-	uint8 *_inBuffer;
+	byte *_inBuffer;
 	uint _inBufferSize;
+
+	int32 _fadeSamples;
+	int32 _fadeCount;
+	int _fading;
 	
 	int readChunk(int16 *buffer, const int maxSamples);
 	
@@ -90,6 +97,13 @@
 	_rate = _file->readUint16LE();
 	_totalSize = _file->readUint32LE();
 	_loop = loop;
+
+	// TODO: Find the correct number of samples for a fade-in/out. Should
+	//       probably take the same amount of time as a palette fade.
+
+	_fadeSamples = 2 * getRate();
+	_fading = 0;
+
 	// TODO?: add checks
 	int flags = _file->readByte();	// flags
 	int type = _file->readByte();	// type
@@ -113,6 +127,18 @@
 #endif
 }
 
+void AUDStream::beginFadeIn() {
+	if (_fading == 0)
+		_fadeCount = 0;
+	_fading = 1;
+}
+
+void AUDStream::beginFadeOut() {
+	if (_fading == 0)
+		_fadeCount = _fadeSamples;
+	_fading = -1;
+}
+
 int AUDStream::readBuffer(int16 *buffer, const int numSamples) {
 	int samplesRead = 0, samplesLeft = numSamples;
 	
@@ -273,12 +299,34 @@
 		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 = (int8)_outBuffer[_outBufferOffset++];
-			*buffer++ = (sample << 8) ^ 0x8000;
+			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 = false;
+
 	return samplesProcessed;
 }
 
@@ -298,15 +346,15 @@
 	return true;
 }
 
-int SoundDigital::playSound(Common::File *fileHandle, bool loop, int channel) {
+int SoundDigital::playSound(Common::File *fileHandle, bool loop, bool fadeIn, int channel) {
 	Sound *use = 0;
 	if (channel != -1 && channel < SOUND_STREAMS) {
 		stopSound(channel);
 		use = &_sounds[channel];
 	} else {
-		for (int i = 0; i < SOUND_STREAMS; ++i) {
-			if (!_sounds[i].fileHandle) {
-				use = &_sounds[i];
+		for (channel = 0; channel < SOUND_STREAMS; ++channel) {
+			if (!_sounds[channel].fileHandle) {
+				use = &_sounds[channel];
 				break;
 			}
 		}
@@ -317,16 +365,19 @@
 		}
 	}
 	
-	Audio::AudioStream *stream = new AUDStream(fileHandle, loop);
-	if (stream->endOfData()) {
-		delete stream;
+	use->stream = new AUDStream(fileHandle, loop);
+	if (use->stream->endOfData()) {
+		delete use->stream;
 		delete fileHandle;
 
 		return -1;
 	}
+
+	if (fadeIn)
+		use->stream->beginFadeIn();
 	
 	// TODO: set correct sound type from channel id
-	_mixer->playInputStream(Audio::Mixer::kPlainSoundType, &use->handle, stream);
+	_mixer->playInputStream(Audio::Mixer::kPlainSoundType, &use->handle, use->stream);
 	use->fileHandle = fileHandle;
 	
 	return use - _sounds;
@@ -348,8 +399,14 @@
 	
 	if (_sounds[channel].fileHandle) {
 		delete _sounds[channel].fileHandle;
-		_sounds[channel].fileHandle = 0;			
+		_sounds[channel].fileHandle = 0;
 	}
 }
 
+void SoundDigital::beginFadeOut(int channel) {
+	if (isPlaying(channel)) {
+		_sounds[channel].stream->beginFadeOut();
+	}
+}
+
 } // 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