DIRECTOR: Fix setting "the volume of sound"

Previously, volume changes would only be picked up by the next sound
started in the channel (if at all).

Fixes the hint music clashing in the fortune teller floor of the
department store and Club Exclaim in The Seven Colors.
This commit is contained in:
Scott Percival 2024-03-21 01:49:27 +08:00 committed by Eugene Sandulenko
parent 95ca062e6d
commit 637caad1c3
4 changed files with 22 additions and 33 deletions

View File

@ -828,7 +828,7 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
break;
case kTheSoundLevel:
// getting sound level of channel 1, maybe need to be amended in higher version
d = _vm->getCurrentWindow()->getSoundManager()->getSoundLevel(1);
d = _vm->getCurrentWindow()->getSoundManager()->getChannelVolume(1) / 32;
break;
case kTheSprite:
d = getTheSprite(id, field);
@ -1136,10 +1136,7 @@ void Lingo::setTheEntity(int entity, Datum &id, int field, Datum &d) {
switch (field) {
case kTheVolume:
{
SoundChannel *chan = _vm->getCurrentWindow()->getSoundManager()->getChannel(id.asInt());
if (chan) {
chan->volume = (byte)d.asInt();
}
_vm->getCurrentWindow()->getSoundManager()->setChannelVolume(id.asInt(), MAX(0, MIN(d.asInt(), 255)));
}
break;
default:
@ -1150,7 +1147,7 @@ void Lingo::setTheEntity(int entity, Datum &id, int field, Datum &d) {
break;
case kTheSoundLevel:
// setting all of the channel for now
_vm->getCurrentWindow()->getSoundManager()->setSoundLevel(-1, d.asInt());
_vm->getCurrentWindow()->getSoundManager()->setChannelVolume(-1, MAX(0, MIN(d.asInt() * 32, 255)));
break;
case kTheSprite:
setTheSprite(id, field, d);

View File

@ -1466,9 +1466,9 @@ Channel *Score::getChannelById(uint16 id) {
void Score::playSoundChannel(bool puppetOnly) {
DirectorSound *sound = _window->getSoundManager();
debugC(5, kDebugSound, "Score::playSoundChannel(): Sound1: %s puppet: %d type: %d, Sound2: %s puppet: %d, type: %d",
_currentFrame->_mainChannels.sound1.asString().c_str(), sound->isChannelPuppet(1), _currentFrame->_mainChannels.soundType1,
_currentFrame->_mainChannels.sound2.asString().c_str(), sound->isChannelPuppet(2), _currentFrame->_mainChannels.soundType2);
debugC(5, kDebugSound, "Score::playSoundChannel(): Sound1: %s puppet: %d type: %d, volume: %d, Sound2: %s puppet: %d, type: %d, volume: %d",
_currentFrame->_mainChannels.sound1.asString().c_str(), sound->isChannelPuppet(1), _currentFrame->_mainChannels.soundType1, sound->getChannelVolume(1),
_currentFrame->_mainChannels.sound2.asString().c_str(), sound->isChannelPuppet(2), _currentFrame->_mainChannels.soundType2, sound->getChannelVolume(2));
if (sound->isChannelPuppet(1)) {
sound->playPuppetSound(1);

View File

@ -640,40 +640,33 @@ void DirectorSound::playFPlaySound(const Common::Array<Common::String> &fplayLis
playFPlaySound();
}
void DirectorSound::setSoundLevelInternal(uint8 soundChannel, uint8 soundLevel) {
// we have 8 level of sounds, and in ScummVM, we have range 0 to 255, thus 1 level represent 32
_channels[soundChannel]->volume = soundLevel * 32;
_volumes[soundChannel] = soundLevel * 32;
void DirectorSound::setChannelVolumeInternal(uint8 soundChannel, uint8 volume) {
if (volume == _channels[soundChannel]->volume)
return;
if (_enable && isChannelActive(soundChannel))
cancelFade(soundChannel);
_channels[soundChannel]->volume = volume;
_volumes[soundChannel] = volume;
if (_enable)
_mixer->setChannelVolume(_channels[soundChannel]->handle, _channels[soundChannel]->volume);
}
// -1 represent all the sound channel
void DirectorSound::setSoundLevel(int channel, uint8 soundLevel) {
if (soundLevel >= 8) {
warning("DirectorSound::setSoundLevel: soundLevel %d out of bounds", soundLevel);
return;
}
void DirectorSound::setChannelVolume(int channel, uint8 volume) {
if (channel != -1) {
if (!assertChannel(channel))
return;
debugC(5, kDebugSound, "DirectorSound::setSoundLevel: setting channel %d to level %d", channel, soundLevel);
setSoundLevelInternal(channel, soundLevel);
debugC(5, kDebugSound, "DirectorSound::setChannelVolume: setting channel %d to volume %d", channel, volume);
setChannelVolumeInternal(channel, volume);
} else {
debugC(5, kDebugSound, "DirectorSound::setSoundLevel: setting all channels to level %d", soundLevel);
debugC(5, kDebugSound, "DirectorSound::setChannelVolume: setting all channels to volume %d", volume);
for (uint i = 0; i < _channels.size(); i++)
setSoundLevelInternal(i + 1, soundLevel);
setChannelVolumeInternal(i + 1, volume);
}
}
uint8 DirectorSound::getSoundLevel(uint8 soundChannel) {
if (!assertChannel(soundChannel))
return 0;
return _channels[soundChannel]->volume / 32;
}
SNDDecoder::SNDDecoder()
: AudioDecoder() {
_data = nullptr;

View File

@ -185,8 +185,6 @@ public:
void playExternalSound(uint16 menu, uint16 submenu, uint8 soundChannel);
void playFPlaySound(const Common::Array<Common::String> &fplayList);
void playFPlaySound();
void setSoundLevel(int channel, uint8 soundLevel);
uint8 getSoundLevel(uint8 soundChannel);
void setSoundEnabled(bool enabled);
void systemBeep();
void changingMovie();
@ -207,6 +205,7 @@ public:
bool isChannelActive(uint8 soundChannel);
uint8 getChannelVolume(uint8 soundChannel);
void setChannelVolume(int channel, uint8 volume);
void stopSound(uint8 soundChannel);
void stopSound();
void setChannelDefaultVolume(int soundChannel);
@ -216,7 +215,7 @@ private:
bool isLastPlayedSound(uint8 soundChannel, const SoundID &soundId);
bool shouldStopOnZero(uint8 soundChannel);
void setSoundLevelInternal(uint8 soundChannel, uint8 soundLevel);
void setChannelVolumeInternal(uint8 soundChannel, uint8 volume);
bool assertChannel(int soundChannel);
void cancelFade(uint8 soundChannel);
};