summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/i_oplmusic.c19
-rw-r--r--src/midifile.h4
-rw-r--r--src/mus2mid.c10
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)