[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