diff options
-rw-r--r-- | engines/sci/sound/midiparser_sci.cpp | 23 | ||||
-rw-r--r-- | engines/sci/sound/midiparser_sci.h | 3 | ||||
-rw-r--r-- | engines/sci/sound/music.cpp | 12 | ||||
-rw-r--r-- | engines/sci/sound/music.h | 6 | ||||
-rw-r--r-- | engines/sci/sound/soundcmd.cpp | 15 |
5 files changed, 47 insertions, 12 deletions
diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp index bdb907a451..1ea990332b 100644 --- a/engines/sci/sound/midiparser_sci.cpp +++ b/engines/sci/sound/midiparser_sci.cpp @@ -79,6 +79,7 @@ bool MidiParser_SCI::loadMusic(SoundResource::Track *track, MusicEntry *psnd, in for (int i = 0; i < 15; i++) { _channelUsed[i] = false; _channelRemap[i] = -1; + _channelMuted[i] = false; } _channelRemap[9] = 9; // never map channel 9, because that's used for percussion _channelRemap[15] = 15; // never map channel 15, because thats used by sierra internally @@ -143,8 +144,22 @@ void MidiParser_SCI::unloadMusic() { } void MidiParser_SCI::sendToDriver(uint32 b) { + byte midiChannel = b & 0xf; + + if ((b & 0xFFF0) == 0x4EB0) { + // this is channel mute only for sci1 + // it's velocity control for sci0 + if (_soundVersion >= SCI_VERSION_1_EARLY) { + _channelMuted[midiChannel] = b & 0xFF0000 ? true : false; + return; // don't send this to driver at all + } + } + + // Is channel muted? if so, don't send command + if (_channelMuted[midiChannel]) + return; // Channel remapping - int16 realChannel = _channelRemap[b & 0xf]; + int16 realChannel = _channelRemap[midiChannel]; assert(realChannel != -1); b = (b & 0xFFFFFFF0) | realChannel; _driver->send(b); @@ -249,7 +264,6 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) { case 0x0A: // pan case 0x0B: // expression case 0x40: // sustain - case 0x4E: // velocity control case 0x79: // reset all case 0x7B: // notes off // These are all handled by the music driver, so ignore them @@ -263,8 +277,11 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) { break; } } - if (info.basic.param1 == 7) // channel volume change -scale it + switch (info.basic.param1) { + case 7: // channel volume change -scale it info.basic.param2 = info.basic.param2 * _volume / MUSIC_VOLUME_MAX; + break; + } info.length = 0; break; diff --git a/engines/sci/sound/midiparser_sci.h b/engines/sci/sound/midiparser_sci.h index 4888fa06ca..89d1e63d8c 100644 --- a/engines/sci/sound/midiparser_sci.h +++ b/engines/sci/sound/midiparser_sci.h @@ -76,9 +76,9 @@ public: const byte *getMixedData() const { return _mixedData; } void tryToOwnChannels(); + void sendToDriver(uint32 b); protected: - void sendToDriver(uint32 b); void parseNextEvent(EventInfo &info); byte *midiMixChannels(); byte *midiFilterChannels(int channelMask); @@ -101,6 +101,7 @@ protected: bool _channelUsed[16]; int16 _channelRemap[16]; + bool _channelMuted[16]; }; } // End of namespace Sci diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp index a1c6cc0a56..c5fc07bfd7 100644 --- a/engines/sci/sound/music.cpp +++ b/engines/sci/sound/music.cpp @@ -446,6 +446,18 @@ void SciMusic::soundSetMasterVolume(uint16 vol) { _pMidiDrv->setVolume(vol); } +void SciMusic::sendMidiCommand(uint32 cmd) { + Common::StackLock lock(_mutex); + _pMidiDrv->send(cmd); +} + +void SciMusic::sendMidiCommand(MusicEntry *pSnd, uint32 cmd) { + if (pSnd->pMidiParser) + pSnd->pMidiParser->sendToDriver(cmd); + else + warning("tried to cmdSendMidi on non midi slot (%04x:%04x)", PRINT_REG(pSnd->soundObj)); +} + void SciMusic::printPlayList(Console *con) { Common::StackLock lock(_mutex); diff --git a/engines/sci/sound/music.h b/engines/sci/sound/music.h index bbafb808cb..8e68d3df92 100644 --- a/engines/sci/sound/music.h +++ b/engines/sci/sound/music.h @@ -179,10 +179,8 @@ public: MusicList::iterator getPlayListStart() { return _playList.begin(); } MusicList::iterator getPlayListEnd() { return _playList.end(); } - void sendMidiCommand(uint32 cmd) { - Common::StackLock lock(_mutex); - _pMidiDrv->send(cmd); - } + void sendMidiCommand(uint32 cmd); + void sendMidiCommand(MusicEntry *pSnd, uint32 cmd); void setReverb(byte reverb); diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp index 6ee23d7fc8..fa215ac302 100644 --- a/engines/sci/sound/soundcmd.cpp +++ b/engines/sci/sound/soundcmd.cpp @@ -232,9 +232,8 @@ reg_t SoundCommandParser::parseCommand(int argc, reg_t *argv, reg_t acc) { uint16 controller = argv[4].toUint16(); uint16 param = argv[5].toUint16(); - if (!channel) - error("invalid channel specified on cmdSendMidi"); - channel--; // channel is given 1-based, we are using 0-based + if (channel) + channel--; // channel is given 1-based, we are using 0-based _midiCommand = (channel | midiCmd) | ((uint32)controller << 8) | ((uint32)param << 16); } @@ -901,7 +900,15 @@ void SoundCommandParser::cmdSendMidi(reg_t obj, int16 value) { //SongHandle handle = FROBNICATE_HANDLE(obj); //_state->sfx_send_midi(handle, value, _midiCmd, _controller, _param); #else - _music->sendMidiCommand(_midiCommand); + MusicEntry *musicSlot = _music->getSlot(obj); + if (!musicSlot) { + // TODO: maybe it's possible to call this with obj == 0:0 and send directly?! + // if so, allow it + //_music->sendMidiCommand(_midiCommand); + warning("cmdSendMidi: Slot not found (%04x:%04x)", PRINT_REG(obj)); + return; + } + _music->sendMidiCommand(musicSlot, _midiCommand); #endif } |