From e31da911c98824b746d8804a63df9695216bc08e Mon Sep 17 00:00:00 2001 From: Walter van Niftrik Date: Fri, 29 May 2015 00:26:46 -0400 Subject: [PATCH] GOB: Implement custom AdLib volume control --- engines/gob/gob.cpp | 3 +++ engines/gob/sound/adlib.cpp | 50 +++++++++++++++++++++++++++++++++++-- engines/gob/sound/adlib.h | 5 ++++ engines/gob/sound/sound.cpp | 10 ++++++++ engines/gob/sound/sound.h | 1 + 5 files changed, 67 insertions(+), 2 deletions(-) diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index 5ab3271a8ff..24bdb858d88 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -389,6 +389,9 @@ void GobEngine::syncSoundSettings() { Engine::syncSoundSettings(); _init->updateConfig(); + + if (_sound) + _sound->adlibSyncVolume(); } void GobEngine::pauseGame() { diff --git a/engines/gob/sound/adlib.cpp b/engines/gob/sound/adlib.cpp index 20fbced63c3..866eecf8bd1 100644 --- a/engines/gob/sound/adlib.cpp +++ b/engines/gob/sound/adlib.cpp @@ -37,6 +37,28 @@ static const int kPitchTomToSnare = 7; static const int kPitchSnareDrum = kPitchTom + kPitchTomToSnare; +// Attenuation map for GUI volume slider +// Note: no volume control in the original engine +const uint8 AdLib::kVolumeTable[Audio::Mixer::kMaxMixerVolume + 1] = { + 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 62, 61, 59, 57, 56, 55, + 53, 52, 51, 50, 49, 48, 47, 46, 46, 45, 44, 43, 43, 42, 41, 41, + 40, 39, 39, 38, 38, 37, 37, 36, 36, 35, 35, 34, 34, 33, 33, 33, + 32, 32, 31, 31, 31, 30, 30, 30, 29, 29, 29, 28, 28, 28, 27, 27, + 27, 26, 26, 26, 26, 25, 25, 25, 24, 24, 24, 24, 23, 23, 23, 23, + 22, 22, 22, 22, 21, 21, 21, 21, 21, 20, 20, 20, 20, 19, 19, 19, + 19, 19, 18, 18, 18, 18, 18, 18, 17, 17, 17, 17, 17, 16, 16, 16, + 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 13, + 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, + 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, + 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0 +}; + // Is the operator a modulator (0) or a carrier (1)? const uint8 AdLib::kOperatorType[kOperatorCount] = { 0, 0, 0, 1, 1, 1, @@ -94,7 +116,7 @@ const uint16 AdLib::kHihatParams [kParamCount] = { AdLib::AdLib(Audio::Mixer &mixer, int callbackFreq) : _mixer(&mixer), _opl(0), - _toPoll(0), _repCount(0), _first(true), _playing(false), _ended(true) { + _toPoll(0), _repCount(0), _first(true), _playing(false), _ended(true), _volume(0) { _rate = _mixer->getOutputRate(); @@ -103,8 +125,10 @@ AdLib::AdLib(Audio::Mixer &mixer, int callbackFreq) : _mixer(&mixer), _opl(0), createOPL(); initOPL(); + syncVolume(); + _opl->start(new Common::Functor0Mem(this, &AdLib::onTimer), callbackFreq); - _mixer->playStream(Audio::Mixer::kMusicSoundType, &_handle, + _mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); } @@ -433,6 +457,13 @@ void AdLib::writeKeyScaleLevelVolume(uint8 oper) { volume = (63 - (_operatorParams[oper][kParamLevel] & 0x3F)) * _operatorVolume[oper]; volume = 63 - ((2 * volume + kMaxVolume) / (2 * kMaxVolume)); + // Adjust carriers for GUI volume slider + if (kOperatorType[oper] == 1) { + volume += kVolumeTable[_volume]; + if (volume > 63) + volume = 63; + } + uint8 keyScale = _operatorParams[oper][kParamKeyScaleLevel] << 6; writeOPL(0x40 + kOperatorOffset[oper], volume | keyScale); @@ -634,4 +665,19 @@ void AdLib::setTimerFrequency(int timerFrequency) { _opl->setCallbackFrequency(timerFrequency); } +void AdLib::syncVolume() { + Common::StackLock slock(_mutex); + + bool mute = false; + if (ConfMan.hasKey("mute")) + mute = ConfMan.getBool("mute"); + + _volume = (mute ? 0 : ConfMan.getInt("music_volume")); + + if (_playing) { + for(int i = 0; i < kOperatorCount; i++) + writeKeyScaleLevelVolume(i); + } +} + } // End of namespace Gob diff --git a/engines/gob/sound/adlib.h b/engines/gob/sound/adlib.h index 6a6215298a1..2c83b15f5b4 100644 --- a/engines/gob/sound/adlib.h +++ b/engines/gob/sound/adlib.h @@ -53,6 +53,7 @@ public: void startPlay(); void stopPlay(); + void syncVolume(); // AudioStream API int readBuffer(int16 *buffer, const int numSamples); @@ -211,6 +212,8 @@ protected: void setTimerFrequency(int timerFrequency); private: + static const uint8 kVolumeTable[Audio::Mixer::kMaxMixerVolume + 1]; + static const uint8 kOperatorType [kOperatorCount]; static const uint8 kOperatorOffset[kOperatorCount]; static const uint8 kOperatorVoice [kOperatorCount]; @@ -235,6 +238,8 @@ private: Common::Mutex _mutex; + int _volume; + uint32 _rate; uint32 _toPoll; diff --git a/engines/gob/sound/sound.cpp b/engines/gob/sound/sound.cpp index d2b2d3d6e89..9b19b9c52c6 100644 --- a/engines/gob/sound/sound.cpp +++ b/engines/gob/sound/sound.cpp @@ -425,6 +425,16 @@ int32 Sound::adlibGetRepeating() const { return false; } +void Sound::adlibSyncVolume() { + if (!_hasAdLib) + return; + + if (_adlPlayer) + _adlPlayer->syncVolume(); + if (_mdyPlayer) + _mdyPlayer->syncVolume(); +} + void Sound::adlibSetRepeating(int32 repCount) { if (!_hasAdLib) return; diff --git a/engines/gob/sound/sound.h b/engines/gob/sound/sound.h index c9599597552..6ebc323b189 100644 --- a/engines/gob/sound/sound.h +++ b/engines/gob/sound/sound.h @@ -96,6 +96,7 @@ public: int32 adlibGetRepeating() const; void adlibSetRepeating(int32 repCount); + void adlibSyncVolume(); // Infogrames