[Scummvm-git-logs] scummvm master -> 30d0950ca288572ee1578c0fbb78f2848ccf0035

OMGPizzaGuy noreply at scummvm.org
Thu Jan 25 00:34:53 UTC 2024


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:
30d0950ca2 ULTIMA8: Rework audio volume and balance calculations.


Commit: 30d0950ca288572ee1578c0fbb78f2848ccf0035
    https://github.com/scummvm/scummvm/commit/30d0950ca288572ee1578c0fbb78f2848ccf0035
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2024-01-24T18:33:42-06:00

Commit Message:
ULTIMA8: Rework audio volume and balance calculations.

Changed paths:
    engines/ultima/ultima8/audio/audio_channel.cpp
    engines/ultima/ultima8/audio/audio_channel.h
    engines/ultima/ultima8/audio/audio_mixer.cpp
    engines/ultima/ultima8/audio/audio_mixer.h
    engines/ultima/ultima8/audio/audio_process.cpp
    engines/ultima/ultima8/audio/audio_process.h


diff --git a/engines/ultima/ultima8/audio/audio_channel.cpp b/engines/ultima/ultima8/audio/audio_channel.cpp
index b7ad2f55b8f..a4a2345a4d3 100644
--- a/engines/ultima/ultima8/audio/audio_channel.cpp
+++ b/engines/ultima/ultima8/audio/audio_channel.cpp
@@ -33,18 +33,18 @@ namespace Ultima8 {
 
 AudioChannel::AudioChannel(Audio::Mixer *mixer, uint32 sampleRate, bool stereo) :
 		_mixer(mixer), _loop(0), _sample(nullptr),
-		_paused(false), _priority(0), _lVol(0), _rVol(0), _pitchShift(0) {
+		_paused(false), _priority(0), _volume(0), _balance(0), _pitchShift(0) {
 }
 
 AudioChannel::~AudioChannel(void) {
 }
 
-void AudioChannel::playSample(AudioSample *sample, int loop, int priority, bool paused, bool isSpeech, uint32 pitchShift, int lvol, int rvol) {
+void AudioChannel::playSample(AudioSample *sample, int loop, int priority, bool paused, bool isSpeech, uint32 pitchShift, byte volume, int8 balance) {
 	_sample = sample;
 	_loop = loop;
 	_priority = priority;
-	_lVol = lvol;
-	_rVol = rvol;
+	_volume = volume;
+	_balance = balance;
 	_paused = paused;
 	_pitchShift = pitchShift;
 
@@ -63,12 +63,8 @@ void AudioChannel::playSample(AudioSample *sample, int loop, int priority, bool
 		(Audio::AudioStream *)audioStream :
 		new Audio::LoopingAudioStream(audioStream, loops);
 
-	// Play it
-	int vol = (_lVol + _rVol) / 2;		 // range is 0 ~ 255
-	int balance = (_rVol - _lVol) / 2; // range is -127 ~ +127
-
 	_mixer->stopHandle(_soundHandle);
-	_mixer->playStream(isSpeech ? Audio::Mixer::kSpeechSoundType : Audio::Mixer::kSFXSoundType, &_soundHandle, stream, -1, vol, balance);
+	_mixer->playStream(isSpeech ? Audio::Mixer::kSpeechSoundType : Audio::Mixer::kSFXSoundType, &_soundHandle, stream, -1, volume, balance);
 	if (_pitchShift != AudioProcess::PITCH_SHIFT_NONE)
 		_mixer->setChannelRate(_soundHandle, stream->getRate() * pitchShift / AudioProcess::PITCH_SHIFT_NONE);
 	if (paused)
diff --git a/engines/ultima/ultima8/audio/audio_channel.h b/engines/ultima/ultima8/audio/audio_channel.h
index a3f5dd65835..e9173e12123 100644
--- a/engines/ultima/ultima8/audio/audio_channel.h
+++ b/engines/ultima/ultima8/audio/audio_channel.h
@@ -38,7 +38,8 @@ private:
 	AudioSample     *_sample;
 
 	// Info for sampling
-	int             _lVol, _rVol;   // 0-256
+	byte            _volume;
+	int8            _balance;
 	uint32          _pitchShift;    // AudioProcess::PITCH_SHIFT_NONE = no shift
 	int             _priority;      // anything.
 	bool            _paused;        // true/false
@@ -50,19 +51,19 @@ public:
 	void stop();
 
 	void playSample(AudioSample *sample, int loop, int priority, bool paused, 
-		bool isSpeech, uint32 pitchShift, int lvol, int rvol);
+		bool isSpeech, uint32 pitchShift, byte volume, int8 balance);
 
 	bool isPlaying();
 
-	void setVolume(int lvol, int rvol) {
-		_lVol = lvol;
-		_rVol = rvol;
-		_mixer->setChannelVolume(_soundHandle, (rvol + lvol) / 2);
-		_mixer->setChannelBalance(_soundHandle, (rvol - lvol) / 2);
+	void setVolume(byte volume, int8 balance) {
+		_volume = volume;
+		_balance = balance;
+		_mixer->setChannelVolume(_soundHandle, volume);
+		_mixer->setChannelBalance(_soundHandle, balance);
 	}
-	void getVolume(int &lvol, int &rvol) const {
-		lvol = _lVol;
-		rvol = _rVol;
+	void getVolume(byte &volume, int8 &balance) const {
+		volume = _volume;
+		balance = _balance;
 	}
 
 	void setPriority(int priority) {
diff --git a/engines/ultima/ultima8/audio/audio_mixer.cpp b/engines/ultima/ultima8/audio/audio_mixer.cpp
index 6fdf994152c..1b217eff723 100644
--- a/engines/ultima/ultima8/audio/audio_mixer.cpp
+++ b/engines/ultima/ultima8/audio/audio_mixer.cpp
@@ -78,7 +78,7 @@ void AudioMixer::reset() {
 	_mixer->stopAll();
 }
 
-int AudioMixer::playSample(AudioSample *sample, int loop, int priority, bool paused, bool isSpeech, uint32 pitch_shift, int lvol, int rvol, bool ambient) {
+int AudioMixer::playSample(AudioSample *sample, int loop, int priority, bool paused, bool isSpeech, uint32 pitch_shift, byte volume, int8 balance, bool ambient) {
 	int lowest = -1;
 	int lowprior = 65536;
 
@@ -97,7 +97,7 @@ int AudioMixer::playSample(AudioSample *sample, int loop, int priority, bool pau
 	}
 
 	if (i != maxchan || lowprior < priority)
-		_channels[lowest]->playSample(sample, loop, priority, paused, isSpeech, pitch_shift, lvol, rvol);
+		_channels[lowest]->playSample(sample, loop, priority, paused, isSpeech, pitch_shift, volume, balance);
 	else
 		lowest = -1;
 
@@ -136,18 +136,18 @@ bool AudioMixer::isPaused(int chan) {
 	return ret;
 }
 
-void AudioMixer::setVolume(int chan, int lvol, int rvol) {
+void AudioMixer::setVolume(int chan, byte volume, int8 balance) {
 	if (chan >= TOTAL_CHANNEL_COUNT || chan < 0)
 		return;
 
-	_channels[chan]->setVolume(lvol, rvol);
+	_channels[chan]->setVolume(volume, balance);
 }
 
-void AudioMixer::getVolume(int chan, int &lvol, int &rvol) {
+void AudioMixer::getVolume(int chan, byte &volume, int8 &balance) {
 	if (chan >= TOTAL_CHANNEL_COUNT || chan < 0)
 		return;
 
-	_channels[chan]->getVolume(lvol, rvol);
+	_channels[chan]->getVolume(volume, balance);
 }
 
 void AudioMixer::openMidiOutput() {
diff --git a/engines/ultima/ultima8/audio/audio_mixer.h b/engines/ultima/ultima8/audio/audio_mixer.h
index 653b55e3a84..835472841a4 100644
--- a/engines/ultima/ultima8/audio/audio_mixer.h
+++ b/engines/ultima/ultima8/audio/audio_mixer.h
@@ -55,15 +55,15 @@ public:
 	void            reset();
 	void            createProcesses();
 
-	int             playSample(AudioSample *sample, int loop, int priority, bool paused, bool isSpeech, uint32 pitch_shift, int lvol, int rvol, bool ambient);
+	int             playSample(AudioSample *sample, int loop, int priority, bool paused, bool isSpeech, uint32 pitch_shift, byte volume, int8 balance, bool ambient);
 	bool            isPlaying(int chan);
 	void            stopSample(int chan);
 
 	void            setPaused(int chan, bool paused);
 	bool            isPaused(int chan);
 
-	void            setVolume(int chan, int lvol, int rvol);
-	void            getVolume(int chan, int &lvol, int &rvol);
+	void            setVolume(int chan, byte volume, int8 balance);
+	void            getVolume(int chan, byte &volume, int8 &balance);
 
 	void            openMidiOutput();
 	void            closeMidiOutput();
diff --git a/engines/ultima/ultima8/audio/audio_process.cpp b/engines/ultima/ultima8/audio/audio_process.cpp
index c6b0686545a..030c48a7b4f 100644
--- a/engines/ultima/ultima8/audio/audio_process.cpp
+++ b/engines/ultima/ultima8/audio/audio_process.cpp
@@ -46,9 +46,13 @@ AudioProcess::~AudioProcess(void) {
 	_theAudioProcess = nullptr;
 }
 
-bool AudioProcess::calculateSoundVolume(ObjId objId, int16 &lVol, int16 &rVol) const {
+bool AudioProcess::calculateSoundVolume(ObjId objId, int16 &volume, int8 &balance) const {
 	Item *item = getItem(objId);
-	if (!item) return false;
+	if (!item) {
+		volume = 255;
+		balance = 0;
+		return false;
+	}
 
 	// Need to get items relative coords from avatar
 
@@ -72,26 +76,11 @@ bool AudioProcess::calculateSoundVolume(ObjId objId, int16 &lVol, int16 &rVol) c
 	int limit = 350 * 350;
 
 	int dist = limit - (x * x + y * y);
-	if (dist < 0) dist = 0;
 	dist = (dist * 256) / limit;
+	volume = CLIP(dist, 0, 255); // range is 0 ~ 255
 
-	int lbal = 160;
-	int rbal = 160;
-
-	if (x < 0) {
-		if (x < -160) rbal = 0;
-		else rbal = x + 160;
-	} else if (x > 0) {
-		if (x > 160) lbal = 0;
-		else lbal = 160 - x;
-	}
-
-	lVol = (dist * lbal) / 160;
-	rVol = (dist * rbal) / 160;
-
-	// Clip to expected range of 0-255
-	lVol = CLIP(lVol, (int16)0, (int16)255);
-	rVol = CLIP(rVol, (int16)0, (int16)255);
+	int b = (x * 127) / 160;
+	balance = CLIP(b, -127, 127); // range is -127 ~ +127
 
 	return true;
 }
@@ -124,11 +113,9 @@ void AudioProcess::run() {
 			it = _sampleInfo.erase(it);
 		else {
 			if (it->_sfxNum != -1 && it->_objId) {
-				it->_lVol = 255;
-				it->_rVol = 255;
-				calculateSoundVolume(it->_objId, it->_lVol, it->_rVol);
+				calculateSoundVolume(it->_objId, it->_calcVol, it->_balance);
 			}
-			mixer->setVolume(it->_channel, (it->_lVol * it->_volume) / 256, (it->_rVol * it->_volume) / 256);
+			mixer->setVolume(it->_channel, (it->_calcVol * it->_volume) / 256, it->_balance);
 
 			++it;
 		}
@@ -199,14 +186,13 @@ bool AudioProcess::loadData(Common::ReadStream *rs, uint32 version) {
 		uint16 volume = rs->readUint16LE();
 
 		if (sfxNum != -1) { // SFX
-			int16 lVol = 0;
-			int16 rVol = 0;
+			int16 calcVol = 0;
+			int8 balance = 0;
 			if (objId != 0) {
-				lVol = 255;
-				rVol = 255;
+				calcVol = 255;
 			}
 			// Note: Small inconsistency for backward compatibility - reload ambient sounds as non-ambient.
-			playSFX(sfxNum, priority, objId, loops, false, pitchShift, volume, lVol, rVol, false);
+			playSFX(sfxNum, priority, objId, loops, false, pitchShift, volume, calcVol, balance, false);
 		} else {                // Speech
 			uint32 slen = rs->readUint32LE();
 
@@ -223,9 +209,9 @@ bool AudioProcess::loadData(Common::ReadStream *rs, uint32 version) {
 	return true;
 }
 
-int AudioProcess::playSample(AudioSample *sample, int priority, int loops, bool isSpeech, uint32 pitchShift, int16 lVol, int16 rVol, bool ambient) {
+int AudioProcess::playSample(AudioSample *sample, int priority, int loops, bool isSpeech, uint32 pitchShift, int16 volume, int8 balance, bool ambient) {
 	AudioMixer *mixer = AudioMixer::get_instance();
-	int channel = mixer->playSample(sample, loops, priority, false, isSpeech, pitchShift, lVol, rVol, ambient);
+	int channel = mixer->playSample(sample, loops, priority, false, isSpeech, pitchShift, volume, balance, ambient);
 
 	if (channel == -1) return channel;
 
@@ -244,7 +230,7 @@ int AudioProcess::playSample(AudioSample *sample, int priority, int loops, bool
 
 void AudioProcess::playSFX(int sfxNum, int priority, ObjId objId, int loops,
 						   bool no_duplicates, uint32 pitchShift, uint16 volume,
-						   int16 lVol, int16 rVol, bool ambient) {
+						   int16 calcVol, int8 balance, bool ambient) {
 
 	SoundFlex *soundflx = GameData::get_instance()->getSoundFlex();
 
@@ -274,17 +260,15 @@ void AudioProcess::playSFX(int sfxNum, int priority, ObjId objId, int loops,
 	AudioSample *sample = soundflx->getSample(sfxNum);
 	if (!sample) return;
 
-	if (lVol == -1 || rVol == -1) {
-		lVol = 255;
-		rVol = 255;
-		if (objId) calculateSoundVolume(objId, lVol, rVol);
+	if (calcVol == -1) {
+		calculateSoundVolume(objId, calcVol, balance);
 	}
 
-	int channel = playSample(sample, priority, loops, false, pitchShift, (lVol * volume) / 256, (rVol * volume) / 256, ambient);
+	int channel = playSample(sample, priority, loops, false, pitchShift, (calcVol * volume) / 256, balance, ambient);
 	if (channel == -1) return;
 
 	// Update list
-	_sampleInfo.push_back(SampleInfo(sfxNum, priority, objId, loops, channel, pitchShift, volume, lVol, rVol, ambient));
+	_sampleInfo.push_back(SampleInfo(sfxNum, priority, objId, loops, channel, pitchShift, volume, calcVol, balance, ambient));
 }
 
 void AudioProcess::stopSFX(int sfxNum, ObjId objId) {
@@ -332,9 +316,8 @@ void AudioProcess::setVolumeSFX(int sfxNum, uint8 volume) {
 		if (it->_sfxNum == sfxNum && it->_sfxNum != -1) {
 			it->_volume = volume;
 
-			int lVol = 256, _rVol = 256;
-			if (it->_objId) calculateSoundVolume(it->_objId, it->_lVol, it->_rVol);
-			mixer->setVolume(it->_channel, (lVol * it->_volume) / 256, (_rVol * it->_volume) / 256);
+			calculateSoundVolume(it->_objId, it->_calcVol, it->_balance);
+			mixer->setVolume(it->_channel, (it->_calcVol * it->_volume) / 256, it->_balance);
 		}
 	}
 }
@@ -347,10 +330,8 @@ void AudioProcess::setVolumeForObjectSFX(ObjId objId, int sfxNum, uint8 volume)
 		if (it->_sfxNum == sfxNum && it->_sfxNum != -1 && objId == it->_objId) {
 			it->_volume = volume;
 
-			int lVol = 256, _rVol = 256;
-			// TODO: does the original recalculate relative volume or just set abosolute?
-			calculateSoundVolume(it->_objId, it->_lVol, it->_rVol);
-			mixer->setVolume(it->_channel, (lVol * it->_volume) / 256, (_rVol * it->_volume) / 256);
+			calculateSoundVolume(it->_objId, it->_calcVol, it->_balance);
+			mixer->setVolume(it->_channel, (it->_calcVol * it->_volume) / 256, it->_balance);
 		}
 	}
 }
@@ -399,7 +380,7 @@ bool AudioProcess::playSpeech(const Std::string &barked, int shapeNum, ObjId obj
 
 	// Update list
 	_sampleInfo.push_back(SampleInfo(barked, shapeNum, objId, channel,
-	                                 speech_start, speech_end, pitchShift, volume, 256, 256, false));
+	                                 speech_start, speech_end, pitchShift, volume, 255, 0, false));
 
 	return true;
 }
diff --git a/engines/ultima/ultima8/audio/audio_process.h b/engines/ultima/ultima8/audio/audio_process.h
index 56c7dc6e7cc..0e2e9cad8de 100644
--- a/engines/ultima/ultima8/audio/audio_process.h
+++ b/engines/ultima/ultima8/audio/audio_process.h
@@ -47,20 +47,20 @@ public:
 		uint32      _curSpeechStart, _curSpeechEnd;
 		uint32      _pitchShift;    // PITCH_SHIFT_NONE is normal
 		uint16      _volume;         // 0-255
-		int16       _lVol;
-		int16       _rVol;
+		int16       _calcVol;
+		int8        _balance;
 		bool		_ambient;
 
 		SampleInfo() : _sfxNum(-1) { }
-		SampleInfo(int32 s, int32 p, ObjId o, int32 l, int32 c, uint32 ps, uint16 v, int16 lv, int16 rv, bool ambient) :
+		SampleInfo(int32 s, int32 p, ObjId o, int32 l, int32 c, uint32 ps, uint16 v, int16 cv, int8 bal, bool ambient) :
 			_sfxNum(s), _priority(p), _objId(o), _loops(l), _channel(c),
-			_pitchShift(ps), _volume(v), _lVol(lv), _rVol(rv),
+			_pitchShift(ps), _volume(v), _calcVol(cv), _balance(bal),
 			_curSpeechStart(0), _curSpeechEnd(0), _ambient(ambient) { }
 		SampleInfo(const Std::string &b, int32 shpnum, ObjId o, int32 c,
-				   uint32 s, uint32 e, uint32 ps, uint16 v, int16 lv, int16 rv, bool ambient) :
+				   uint32 s, uint32 e, uint32 ps, uint16 v, int16 cv, int8 bal, bool ambient) :
 			_sfxNum(-1), _priority(shpnum), _objId(o), _loops(0), _channel(c), _barked(b),
 			_curSpeechStart(s), _curSpeechEnd(e), _pitchShift(ps), _volume(v),
-			_lVol(lv), _rVol(rv), _ambient(ambient) { }
+			_calcVol(cv), _balance(bal), _ambient(ambient) { }
 	};
 
 	Std::list<SampleInfo> _sampleInfo;
@@ -92,13 +92,13 @@ public:
 
 	void playSFX(int sfxNum, int priority, ObjId objId, int loops,
 				 bool no_duplicates, uint32 pitchShift,
-				 uint16 volume, int16 lVol, int16 rVol,
+				 uint16 volume, int16 calcVol, int8 balance,
 				 bool ambient);
 
 	void playSFX(int sfxNum, int priority, ObjId objId, int loops,
 				 bool no_duplicates = false, uint32 pitchShift = PITCH_SHIFT_NONE,
 				 uint16 volume = 0x80, bool ambient = false) {
-		playSFX(sfxNum, priority, objId, loops, no_duplicates, pitchShift, volume, -1, -1, ambient);
+		playSFX(sfxNum, priority, objId, loops, no_duplicates, pitchShift, volume, -1, 0, ambient);
 	}
 
 	//! stop sfx on object.  set sfxNum = -1 to stop all for object.
@@ -119,8 +119,8 @@ public:
 	//! play a sample (without storing a SampleInfo)
 	//! returns channel sample is played on, or -1
 	int playSample(AudioSample *sample, int priority, int loops, bool isSpeech = false,
-				   uint32 pitchShift = PITCH_SHIFT_NONE, int16 lVol = 255,
-				   int16 rVol = 255, bool ambient = false);
+				   uint32 pitchShift = PITCH_SHIFT_NONE, int16 volume = 255,
+				   int8 balance = 0, bool ambient = false);
 
 	//! pause all currently playing samples
 	void pauseAllSamples();
@@ -141,7 +141,7 @@ private:
 	//! returns true if there was speech left to play, or false if finished
 	bool continueSpeech(SampleInfo &si);
 
-	bool calculateSoundVolume(ObjId objId, int16 &lVol, int16 &rVol) const;
+	bool calculateSoundVolume(ObjId objId, int16 &volume, int8 &balance) const;
 
 	static AudioProcess *_theAudioProcess;
 };




More information about the Scummvm-git-logs mailing list