[Scummvm-git-logs] scummvm master -> 0044225060be78be594b5c360cbb690f7a30d126

npjg nathanael.gentrydb8 at gmail.com
Wed Jul 22 18:17:08 UTC 2020


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
0044225060 DIRECTOR: Make sound fade non-blocking


Commit: 0044225060be78be594b5c360cbb690f7a30d126
    https://github.com/scummvm/scummvm/commit/0044225060be78be594b5c360cbb690f7a30d126
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-07-22T14:13:38-04:00

Commit Message:
DIRECTOR: Make sound fade non-blocking

Changed paths:
    engines/director/lingo/lingo-builtins.cpp
    engines/director/score.cpp
    engines/director/score.h
    engines/director/sound.cpp
    engines/director/sound.h


diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index b74f0d80d6..586284399c 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -2112,7 +2112,6 @@ void LB::b_sound(int nargs) {
 		TYPECHECK(firstArg, INT);
 		g_director->getSoundManager()->stopSound(firstArg.u.i);
 	} else if (verb.u.s->equalsIgnoreCase("fadeIn")) {
-		// TODO: Check for case when sound channel changes while sound is being played.
 		if (nargs > 2) {
 			TYPECHECK(secondArg, INT);
 			ticks = secondArg.u.i;
@@ -2121,10 +2120,10 @@ void LB::b_sound(int nargs) {
 		}
 
 		TYPECHECK(firstArg, INT);
-		g_director->getSoundManager()->playFade(firstArg.u.i, true, ticks);
+		g_director->getSoundManager()->registerFade(firstArg.u.i, true, ticks);
+		g_director->getCurrentMovie()->getScore()->_activeFade = firstArg.u.i;
 		return;
 	} else if (verb.u.s->equalsIgnoreCase("fadeOut")) {
-		// TODO: Check for case when sound channel changes while sound is being played.
 		if (nargs > 2) {
 			TYPECHECK(secondArg, INT);
 			ticks = secondArg.u.i;
@@ -2133,7 +2132,8 @@ void LB::b_sound(int nargs) {
 		}
 
 		TYPECHECK(firstArg, INT);
-		g_director->getSoundManager()->playFade(firstArg.u.i, false, ticks);
+		g_director->getSoundManager()->registerFade(firstArg.u.i, false, ticks);
+		g_director->getCurrentMovie()->getScore()->_activeFade = firstArg.u.i;
 		return;
 	} else if (verb.u.s->equalsIgnoreCase("playFile")) {
 		ARGNUMCHECK(3)
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index a78f04e67a..2b46f1637a 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -279,6 +279,11 @@ void Score::update() {
 		_waitForChannel = 0;
 	}
 
+	if (_activeFade) {
+		if (!_soundManager->fadeChannel(_activeFade))
+			_activeFade = 0;
+	}
+
 	if (g_system->getMillis() < _nextFrameTime && !debugChannelSet(-1, kDebugFast)) {
 		return;
 	}
diff --git a/engines/director/score.h b/engines/director/score.h
index 050651d1d5..af1975f876 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -121,6 +121,7 @@ public:
 	PlayState _playState;
 	uint32 _nextFrameTime;
 	int _waitForChannel;
+	int _activeFade;
 	Cursor *_currentCursor;
 
 	int _numChannelsDisplayed;
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 9b09c7e49f..6e8dee8bcd 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -77,6 +77,7 @@ void DirectorSound::playFile(Common::String filename, uint8 soundChannel) {
 	AudioFileDecoder af(filename);
 	Audio::RewindableAudioStream *sound = af.getAudioStream(DisposeAfterUse::YES);
 
+	cancelFade(soundChannel);
 	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_channels[soundChannel - 1].handle, sound, -1, _channels[soundChannel - 1].volume);
 }
 
@@ -94,6 +95,7 @@ void DirectorSound::playStream(Audio::AudioStream &stream, uint8 soundChannel) {
 		return;
 	}
 
+	cancelFade(soundChannel);
 	_mixer->stopHandle(_channels[soundChannel - 1].handle);
 	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_channels[soundChannel - 1].handle, &stream, -1, _channels[soundChannel - 1].volume);
 }
@@ -133,42 +135,60 @@ void DirectorSound::playCastMember(int castId, uint8 soundChannel, bool allowRep
 	}
 }
 
