ZDoom / ZMusic

GZDoom's music system as a standalone library
https://forum.zdoom.org/index.php
61 stars 32 forks source link

Fixed 2 bugs that prevented GS banks from being selected. #55

Closed RoqueDeicide closed 8 months ago

RoqueDeicide commented 8 months ago

I initially noticed that the Reverse Cymbal was being played instead of Reverse Snare at the beginning of "One Night in Neo Kobe City" track featured in DBP37: AUGER;ZENITH megawad. This was happening with both internal and external FluidSynth instances, as well as with Microsoft GS Wavetable Synth. I realized that they weren't reacting to Bank Select ControlChange MIDI messages.

After a lot of digging, I finally found out, what was causing it: a SysEx message sent by MIDIStreamer::FillBuffer function. It appears, there was a misunderstanding of its purpose: in the comment it's referred to as a "GS System Reset", but it's actually a "GM System Enable" message. It's primary effect is to switch the synth to a pure GM mode, with a system reset as a side effect.

I've decided to keep the message, so that any pure GM synth can perform a system reset, but I've changed the comment to properly reflect its identity. I've also added another SysEx message, called "GS DT1 MODE SET" to instruct the synth to switch to GS mode, if one is supported.

The change worked, but only with MSGSWS and external FluidSynth, not with internal FluidSynth. After more digging, I chanced upon a bug from all the way back in August 2010: the number of bytes reported to FluidSynth as comprising the SysEx message was 1 too big, as both first and last bytes needed to be excluded, not just the first one. This didn't matter for "GM System Enable" message, as when processing it, FluidSynth doesn't check the byte count. I've fixed the bug and added a clarifying comment.

These changes were only tested with internal and external FluidSynth and MSGSWS.