aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Snover2016-07-01 12:38:59 -0500
committerColin Snover2016-07-01 12:43:39 -0500
commitb7dcf5f6c1f560d668d3857012e98a91bcf881d4 (patch)
treece039725fa19114b06fdd20e614fd3d3bc4e743b
parente8552cf96c91094bd69d7ca5859008a0f18f7957 (diff)
downloadscummvm-rg350-b7dcf5f6c1f560d668d3857012e98a91bcf881d4.tar.gz
scummvm-rg350-b7dcf5f6c1f560d668d3857012e98a91bcf881d4.tar.bz2
scummvm-rg350-b7dcf5f6c1f560d668d3857012e98a91bcf881d4.zip
SCI32: Use better audio fading algorithm
Using the one from SCI2.1mid makes fades very slow because SDL has a larger audio buffer than SSCI DOS. This new algorithm is based on wall time so will always fade at the correct speed, although the larger buffers will have a coarser granularity so the fades may not be as smooth as in the original engine. If anyone cares, the fade volume could be mixed into individual samples in `readBuffer` instead of applying just once per complete buffer. SSCI did not do this, however, so this implementation should be pretty accurate.
-rw-r--r--engines/sci/sound/audio32.cpp45
-rw-r--r--engines/sci/sound/audio32.h20
2 files changed, 31 insertions, 34 deletions
diff --git a/engines/sci/sound/audio32.cpp b/engines/sci/sound/audio32.cpp
index ced88a3028..4689d13d7d 100644
--- a/engines/sci/sound/audio32.cpp
+++ b/engines/sci/sound/audio32.cpp
@@ -305,7 +305,7 @@ int Audio32::readBuffer(Audio::st_sample_t *buffer, const int numSamples) {
// Channel finished fading and had the
// stopChannelOnFade flag set, so no longer exists
- if (channel.fadeStepsRemaining && processFade(channelIndex)) {
+ if (channel.fadeStartTick && processFade(channelIndex)) {
--channelIndex;
continue;
}
@@ -602,8 +602,7 @@ uint16 Audio32::play(int16 channelIndex, const ResourceId resourceId, const bool
channel.loop = loop;
channel.robot = false;
channel.vmd = false;
- channel.lastFadeTick = 0;
- channel.fadeStepsRemaining = 0;
+ channel.fadeStartTick = 0;
channel.soundNode = soundNode;
channel.volume = volume < 0 || volume > kMaxVolume ? (int)kMaxVolume : volume;
// TODO: SCI3 introduces stereo audio
@@ -927,12 +926,12 @@ bool Audio32::fadeChannel(const int16 channelIndex, const int16 targetVolume, co
return false;
}
- if (steps) {
- channel.fadeVolume = targetVolume;
- channel.fadeSpeed = speed;
- channel.fadeStepsRemaining = steps;
+ if (steps && speed) {
+ channel.fadeStartTick = g_sci->getTickCount();
+ channel.fadeStartVolume = channel.volume;
+ channel.fadeTargetVolume = targetVolume;
+ channel.fadeDuration = speed * steps;
channel.stopChannelOnFade = stopAfterFade;
- channel.lastFadeTick = g_sci->getTickCount();
} else {
setVolume(channelIndex, targetVolume);
}
@@ -944,28 +943,28 @@ bool Audio32::processFade(const int16 channelIndex) {
Common::StackLock lock(_mutex);
AudioChannel &channel = getChannel(channelIndex);
- uint32 now = g_sci->getTickCount();
-
- if (channel.lastFadeTick + channel.fadeSpeed <= now) {
- --channel.fadeStepsRemaining;
-
- if (!channel.fadeStepsRemaining) {
+ if (channel.fadeStartTick) {
+ const uint32 fadeElapsed = g_sci->getTickCount() - channel.fadeStartTick;
+ if (fadeElapsed > channel.fadeDuration) {
+ channel.fadeStartTick = 0;
if (channel.stopChannelOnFade) {
stop(channelIndex);
return true;
} else {
- setVolume(channelIndex, channel.fadeVolume);
- }
- } else {
- int volume = channel.volume - (channel.volume - channel.fadeVolume) / (channel.fadeStepsRemaining + 1);
-
- if (volume == channel.fadeVolume) {
- channel.fadeStepsRemaining = 1;
+ setVolume(channelIndex, channel.fadeTargetVolume);
}
+ return false;
+ }
- setVolume(channelIndex, volume);
- channel.lastFadeTick = now;
+ int volume;
+ if (channel.fadeStartVolume > channel.fadeTargetVolume) {
+ volume = channel.fadeStartVolume - fadeElapsed * (channel.fadeStartVolume - channel.fadeTargetVolume) / channel.fadeDuration;
+ } else {
+ volume = channel.fadeStartVolume + fadeElapsed * (channel.fadeTargetVolume - channel.fadeStartVolume) / channel.fadeDuration;
}
+
+ setVolume(channelIndex, volume);
+ return false;
}
return false;
diff --git a/engines/sci/sound/audio32.h b/engines/sci/sound/audio32.h
index 416b81d865..42211eb890 100644
--- a/engines/sci/sound/audio32.h
+++ b/engines/sci/sound/audio32.h
@@ -90,27 +90,25 @@ struct AudioChannel {
bool loop;
/**
- * The time the last fade iteration occurred.
+ * The time, in ticks, that the channel fade began.
+ * If 0, the channel is not being faded.
*/
- uint32 lastFadeTick;
+ uint32 fadeStartTick;
/**
- * The target volume of the fade.
+ * The start volume of a fade.
*/
- int fadeVolume;
+ int fadeStartVolume;
/**
- * The number of ticks that should elapse between
- * each change of volume.
+ * The total length of the fade, in ticks.
*/
- int fadeSpeed;
+ uint32 fadeDuration;
/**
- * The number of iterations the fade should take to
- * complete. If this value is 0, it indicates that the
- * channel is not fading.
+ * The end volume of a fade.
*/
- int fadeStepsRemaining;
+ uint32 fadeTargetVolume;
/**
* Whether or not the channel should be stopped and