diff options
-rw-r--r-- | src/i_oplmusic.c | 19 | ||||
-rw-r--r-- | src/midifile.h | 4 | ||||
-rw-r--r-- | src/mus2mid.c | 10 |
3 files changed, 30 insertions, 3 deletions
diff --git a/src/i_oplmusic.c b/src/i_oplmusic.c index 5f9ab462..bcc8fe68 100644 --- a/src/i_oplmusic.c +++ b/src/i_oplmusic.c @@ -961,6 +961,21 @@ static void SetChannelVolume(opl_channel_data_t *channel, unsigned int volume) } } +// Handler for the MIDI_CONTROLLER_ALL_NOTES_OFF channel event. +static void AllNotesOff(opl_channel_data_t *channel, unsigned int param) +{ + unsigned int i; + + for (i = 0; i < OPL_NUM_VOICES; ++i) + { + if (voices[i].channel == channel) + { + VoiceKeyOff(&voices[i]); + ReleaseVoice(&voices[i]); + } + } +} + static void ControllerEvent(opl_track_data_t *track, midi_event_t *event) { unsigned int controller; @@ -984,6 +999,10 @@ static void ControllerEvent(opl_track_data_t *track, midi_event_t *event) SetChannelVolume(channel, param); break; + case MIDI_CONTROLLER_ALL_NOTES_OFF: + AllNotesOff(channel, param); + break; + default: #ifdef OPL_MIDI_DEBUG fprintf(stderr, "Unknown MIDI controller type: %i\n", controller); diff --git a/src/midifile.h b/src/midifile.h index b539b1b5..490c2a0a 100644 --- a/src/midifile.h +++ b/src/midifile.h @@ -48,7 +48,9 @@ typedef enum MIDI_CONTROLLER_DATA_ENTRY = 0x5, MIDI_CONTROLLER_MAIN_VOLUME = 0x7, - MIDI_CONTROLLER_PAN = 0xa + MIDI_CONTROLLER_PAN = 0xa, + + MIDI_CONTROLLER_ALL_NOTES_OFF = 0x7b, } midi_controller_t; typedef enum diff --git a/src/mus2mid.c b/src/mus2mid.c index 2bf5ef9a..3cbcb0dd 100644 --- a/src/mus2mid.c +++ b/src/mus2mid.c @@ -383,7 +383,7 @@ static int AllocateMIDIChannel(void) // Given a MUS channel number, get the MIDI channel number to use // in the outputted file. -static int GetMIDIChannel(int mus_channel) +static int GetMIDIChannel(int mus_channel, MEMFILE *midioutput) { // Find the MIDI channel to use for this MUS channel. // MUS channel 15 is the percusssion channel. @@ -400,6 +400,12 @@ static int GetMIDIChannel(int mus_channel) if (channel_map[mus_channel] == -1) { channel_map[mus_channel] = AllocateMIDIChannel(); + + // First time using the channel, send an "all notes off" + // event. This fixes "The D_DDTBLU disease" described here: + // http://www.doomworld.com/vb/source-ports/66802-the + WriteChangeController_Valueless(channel_map[mus_channel], 0x7b, + midioutput); } return channel_map[mus_channel]; @@ -514,7 +520,7 @@ boolean mus2mid(MEMFILE *musinput, MEMFILE *midioutput) return true; } - channel = GetMIDIChannel(eventdescriptor & 0x0F); + channel = GetMIDIChannel(eventdescriptor & 0x0F, midioutput); event = eventdescriptor & 0x70; switch (event) |