summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Howard2014-11-01 20:42:30 -0400
committerSimon Howard2014-11-01 20:42:30 -0400
commitaf1dd2eb9436b2a1cba2886eb2d2637e7fd7950c (patch)
tree2240e9177eb0b70281cc2c9ca2a122feb9fa7f9b
parent66477dc794278f615447f1b2dae1fba69a63401a (diff)
downloadchocolate-doom-af1dd2eb9436b2a1cba2886eb2d2637e7fd7950c.tar.gz
chocolate-doom-af1dd2eb9436b2a1cba2886eb2d2637e7fd7950c.tar.bz2
chocolate-doom-af1dd2eb9436b2a1cba2886eb2d2637e7fd7950c.zip
opl: Internally swap MUS/MID percussion channel #s.
MIDI uses channel 9 for percussion but MUS uses channel 15. As the channel numbers matter when we run out of free voices (#468), internally swap channels 9 and 15 so that channel precedence is decided correctly.
-rw-r--r--src/i_oplmusic.c43
1 files changed, 30 insertions, 13 deletions
diff --git a/src/i_oplmusic.c b/src/i_oplmusic.c
index aa6a7a6d..433e78fa 100644
--- a/src/i_oplmusic.c
+++ b/src/i_oplmusic.c
@@ -610,6 +610,26 @@ static void VoiceKeyOff(opl_voice_t *voice)
OPL_WriteRegister(OPL_REGS_FREQ_2 + voice->index, voice->freq >> 8);
}
+static opl_channel_data_t *TrackChannelForEvent(opl_track_data_t *track,
+ midi_event_t *event)
+{
+ unsigned int channel_num = event->data.channel.channel;
+
+ // MIDI uses track #9 for percussion, but for MUS it's track #15
+ // instead. Because DMX works on MUS data internally, we need to
+ // swap back to the MUS version of the channel number.
+ if (channel_num == 9)
+ {
+ channel_num = 15;
+ }
+ else if (channel_num == 15)
+ {
+ channel_num = 9;
+ }
+
+ return &track->channels[channel_num];
+}
+
// Get the frequency that we should be using for a voice.
static void KeyOffEvent(opl_track_data_t *track, midi_event_t *event)
@@ -625,7 +645,7 @@ static void KeyOffEvent(opl_track_data_t *track, midi_event_t *event)
event->data.channel.param2);
*/
- channel = &track->channels[event->data.channel.channel];
+ channel = TrackChannelForEvent(track, event);
key = event->data.channel.param1;
// Turn off voices being used to play this key.
@@ -826,9 +846,7 @@ static void KeyOnEvent(opl_track_data_t *track, midi_event_t *event)
{
genmidi_instr_t *instrument;
opl_channel_data_t *channel;
- unsigned int note;
- unsigned int key;
- unsigned int volume;
+ unsigned int note, key, volume;
/*
printf("note on: channel %i, %i, %i\n",
@@ -851,10 +869,9 @@ static void KeyOnEvent(opl_track_data_t *track, midi_event_t *event)
}
// The channel.
- channel = &track->channels[event->data.channel.channel];
-
- // Percussion channel (10) is treated differently.
+ channel = TrackChannelForEvent(track, event);
+ // Percussion channel is treated differently.
if (event->data.channel.channel == 9)
{
if (key < 35 || key > 81)
@@ -891,14 +908,14 @@ static void KeyOnEvent(opl_track_data_t *track, midi_event_t *event)
static void ProgramChangeEvent(opl_track_data_t *track, midi_event_t *event)
{
- int channel;
+ opl_channel_data_t *channel;
int instrument;
// Set the instrument used on this channel.
- channel = event->data.channel.channel;
+ channel = TrackChannelForEvent(track, event);
instrument = event->data.channel.param1;
- track->channels[channel].instrument = &main_instrs[instrument];
+ channel->instrument = &main_instrs[instrument];
// TODO: Look through existing voices that are turned on on this
// channel, and change the instrument.
@@ -938,9 +955,9 @@ static void AllNotesOff(opl_channel_data_t *channel, unsigned int param)
static void ControllerEvent(opl_track_data_t *track, midi_event_t *event)
{
+ opl_channel_data_t *channel;
unsigned int controller;
unsigned int param;
- opl_channel_data_t *channel;
/*
printf("change controller: channel %i, %i, %i\n",
@@ -949,7 +966,7 @@ static void ControllerEvent(opl_track_data_t *track, midi_event_t *event)
event->data.channel.param2);
*/
- channel = &track->channels[event->data.channel.channel];
+ channel = TrackChannelForEvent(track, event);
controller = event->data.channel.param1;
param = event->data.channel.param2;
@@ -981,7 +998,7 @@ static void PitchBendEvent(opl_track_data_t *track, midi_event_t *event)
// Update the channel bend value. Only the MSB of the pitch bend
// value is considered: this is what Doom does.
- channel = &track->channels[event->data.channel.channel];
+ channel = TrackChannelForEvent(track, event);
channel->bend = event->data.channel.param2 - 64;
// Update all voices for this channel.