-void DirectorSound::playFade(uint8 soundChannel, bool fadeIn, int ticks) {
+void DirectorSound::registerFade(uint8 soundChannel, bool fadeIn, int ticks) {
 	if (soundChannel == 0 || soundChannel > _channels.size()) {
 		warning("Invalid sound channel %d", soundChannel);
 		return;
 	}
 
-	Audio::SoundHandle handle = _channels[soundChannel - 1].handle;
+	cancelFade(soundChannel);
 
-	if (!isChannelActive(soundChannel))
-			return;
+	int startVol = fadeIn ? 0 :  _channels[soundChannel - 1].volume;
+	int targetVol = fadeIn ? _channels[soundChannel - 1].volume : 0;
 
-	float startVolume = fadeIn ? 0 :  _channels[soundChannel - 1].volume;
-	float targetVolume = fadeIn ? _channels[soundChannel - 1].volume : 0;
-	int lastVolume = 0;
-
-	_mixer->setChannelVolume(handle, startVolume);
+	_channels[soundChannel - 1].fade = new FadeParams(startVol, targetVol, ticks, _vm->getMacTicks(), fadeIn);
+	_mixer->setChannelVolume(_channels[soundChannel - 1].handle, startVol);
+}
 
-	int startTicks = _vm->getMacTicks();
-	int lapsedTicks = 0, lastTicks = 0;
+bool DirectorSound::fadeChannel(uint8 soundChannel) {
+	if (soundChannel == 0 || soundChannel > _channels.size()) {
+		warning("Invalid sound channel %d", soundChannel);
+		return false;
+	} else if (!isChannelActive(soundChannel)) {
+			return false;
+	}
 
-	while (lapsedTicks < ticks) {
-		lapsedTicks = _vm->getMacTicks() - startTicks;
-		if (lapsedTicks == lastTicks)
-			continue;
+	FadeParams *fade = _channels[soundChannel - 1].fade;
+	if (!fade)
+		return false;
 
-		lastTicks = lapsedTicks;
-		if (fadeIn) {
-			lastVolume = MIN(lapsedTicks * (targetVolume / ticks), (float)Audio::Mixer::kMaxChannelVolume);
-		} else {
-			lastVolume = MAX((ticks - lapsedTicks) * (startVolume / ticks), (float)0);
-		}
+	fade->lapsedTicks = _vm->getMacTicks() - fade->startTicks;
+	if (fade->lapsedTicks > fade->totalTicks) {
+		cancelFade(soundChannel);
+		return false;
+	}
 
-		_mixer->setChannelVolume(handle, lastVolume);
+	int fadeVol;
+	if (fade->fadeIn) {
+		fadeVol = MIN(fade->lapsedTicks * ((float)fade->targetVol / fade->totalTicks), (float)Audio::Mixer::kMaxChannelVolume);
+	} else {
+		fadeVol = MAX((fade->totalTicks - fade->lapsedTicks) * ((float)fade->startVol / fade->totalTicks), (float)0);
 	}
 
-	_mixer->setChannelVolume(handle, targetVolume);
+	_mixer->setChannelVolume(_channels[soundChannel - 1].handle, fadeVol);
+	return true;
+}
+
+void DirectorSound::cancelFade(uint8 soundChannel) {
+	// NOTE: It is assumed that soundChannel has already been validated, which is
+	// why this method is private.
+
+	if (_channels[soundChannel - 1].fade) {
+		_mixer->setChannelVolume(_channels[soundChannel - 1].handle, _channels[soundChannel - 1].fade->targetVol);
+
+		delete _channels[soundChannel - 1].fade;
+		_channels[soundChannel - 1].fade = nullptr;
+	}
 }
 
 bool DirectorSound::isChannelActive(uint8 soundChannel) {
@@ -195,6 +215,7 @@ void DirectorSound::stopSound(uint8 soundChannel) {
 		return;
 	}
 
+	cancelFade(soundChannel);
 	_mixer->stopHandle(_channels[soundChannel - 1].handle);
 	_channels[soundChannel - 1].lastPlayingCast = 0;
 	return;
@@ -202,9 +223,12 @@ void DirectorSound::stopSound(uint8 soundChannel) {
 
 void DirectorSound::stopSound() {
 	for (uint i = 0; i < _channels.size(); i++) {
+		cancelFade(i);
+
 		_mixer->stopHandle(_channels[i].handle);
 		_channels[i].lastPlayingCast = 0;
 	}
+
 	_mixer->stopHandle(*_scriptSound);
 	_mixer->stopHandle(*_pcSpeakerHandle);
 }
diff --git a/engines/director/sound.h b/engines/director/sound.h
index e0d76e6245..ea1c4b1a08 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -34,12 +34,25 @@ namespace Audio {
 
 namespace Director {
 
+struct FadeParams {
+	int startVol;
+	int targetVol;
+	int totalTicks;
+	int startTicks;
+	int lapsedTicks;
+	bool fadeIn;
+
+	FadeParams(int sv, int tv, int tt, int st, bool f) :
+		startVol(sv), targetVol(tv), totalTicks(tt), startTicks(st), lapsedTicks(0), fadeIn(f) {}
+};
+
 struct SoundChannel {
 	Audio::SoundHandle handle;
 	int lastPlayingCast;
 	byte volume;
+	FadeParams *fade;
 
-	SoundChannel(): handle(), lastPlayingCast(0), volume(255) {}
+	SoundChannel(): handle(), lastPlayingCast(0), volume(255), fade(nullptr) {}
 };
 
 class DirectorSound {
@@ -61,13 +74,18 @@ public:
 	void playMCI(Audio::AudioStream &stream, uint32 from, uint32 to);
 	void playStream(Audio::AudioStream &stream, uint8 soundChannel);
 	void playCastMember(int castId, uint8 soundChannel, bool allowRepeat = true);
-	void playFade(uint8 soundChannel, bool fadeIn, int ticks);
 	void systemBeep();
 
+	void registerFade(uint8 soundChannel, bool fadeIn, int ticks);
+	bool fadeChannel(uint8 soundChannel);
+
 	bool isChannelActive(uint8 soundChannel);
 	int lastPlayingCast(uint8 soundChannel);
 	void stopSound(uint8 soundChannel);
 	void stopSound();
+
+private:
+	void cancelFade(uint8 soundChannel);
 };
 
 class AudioDecoder {




More information about the Scummvm-git-logs mailing list