diff --git a/engines/kyra/sound_midi.cpp b/engines/kyra/sound_midi.cpp index fc6e92a..1bedb43 100644 --- a/engines/kyra/sound_midi.cpp +++ b/engines/kyra/sound_midi.cpp @@ -36,7 +36,7 @@ public: MidiOutput(OSystem *system, MidiDriver *output, bool isMT32, bool defaultMT32); ~MidiOutput(); - void setSourceVolume(int source, int volume, bool apply=false); + void setSourceVolume(int source, int volume, bool apply=false, bool immediate=false); void initSource(int source); void deinitSource(int source); @@ -82,6 +82,9 @@ private: byte noteCount; + bool hasPendingVolume; + byte pendingVolume; + Controller controllers[9]; } _channels[16]; @@ -235,18 +238,22 @@ void MidiOutput::send(uint32 b) { } if (note != -1) { + int ch = _sources[_curSource].channelMap[channel]; if (remove) { _sources[_curSource].notes[note].channel = 0xFF; - --_channels[_sources[_curSource].channelMap[channel]].noteCount; + --_channels[ch].noteCount; } else { _sources[_curSource].notes[note].channel = channel; _sources[_curSource].notes[note].note = param1; - ++_channels[_sources[_curSource].channelMap[channel]].noteCount; + ++_channels[ch].noteCount; } - - sendIntern(event, _sources[_curSource].channelMap[channel], param1, param2); + if (!remove && _channels[ch].hasPendingVolume) { + sendIntern(0xB0, ch, 0x07, _channels[ch].pendingVolume); + _channels[ch].hasPendingVolume = false; + } + sendIntern(event, ch, param1, param2); } } return; @@ -316,7 +323,7 @@ void MidiOutput::metaEvent(byte type, byte *data, uint16 length) { _output->metaEvent(type, data, length); } -void MidiOutput::setSourceVolume(int source, int volume, bool apply) { +void MidiOutput::setSourceVolume(int source, int volume, bool apply, bool immediate) { _sources[source].volume = volume; if (apply) { @@ -324,7 +331,12 @@ void MidiOutput::setSourceVolume(int source, int volume, bool apply) { // Controller 0 in the state table should always be '7' aka // volume control byte realVol = (_sources[source].controllers[i][0].value * volume) >> 8; - sendIntern(0xB0, i, 0x07, realVol); + if (immediate) { + sendIntern(0xB0, i, 0x07, realVol); + } else { + _channels[i].hasPendingVolume = true; + _channels[i].pendingVolume = realVol; + } } } } @@ -339,6 +351,9 @@ void MidiOutput::initSource(int source) { for (int j = 0; j < 9; ++j) _sources[source].controllers[i][j] = _channels[i].controllers[j]; + + _channels[i].hasPendingVolume = false; + _channels[i].pendingVolume = 0; } } @@ -584,7 +599,7 @@ void SoundMidiPC::updateVolumeSettings() { const int newMusVol = (mute ? 0 : ConfMan.getInt("music_volume")); _sfxVolume = (mute ? 0 : ConfMan.getInt("sfx_volume")); - _output->setSourceVolume(0, newMusVol, newMusVol != _musicVolume); + _output->setSourceVolume(0, newMusVol, newMusVol != _musicVolume, true); _musicVolume = newMusVol; for (int i = 1; i < 4; ++i) @@ -768,7 +783,7 @@ void SoundMidiPC::onTimer(void *data) { if (midi->_fadeStartTime + musicFadeTime > midi->_vm->_system->getMillis()) { int volume = (byte)((musicFadeTime - (midi->_vm->_system->getMillis() - midi->_fadeStartTime)) * midi->_musicVolume / musicFadeTime); - midi->_output->setSourceVolume(0, volume, true); + midi->_output->setSourceVolume(0, volume, true, true); } else { for (int i = 0; i < 16; ++i) midi->_output->stopNotesOnChannel(i);