From 64313cd7f10267c29d7e3b963c7bd0ff2e1c7f1a Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Wed, 1 Sep 2010 19:20:17 +0000 Subject: SCI: set master volume correctly and merge it together with global volume, fixes bug #3053104) svn-id: r52484 --- engines/sci/sci.cpp | 3 ++- engines/sci/sound/midiparser_sci.cpp | 28 +++++++++++++++++++++++++--- engines/sci/sound/midiparser_sci.h | 4 +++- engines/sci/sound/music.cpp | 8 ++++++-- engines/sci/sound/music.h | 2 ++ engines/sci/sound/soundcmd.cpp | 5 +++-- engines/sci/sound/soundcmd.h | 4 ---- 7 files changed, 41 insertions(+), 13 deletions(-) (limited to 'engines') diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index 57f9b41140..4b5888a245 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -45,6 +45,7 @@ #include "sci/engine/selector.h" // for SELECTOR #include "sci/sound/audio.h" +#include "sci/sound/music.h" #include "sci/sound/soundcmd.h" #include "sci/graphics/animate.h" #include "sci/graphics/cache.h" @@ -678,7 +679,7 @@ void SciEngine::syncSoundSettings() { int soundVolumeMusic = (mute ? 0 : ConfMan.getInt("music_volume")); if (_gamestate && g_sci->_soundCmd) { - int vol = (soundVolumeMusic + 1) * SoundCommandParser::kMaxSciVolume / Audio::Mixer::kMaxMixerVolume; + int vol = (soundVolumeMusic + 1) * MUSIC_MASTERVOLUME_MAX / Audio::Mixer::kMaxMixerVolume; g_sci->_soundCmd->setMasterVolume(vol); } } diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp index 598b394887..d53f919f8f 100644 --- a/engines/sci/sound/midiparser_sci.cpp +++ b/engines/sci/sound/midiparser_sci.cpp @@ -53,6 +53,7 @@ MidiParser_SCI::MidiParser_SCI(SciVersion soundVersion, SciMusic *music) : _ppqn = 1; setTempo(16667); + _masterVolume = 15; _volume = 127; _signalSet = false; @@ -418,7 +419,7 @@ void MidiParser_SCI::sendToDriver(uint32 midi) { int channelVolume = (midi >> 16) & 0xFF; // Remember, if we need to set it ourselves _channelVolume[midiChannel] = channelVolume; - // Adjust volume accordingly to current "global" volume + // Adjust volume accordingly to current local volume channelVolume = channelVolume * _volume / 127; midi = (midi & 0xFFF0) | ((channelVolume & 0xFF) << 16); } @@ -659,6 +660,28 @@ void MidiParser_SCI::allNotesOff() { memset(_active_notes, 0, sizeof(_active_notes)); } +void MidiParser_SCI::setMasterVolume(byte masterVolume) { + assert(masterVolume <= MUSIC_MASTERVOLUME_MAX); + _masterVolume = masterVolume; + switch (_soundVersion) { + case SCI_VERSION_0_EARLY: + case SCI_VERSION_0_LATE: + // update driver master volume + setVolume(_volume); + break; + + case SCI_VERSION_1_EARLY: + case SCI_VERSION_1_LATE: + case SCI_VERSION_2_1: + // directly set master volume (global volume is merged with channel volumes) + ((MidiPlayer *)_driver)->setVolume(masterVolume); + break; + + default: + error("MidiParser_SCI::setVolume: Unsupported soundVersion"); + } +} + void MidiParser_SCI::setVolume(byte volume) { assert(volume <= MUSIC_VOLUME_MAX); _volume = volume; @@ -667,8 +690,7 @@ void MidiParser_SCI::setVolume(byte volume) { case SCI_VERSION_0_EARLY: case SCI_VERSION_0_LATE: { // SCI0 adlib driver doesn't support channel volumes, so we need to go this way - // TODO: this should take the actual master volume into account - int16 globalVolume = _volume * 15 / 127; + int16 globalVolume = _volume * _masterVolume / MUSIC_VOLUME_MAX; ((MidiPlayer *)_driver)->setVolume(globalVolume); break; } diff --git a/engines/sci/sound/midiparser_sci.h b/engines/sci/sound/midiparser_sci.h index 90db06e539..9d0cb15e74 100644 --- a/engines/sci/sound/midiparser_sci.h +++ b/engines/sci/sound/midiparser_sci.h @@ -65,6 +65,7 @@ public: } void sendInitCommands(); void unloadMusic(); + void setMasterVolume(byte masterVolume); void setVolume(byte volume); void stop() { _abort_parse = true; @@ -104,7 +105,8 @@ protected: SoundResource::Track *_track; MusicEntry *_pSnd; uint32 _loopTick; - byte _volume; + byte _masterVolume; // the overall master volume (same for all tracks) + byte _volume; // the global volume of the current track bool _signalSet; int16 _signalToSet; diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp index aac25399b9..74dca191a8 100644 --- a/engines/sci/sound/music.cpp +++ b/engines/sci/sound/music.cpp @@ -261,6 +261,7 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) { pSnd->pMidiParser = new MidiParser_SCI(_soundVersion, this); pSnd->pMidiParser->setMidiDriver(_pMidiDrv); pSnd->pMidiParser->setTimerRate(_dwTempo); + pSnd->pMidiParser->setMasterVolume(_masterVolume); } pSnd->pauseCounter = 0; @@ -526,8 +527,11 @@ void SciMusic::soundSetMasterVolume(uint16 vol) { Common::StackLock lock(_mutex); - if (_pMidiDrv) - _pMidiDrv->setVolume(vol); + const MusicList::iterator end = _playList.end(); + for (MusicList::iterator i = _playList.begin(); i != end; ++i) { + if ((*i)->pMidiParser) + (*i)->pMidiParser->setMasterVolume(vol); + } } void SciMusic::sendMidiCommand(uint32 cmd) { diff --git a/engines/sci/sound/music.h b/engines/sci/sound/music.h index 7f02dc1513..dfef49e3bf 100644 --- a/engines/sci/sound/music.h +++ b/engines/sci/sound/music.h @@ -47,6 +47,8 @@ enum SoundStatus { #define MUSIC_VOLUME_DEFAULT 127 #define MUSIC_VOLUME_MAX 127 +#define MUSIC_MASTERVOLUME_DEFAULT 15 +#define MUSIC_MASTERVOLUME_MAX 15 class MidiParser_SCI; class SegManager; diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp index d613f0ecdc..c85d4c90a6 100644 --- a/engines/sci/sound/soundcmd.cpp +++ b/engines/sci/sound/soundcmd.cpp @@ -284,8 +284,8 @@ reg_t SoundCommandParser::kDoSoundMasterVolume(int argc, reg_t *argv, reg_t acc) if (argc > 0) { debugC(2, kDebugLevelSound, "kDoSound(masterVolume): %d", argv[0].toSint16()); - int vol = CLIP(argv[0].toSint16(), 0, kMaxSciVolume); - vol = vol * Audio::Mixer::kMaxMixerVolume / kMaxSciVolume; + int vol = CLIP(argv[0].toSint16(), 0, MUSIC_MASTERVOLUME_MAX); + vol = vol * Audio::Mixer::kMaxMixerVolume / MUSIC_MASTERVOLUME_MAX; ConfMan.setInt("music_volume", vol); ConfMan.setInt("sfx_volume", vol); g_engine->syncSoundSettings(); @@ -688,6 +688,7 @@ void SoundCommandParser::startNewSound(int number) { } void SoundCommandParser::setMasterVolume(int vol) { + // 0...15 _music->soundSetMasterVolume(vol); } diff --git a/engines/sci/sound/soundcmd.h b/engines/sci/sound/soundcmd.h index 8e6fb81762..4f006c20d8 100644 --- a/engines/sci/sound/soundcmd.h +++ b/engines/sci/sound/soundcmd.h @@ -47,10 +47,6 @@ public: SoundCommandParser(ResourceManager *resMan, SegManager *segMan, Kernel *kernel, AudioPlayer *audio, SciVersion soundVersion); ~SoundCommandParser(); - enum { - kMaxSciVolume = 15 - }; - //reg_t parseCommand(int argc, reg_t *argv, reg_t acc); // Functions used for game state loading -- cgit v1.2.3