MIDI synth (Fluidsynth): Add code to recognize Roland GS MASTER VOLUME sysex. Now PC-98 games can "fade out" the MIDI music using GS commands (Seiyoku Gakuen Seraphita)

This commit is contained in:
Jonathan Campbell 2025-01-10 18:35:31 -08:00
parent c109f80c5b
commit 4035992975
2 changed files with 26 additions and 0 deletions

View File

@ -58,6 +58,7 @@ struct DB_Midi {
DB_Midi() {}
};
extern bool roland_gs_sysex;
extern DB_Midi midi;
#endif

View File

@ -33,6 +33,7 @@
static MixerChannel *synthchan = NULL;
static fluid_synth_t *synth_soft = NULL;
static int synthsamplerate = 0;
static uint8_t master_volume = 128;
static void synth_log(int level,
#if !defined (FLUIDSYNTH_VERSION_MAJOR) || FLUIDSYNTH_VERSION_MAJOR >= 2 // Let version 2.x be the default
@ -61,6 +62,11 @@ static void synth_log(int level,
static void synth_CallBack(Bitu len) {
if (synth_soft != NULL) {
fluid_synth_write_s16(synth_soft, (int)len, MixTemp, 0, 2, MixTemp, 1, 2);
if (master_volume < 128) {
for (unsigned int i=0;i < (len*2);i++) {
((int16_t*)MixTemp)[i] = (int16_t)(((((int16_t*)MixTemp)[i]) * master_volume) >> 7);
}
}
synthchan->AddSamples_s16(len,(int16_t *)MixTemp);
}
}
@ -82,6 +88,23 @@ private:
void PlayEvent(uint8_t *msg, Bitu len) {
uint8_t event = msg[0], channel, p1, p2;
if (roland_gs_sysex) {
if (msg[1] == 0x41/*Roland*/ && msg[3] == 0x42/*GS*/ && msg[4] == 0x12/*Send*/ && len >= 9) {
const uint32_t addr =
((uint32_t)msg[5] << 16) +
((uint32_t)msg[6] << 8) +
(uint32_t)msg[7];
if (addr == 0x400004) { /* MASTER VOLUME */
/* Fluidsynth doesn't appear to support this message, so we have to handle it ourself. */
master_volume = msg[8];
if (master_volume >= 127) master_volume = 128;
LOG_MSG("MIDI synth: MASTER VOLUME %u",master_volume);
return;
}
}
}
switch (event) {
case 0xf0:
case 0xf7:
@ -92,6 +115,7 @@ private:
LOG(LOG_MISC,LOG_DEBUG)("SYNTH: midi tick");
return;
case 0xff:
master_volume = 128;
LOG(LOG_MISC,LOG_DEBUG)("SYNTH: system reset");
fluid_synth_system_reset(synth_soft);
return;
@ -224,6 +248,7 @@ public:
sffile=sf;
fsinfo="Sound font: "+sf;
master_volume = 128;
synthchan = MIXER_AddChannel(synth_CallBack, (unsigned int)synthsamplerate, "SYNTH");
synthchan->Enable(false);
isOpen = true;