[Scummvm-git-logs] scummvm master -> b31de33545cd03a9143be9470897d5c7930bbc2b

NMIError noreply at scummvm.org
Sun Jul 3 19:26:28 UTC 2022


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:
b31de33545 CHEWY: Fix cutscene volume and panning


Commit: b31de33545cd03a9143be9470897d5c7930bbc2b
    https://github.com/scummvm/scummvm/commit/b31de33545cd03a9143be9470897d5c7930bbc2b
Author: Coen Rampen (crampen at gmail.com)
Date: 2022-07-03T21:26:22+02:00

Commit Message:
CHEWY: Fix cutscene volume and panning

This commit fixes the initial volume and panning for SFX and music in
cutscenes. These were set on the sound handle of the previous SFX or music
track played, which would not affect the new sound.

Changed paths:
    engines/chewy/atds.cpp
    engines/chewy/dialogs/options.cpp
    engines/chewy/r_event.cpp
    engines/chewy/sound.cpp
    engines/chewy/sound.h
    engines/chewy/video/cfo_decoder.cpp
    engines/chewy/video/cfo_decoder.h
    engines/chewy/video/video_player.cpp


diff --git a/engines/chewy/atds.cpp b/engines/chewy/atds.cpp
index 1320832259b..05fe089b02c 100644
--- a/engines/chewy/atds.cpp
+++ b/engines/chewy/atds.cpp
@@ -607,6 +607,13 @@ void Atdsys::print_aad(int16 scrX, int16 scrY) {
 			if (g_engine->_sound->speechEnabled() &&
 					_aadv._strHeader->_vocNr - ATDS_VOC_OFFSET != -1) {
 				if (_atdsv._vocNr != _aadv._strHeader->_vocNr - ATDS_VOC_OFFSET) {
+					// TODO Panning does not work properly during cutscenes.
+					// The x position seems to be fixed, probably that of the
+					// character in the (now invisible) game screen, so all
+					// cutscene voices are panned to the same position. I don't
+					// know if the x position of the character speaking in the
+					// cutscene is available somehow; otherwise panning must be
+					// disabled (fixed center) during cutscenes.
 					_atdsv._vocNr = _aadv._strHeader->_vocNr - ATDS_VOC_OFFSET;
 					const int16 vocx = _G(moveState)[personId].Xypos[0] -
 								 _G(gameState).scrollx + _G(spieler_mi)[personId].HotX;
diff --git a/engines/chewy/dialogs/options.cpp b/engines/chewy/dialogs/options.cpp
index e895f2ff884..e93df89cebb 100644
--- a/engines/chewy/dialogs/options.cpp
+++ b/engines/chewy/dialogs/options.cpp
@@ -100,12 +100,12 @@ void Options::execute(TafInfo *ti) {
 				8 + ti->correction[(SCHNULL_BAND << 1) + 1], 0);
 		}
 
-		const int soundVolume = MAX(1, g_engine->_sound->getSoundVolume() * 32 / Audio::Mixer::kMaxMixerVolume);
+		const int soundVolume = MAX(1, g_engine->_sound->getUserSoundVolume() * 32 / Audio::Mixer::kMaxMixerVolume);
 		_G(out)->pop_box(32 - 2, 104 - 12, 42 + 4, 136 + 2, 192, 183, 182);
 		_G(out)->printxy(32 + 3, 104 - 10, 15, 300, 0, "S");
 		_G(out)->boxFill(33, 136 - soundVolume, 42, 136, 15);
 
-		const int musicVolume = MAX(1, g_engine->_sound->getMusicVolume() * 32 / Audio::Mixer::kMaxMixerVolume);
+		const int musicVolume = MAX(1, g_engine->_sound->getUserMusicVolume() * 32 / Audio::Mixer::kMaxMixerVolume);
 		_G(out)->pop_box(52 - 2, 104 - 12, 62 + 4, 136 + 2, 192, 183, 182);
 		_G(out)->printxy(52 + 3, 104 - 10, 31, 300, 0, "M");
 		_G(out)->boxFill(53, 136 - musicVolume, 62, 136, 31);
@@ -193,11 +193,11 @@ void Options::execute(TafInfo *ti) {
 				key = Common::KEYCODE_ESCAPE;
 				break;
 			case 7: // S volume gauge
-				g_engine->_sound->setSoundVolume(MIN(32, 136 - g_events->_mousePos.y) * Audio::Mixer::kMaxMixerVolume / 32);
+				g_engine->_sound->setUserSoundVolume(MIN(32, 136 - g_events->_mousePos.y) * Audio::Mixer::kMaxMixerVolume / 32);
 				g_engine->syncSoundSettings();
 				break;
 			case 8: // M volume gauge
-				g_engine->_sound->setMusicVolume(MIN(32, 136 - g_events->_mousePos.y) * Audio::Mixer::kMaxMixerVolume / 32);
+				g_engine->_sound->setUserMusicVolume(MIN(32, 136 - g_events->_mousePos.y) * Audio::Mixer::kMaxMixerVolume / 32);
 				g_engine->syncSoundSettings();
 				break;
 
diff --git a/engines/chewy/r_event.cpp b/engines/chewy/r_event.cpp
index 8e29c99277b..c956e1e974e 100644
--- a/engines/chewy/r_event.cpp
+++ b/engines/chewy/r_event.cpp
@@ -754,9 +754,9 @@ void flic_cut(int16 nr) {
 		break;
 
 	case FCUT_112:
-		g_engine->_sound->setMusicVolume(32 * Audio::Mixer::kMaxChannelVolume / 120);
+		g_engine->_sound->setActiveMusicVolume(32);
 		g_engine->_video->playVideo(nr);
-		g_engine->_sound->setMusicVolume(5 * Audio::Mixer::kMaxChannelVolume / 120);
+		g_engine->_sound->setActiveMusicVolume(5);
 		break;
 
 	case FCUT_133:
diff --git a/engines/chewy/sound.cpp b/engines/chewy/sound.cpp
index 1cfa1a2de68..6674b4f40d7 100644
--- a/engines/chewy/sound.cpp
+++ b/engines/chewy/sound.cpp
@@ -66,11 +66,8 @@ void Sound::playSound(uint8 *data, uint32 size, uint channel, bool loop, uint16
 			dispose),
 		loop ? 0 : 1);
 
-	assert(volume >= 0 && volume < 64);
-	assert(balance >= 0 && balance < 128);
-
 	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle[channel], stream, -1,
-		volume * Audio::Mixer::kMaxChannelVolume / 63, MIN(127, (balance - 63) * 2));
+		convertVolume(volume), convertBalance(balance));
 }
 
 void Sound::pauseSound(uint channel) {
@@ -98,37 +95,24 @@ bool Sound::isSoundActive(uint channel) const {
 	return _mixer->isSoundHandleActive(_soundHandle[channel]);
 }
 
-void Sound::setSoundVolume(uint volume) {
+void Sound::setUserSoundVolume(uint volume) {
 	_userSoundVolume = volume;
 	if (soundEnabled())
 		ConfMan.setInt("sfx_volume", volume);
 }
 
-int Sound::getSoundVolume() const {
+int Sound::getUserSoundVolume() const {
 	return _userSoundVolume;
 }
 
-void Sound::pushVolume() {
-	/* _soundVolume = _mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType);
-	_speechVolume = _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType);
-	_musicVolume = _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType);*/
-}
-
-void Sound::popVolume() {
-	/* assert(_soundVolume >= 0 && _speechVolume >= 0 && _musicVolume >= 0);
-	_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, _soundVolume);
-	_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, _speechVolume);
-	_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, _musicVolume);*/
-}
-
 void Sound::setSoundChannelVolume(uint channel, uint volume) {
 	assert(channel < MAX_SOUND_EFFECTS);
-	_mixer->setChannelVolume(_soundHandle[channel], volume);
+	_mixer->setChannelVolume(_soundHandle[channel], convertVolume(volume));
 }
 
 void Sound::setSoundChannelBalance(uint channel, int8 balance) {
 	assert(channel < MAX_SOUND_EFFECTS);
-	_mixer->setChannelBalance(_soundHandle[channel], balance);
+	_mixer->setChannelBalance(_soundHandle[channel], convertBalance(balance));
 }
 
 void Sound::playMusic(int16 num, bool loop) {
@@ -142,11 +126,11 @@ void Sound::playMusic(int16 num, bool loop) {
 	delete[] data;
 }
 
-void Sound::playMusic(uint8 *data, uint32 size) {
+void Sound::playMusic(uint8 *data, uint32 size, uint8 volume) {
 	TMFStream *stream = new TMFStream(new Common::MemoryReadStream(data, size), 0);
 	_curMusic = -1;
 
-	_mixer->playStream(Audio::Mixer::kMusicSoundType, &_musicHandle, stream);
+	_mixer->playStream(Audio::Mixer::kMusicSoundType, &_musicHandle, stream, -1, convertVolume(volume));
 }
 
 void Sound::pauseMusic() {
@@ -166,16 +150,21 @@ bool Sound::isMusicActive() const {
 	return _mixer->isSoundHandleActive(_musicHandle);
 }
 
-void Sound::setMusicVolume(uint volume) {
+void Sound::setUserMusicVolume(uint volume) {
 	_userMusicVolume = volume;
 	if (musicEnabled())
 		ConfMan.setInt("music_volume", volume);
 }
 
-int Sound::getMusicVolume() const {
+int Sound::getUserMusicVolume() const {
 	return _userMusicVolume;
 }
 
+void Sound::setActiveMusicVolume(uint8 volume) {
+	if (isMusicActive())
+		_mixer->setChannelVolume(_musicHandle, convertVolume(volume));
+}
+
 void Sound::playSpeech(int num, bool waitForFinish, uint16 balance) {
 	if (isSpeechActive())
 		stopSpeech();
@@ -194,10 +183,8 @@ void Sound::playSpeech(int num, bool waitForFinish, uint16 balance) {
 		new Common::MemorySeekableReadWriteStream(data, size, DisposeAfterUse::YES),
 		DisposeAfterUse::YES);
 
-	assert(balance >= 0 && balance < 128);
-
 	_mixer->playStream(Audio::Mixer::kSpeechSoundType, &_speechHandle, stream,
-		-1 , 255, MIN(127, (balance - 63) * 2));
+		-1, Audio::Mixer::kMaxChannelVolume, convertBalance(balance));
 
 	if (waitForFinish) {
 		// Wait for speech to finish
@@ -237,7 +224,7 @@ void Sound::waitForSpeechToFinish() {
 
 void Sound::setSpeechBalance(uint16 balance) {
 	if (isSpeechActive()) {
-		_mixer->setChannelBalance(_speechHandle, balance);
+		_mixer->setChannelBalance(_speechHandle, convertBalance(balance));
 	}
 }
 
@@ -346,4 +333,14 @@ void Sound::playRoomMusic(int16 roomNum) {
 	}
 }
 
+uint8 Sound::convertVolume(uint16 volume) {
+	assert(volume >= 0 && volume < 64);
+	return volume * Audio::Mixer::kMaxChannelVolume / 63;
+}
+
+int8 Sound::convertBalance(uint16 balance) {
+	assert(balance >= 0 && balance < 128);
+	return MIN(127, (balance - 63) * 2);
+}
+
 } // namespace Chewy
diff --git a/engines/chewy/sound.h b/engines/chewy/sound.h
index eb3d3021065..921aa61a074 100644
--- a/engines/chewy/sound.h
+++ b/engines/chewy/sound.h
@@ -50,21 +50,26 @@ public:
 	void stopSound(uint channel = 0);
 	void stopAllSounds();
 	bool isSoundActive(uint channel) const;
-	void setSoundVolume(uint volume);
-	int getSoundVolume() const;
+	void setUserSoundVolume(uint volume);
+	int getUserSoundVolume() const;
+	// Sets the volume of the sound effect curently active on the specified
+	// channel. Does not affect the next sound effect played on the channel.
 	void setSoundChannelVolume(uint channel, uint volume);
+	// Sets the balance of the sound effect curently active on the specified
+	// channel. Does not affect the next sound effect played on the channel.
 	void setSoundChannelBalance(uint channel, int8 balance);
-	void pushVolume();
-	void popVolume();
 
 	void playMusic(int16 num, bool loop = false);
-	void playMusic(uint8 *data, uint32 size);
+	void playMusic(uint8 *data, uint32 size, uint8 volume = 63);
 	void pauseMusic();
 	void resumeMusic();
 	void stopMusic();
 	bool isMusicActive() const;
-	void setMusicVolume(uint volume);
-	int getMusicVolume() const;
+	void setUserMusicVolume(uint volume);
+	int getUserMusicVolume() const;
+	// Sets the volume of the currently active music track. Does not affect the
+	// next music track played.
+	void setActiveMusicVolume(uint8 volume);
 	void playRoomMusic(int16 roomNum);
 
 	void playSpeech(int num, bool waitForFinish, uint16 balance = 63);
@@ -72,6 +77,8 @@ public:
 	void resumeSpeech();
 	void stopSpeech();
 	bool isSpeechActive() const;
+	// Sets the balance of the currently playing speech sample. Does not affect
+	// the next speech sample played.
 	void setSpeechBalance(uint16 balance = 63);
 
 	void stopAll();
@@ -96,6 +103,13 @@ public:
 	void syncSoundSettings();
 
 private:
+	// Converts volume from the scale used by the game data (0 - 63) to the
+	// ScummVM mixer channel scale (0 - 255).
+	uint8 convertVolume(uint16 volume);
+	// Converts balance from the scale used by the game data (0 - 127) to the
+	// ScummVM mixer channel scale (-127 - 127).
+	int8 convertBalance(uint16 balance);
+
 	Audio::Mixer *_mixer;
 	Audio::SoundHandle _soundHandle[MAX_SOUND_EFFECTS];
 	Audio::SoundHandle _musicHandle;
diff --git a/engines/chewy/video/cfo_decoder.cpp b/engines/chewy/video/cfo_decoder.cpp
index dc9c4de53a6..6db9dbc31e7 100644
--- a/engines/chewy/video/cfo_decoder.cpp
+++ b/engines/chewy/video/cfo_decoder.cpp
@@ -83,6 +83,10 @@ CfoDecoder::CfoVideoTrack::CfoVideoTrack(Common::SeekableReadStream *stream, uin
 
 	_musicData = nullptr;
 	_musicSize = 0;
+
+	Common::fill(_sfxBalances, _sfxBalances + ARRAYSIZE(_sfxBalances), 63);
+	_sfxGlobalVolume = 63;
+	_musicVolume = 63;
 }
 
 CfoDecoder::CfoVideoTrack::~CfoVideoTrack() {
@@ -219,7 +223,7 @@ void CfoDecoder::CfoVideoTrack::handleCustomFrame() {
 			break;
 		case kChunkPlayMusic:
 			// Used in videos 0, 18, 34, 71
-			_sound->playMusic(_musicData, _musicSize);
+			_sound->playMusic(_musicData, _musicSize, _musicVolume);
 			break;
 		case kChunkPlaySeq:
 			error("Unused chunk kChunkPlaySeq found");
@@ -246,8 +250,10 @@ void CfoDecoder::CfoVideoTrack::handleCustomFrame() {
 			} while (_sound->isMusicActive() && musicLoops < 100);
 			break;
 		case kChunkSetMusicVolume:
-			volume = _fileStream->readUint16LE() * Audio::Mixer::kMaxChannelVolume / 63;
-			_sound->setMusicVolume(volume);
+			volume = _fileStream->readUint16LE();
+
+			_musicVolume = volume;
+			_sound->setActiveMusicVolume(volume);
 			break;
 		case kChunkSetLoopMode:
 			error("Unused chunk kChunkSetLoopMode found");
@@ -262,18 +268,21 @@ void CfoDecoder::CfoVideoTrack::handleCustomFrame() {
 			repeat = _fileStream->readUint16LE();
 			assert(number < MAX_SOUND_EFFECTS);
 
-			//_sound->setSoundVolume(volume);
-			_sound->playSound(_soundEffects[number], _soundEffectSize[number], channel, repeat, volume, 63, DisposeAfterUse::NO);
+			_sound->playSound(_soundEffects[number], _soundEffectSize[number], channel, repeat,
+				volume * _sfxGlobalVolume / 63, _sfxBalances[channel], DisposeAfterUse::NO);
 			break;
 		case kChunkSetSoundVolume:
-			volume = _fileStream->readUint16LE() * Audio::Mixer::kMaxChannelVolume / 63;
-			_sound->setSoundVolume(volume);
+			volume = _fileStream->readUint16LE();
+			assert(volume >= 0 && volume < 64);
+			_sfxGlobalVolume = volume;
+			// This is only used once in the credits video, before any sounds
+			// are played, so no need to update volume of active sounds.
 			break;
 		case kChunkSetChannelVolume:
 			channel = _fileStream->readUint16LE();
-			volume = _fileStream->readUint16LE() * Audio::Mixer::kMaxChannelVolume / 63;
+			volume = _fileStream->readUint16LE();
 
-			_sound->setSoundChannelVolume(channel, volume);
+			_sound->setSoundChannelVolume(channel, volume * _sfxGlobalVolume / 63);
 			break;
 		case kChunkFreeSoundEffect:
 			number = _fileStream->readUint16LE();
@@ -293,7 +302,9 @@ void CfoDecoder::CfoVideoTrack::handleCustomFrame() {
 			break;
 		case kChunkSetBalance:
 			channel = _fileStream->readUint16LE();
-			balance = (_fileStream->readUint16LE() * 2) - 127;
+			balance = _fileStream->readUint16LE();
+
+			_sfxBalances[channel] = balance;
 			_sound->setSoundChannelBalance(channel, balance);
 			break;
 		case kChunkSetSpeed:
diff --git a/engines/chewy/video/cfo_decoder.h b/engines/chewy/video/cfo_decoder.h
index c087cd125e9..41c7864bf4d 100644
--- a/engines/chewy/video/cfo_decoder.h
+++ b/engines/chewy/video/cfo_decoder.h
@@ -62,6 +62,10 @@ private:
 		uint32 _soundEffectSize[MAX_SOUND_EFFECTS];
 		uint8 *_musicData;
 		uint32 _musicSize;
+
+		uint8 _sfxBalances[MAX_SOUND_EFFECTS];
+		uint8 _sfxGlobalVolume;
+		uint8 _musicVolume;
 	};
 };
 
diff --git a/engines/chewy/video/video_player.cpp b/engines/chewy/video/video_player.cpp
index 57b947e2a87..380da53f660 100644
--- a/engines/chewy/video/video_player.cpp
+++ b/engines/chewy/video/video_player.cpp
@@ -36,7 +36,6 @@ bool VideoPlayer::playVideo(uint num, bool stopMusic) {
 	CfoDecoder *cfoDecoder = new CfoDecoder(g_engine->_sound);
 	VideoResource *videoResource = new VideoResource("cut.tap");
 	Common::SeekableReadStream *videoStream = videoResource->getVideoStream(num);
-	g_engine->_sound->pushVolume();
 	_playCount = 0;
 
 	if (stopMusic) {
@@ -102,7 +101,6 @@ bool VideoPlayer::playVideo(uint num, bool stopMusic) {
 
 	g_system->getPaletteManager()->setPalette(curPalette, 0, 256);
 	_G(cur)->showCursor();
-	g_engine->_sound->popVolume();
 
 	delete videoResource;
 	delete cfoDecoder;




More information about the Scummvm-git-logs mailing list