ref: af1dd2eb9436b2a1cba2886eb2d2637e7fd7950c
parent: 66477dc794278f615447f1b2dae1fba69a63401a
author: Simon Howard <fraggle@gmail.com>
date: Sat Nov 1 16:42:30 EDT 2014
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.
--- a/src/i_oplmusic.c
+++ b/src/i_oplmusic.c
@@ -610,6 +610,26 @@
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 @@
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 @@
{
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 @@
}
// The channel.
- channel = &track->channels[event->data.channel.channel];
+ channel = TrackChannelForEvent(track, event);
- // Percussion channel (10) is treated differently.
-
+ // Percussion channel is treated differently.
if (event->data.channel.channel == 9)
{
if (key < 35 || key > 81)
@@ -891,14 +908,14 @@
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 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 @@
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 @@
// 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.