From 5962b0bbe27b8d32dbbad1e8c3d36906dc391dd2 Mon Sep 17 00:00:00 2001 From: Florian Kagerer Date: Tue, 3 Aug 2010 14:58:01 +0000 Subject: KYRA/TOWNS: implement music/sfx volume control via GUI/GMM svn-id: r51695 --- sound/softsynth/fmtowns_pc98/towns_audio.cpp | 25 +++++++++++++++++++++- sound/softsynth/fmtowns_pc98/towns_audio.h | 10 +++++++++ sound/softsynth/fmtowns_pc98/towns_euphony.cpp | 21 +++++++++++++++++- sound/softsynth/fmtowns_pc98/towns_euphony.h | 5 ++++- .../softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp | 8 +++---- 5 files changed, 62 insertions(+), 7 deletions(-) (limited to 'sound/softsynth') diff --git a/sound/softsynth/fmtowns_pc98/towns_audio.cpp b/sound/softsynth/fmtowns_pc98/towns_audio.cpp index 3d3427fcfb..683f574f65 100644 --- a/sound/softsynth/fmtowns_pc98/towns_audio.cpp +++ b/sound/softsynth/fmtowns_pc98/towns_audio.cpp @@ -101,7 +101,8 @@ private: TownsAudioInterface::TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver) : TownsPC98_FmSynth(mixer, kTypeTowns), _fmInstruments(0), _pcmInstruments(0), _pcmChan(0), _waveTables(0), _waveTablesTotalDataSize(0), - _baserate(55125.0f / (float)mixer->getOutputRate()), _tickLength(0), _timer(0), _drv(driver), _ready(false) { + _baserate(55125.0f / (float)mixer->getOutputRate()), _tickLength(0), _timer(0), _drv(driver), + _musicVolume(256), _sfxVolume(256), _pcmSfxChanMask(0), _ready(false) { #define INTCB(x) &TownsAudioInterface::intf_##x static const TownsAudioIntfCallback intfCb[] = { @@ -247,6 +248,8 @@ bool TownsAudioInterface::init() { _timer = 0; + setVolumeChannelMasks(-1, 0); + callback(0); _ready = true; @@ -269,6 +272,22 @@ int TownsAudioInterface::callback(int command, ...) { return res; } +void TownsAudioInterface::setMusicVolume(int volume) { + _musicVolume = CLIP(volume, 0, Audio::Mixer::kMaxMixerVolume); + setVolumeIntern(_musicVolume, _sfxVolume); +} + +void TownsAudioInterface::setSoundEffectVolume(int volume) { + _sfxVolume = CLIP(volume, 0, Audio::Mixer::kMaxMixerVolume); + setVolumeIntern(_musicVolume, _sfxVolume); +} + +void TownsAudioInterface::setSoundEffectChanMask(uint32 mask) { + _pcmSfxChanMask = mask >> 6; + mask &= 0x3f; + setVolumeChannelMasks(~mask, mask); +} + void TownsAudioInterface::nextTickEx(int32 *buffer, uint32 bufferSize) { if (!_ready) return; @@ -302,6 +321,10 @@ void TownsAudioInterface::nextTickEx(int32 *buffer, uint32 bufferSize) { for (int ii = 0; ii < 8; ii++) { if (_pcmChanOut & _chanFlags[ii]) { int32 o = _pcmChan[ii].data[_pcmChan[ii].pos >> 11] * _pcmChan[ii].velo; + if ((1 << ii) & (~_pcmSfxChanMask)) + o = (o * _musicVolume) / Audio::Mixer::kMaxMixerVolume; + if ((1 << ii) & _pcmSfxChanMask) + o = (o * _sfxVolume) / Audio::Mixer::kMaxMixerVolume; if (_pcmChan[ii].panLeft) finOutL += ((o * _pcmChan[ii].panLeft) >> 3); if (_pcmChan[ii].panRight) diff --git a/sound/softsynth/fmtowns_pc98/towns_audio.h b/sound/softsynth/fmtowns_pc98/towns_audio.h index 93a9198fe4..707c9e6bd4 100644 --- a/sound/softsynth/fmtowns_pc98/towns_audio.h +++ b/sound/softsynth/fmtowns_pc98/towns_audio.h @@ -46,6 +46,12 @@ public: int callback(int command, ...); + void setMusicVolume(int volume); + void setSoundEffectVolume(int volume); + // Defines the channels used as sound effect channels for the purpose of ScummVM GUI volume control. + // The first 6 bits are the 6 fm channels. The next 8 bits are pcm channels. + void setSoundEffectChanMask(uint32 mask); + private: void nextTickEx(int32 *buffer, uint32 bufferSize); @@ -148,6 +154,10 @@ private: uint32 _tickLength; uint32 _timer; + uint16 _musicVolume; + uint16 _sfxVolume; + uint32 _pcmSfxChanMask; + TownsAudioInterfacePluginDriver *_drv; bool _ready; diff --git a/sound/softsynth/fmtowns_pc98/towns_euphony.cpp b/sound/softsynth/fmtowns_pc98/towns_euphony.cpp index 4fe645e2fc..13120df17a 100644 --- a/sound/softsynth/fmtowns_pc98/towns_euphony.cpp +++ b/sound/softsynth/fmtowns_pc98/towns_euphony.cpp @@ -130,8 +130,19 @@ void TownsEuphonyDriver::unloadWaveTable(int id) { _intf->callback(35, id); } -void TownsEuphonyDriver::reserveSfxChannels(int num) { +void TownsEuphonyDriver::reserveSoundEffectChannels(int num) { _intf->callback(33, num); + uint32 volMask = 0; + + if (num > 8) + return; + + for (uint32 v = 1 << 13; num; num--) { + volMask |= v; + v >>= 1; + } + + _intf->setSoundEffectChanMask(volMask); } int TownsEuphonyDriver::setMusicTempo(int tempo) { @@ -289,6 +300,14 @@ void TownsEuphonyDriver::timerCallback(int timerId) { } } +void TownsEuphonyDriver::setMusicVolume(int volume) { + _intf->setMusicVolume(volume); +} + +void TownsEuphonyDriver::setSoundEffectVolume(int volume) { + _intf->setSoundEffectVolume(volume); +} + void TownsEuphonyDriver::resetTables() { memset(_tEnable, 0xff, 32); memset(_tMode, 0xff, 16); diff --git a/sound/softsynth/fmtowns_pc98/towns_euphony.h b/sound/softsynth/fmtowns_pc98/towns_euphony.h index c869b612a3..47cfdcb2b9 100644 --- a/sound/softsynth/fmtowns_pc98/towns_euphony.h +++ b/sound/softsynth/fmtowns_pc98/towns_euphony.h @@ -39,7 +39,7 @@ public: void loadInstrument(int chanType, int id, const uint8 *data); void loadWaveTable(const uint8 *data); void unloadWaveTable(int id); - void reserveSfxChannels(int num); + void reserveSoundEffectChannels(int num); int setMusicTempo(int tempo); int startMusicTrack(const uint8 *data, int trackSize, int startTick); @@ -66,6 +66,9 @@ public: void timerCallback(int timerId); + void setMusicVolume(int volume); + void setSoundEffectVolume(int volume); + TownsAudioInterface *intf() { return _intf; } diff --git a/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp b/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp index 7a91cb81b9..507c8e159a 100644 --- a/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp +++ b/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp @@ -1157,12 +1157,12 @@ uint8 TownsPC98_FmSynth::readSSGStatus() { void TownsPC98_FmSynth::setVolumeIntern(int volA, int volB) { Common::StackLock lock(_mutex); - _volumeA = volA; - _volumeB = volB; + _volumeA = CLIP(volA, 0, Audio::Mixer::kMaxMixerVolume); + _volumeB = CLIP(volB, 0, Audio::Mixer::kMaxMixerVolume); if (_ssg) - _ssg->setVolumeIntern(volA, volB); + _ssg->setVolumeIntern(_volumeA, _volumeB); if (_prc) - _prc->setVolumeIntern(volA, volB); + _prc->setVolumeIntern(_volumeA, _volumeB); } void TownsPC98_FmSynth::setVolumeChannelMasks(int channelMaskA, int channelMaskB) { -- cgit v1.2.3