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  | 
