diff options
author | Colin Snover | 2016-07-01 12:38:59 -0500 |
---|---|---|
committer | Colin Snover | 2016-07-01 12:43:39 -0500 |
commit | b7dcf5f6c1f560d668d3857012e98a91bcf881d4 (patch) | |
tree | ce039725fa19114b06fdd20e614fd3d3bc4e743b | |
parent | e8552cf96c91094bd69d7ca5859008a0f18f7957 (diff) | |
download | scummvm-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.cpp | 45 | ||||
-rw-r--r-- | engines/sci/sound/audio32.h | 20 |
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 |