ref: 1d045ed19c58abff063ac69db24a2e73d62ef530
parent: ca23c95db8053b82fb817241e5de83a881f931e5
author: Simon Howard <fraggle@gmail.com>
date: Sun Aug 30 18:03:20 EDT 2009
Initial, broken, volume level setting. Subversion-branch: /branches/opl-branch Subversion-revision: 1644
--- a/src/i_oplmusic.c
+++ b/src/i_oplmusic.c
@@ -160,6 +160,27 @@
0x2da, 0x306, 0x334, 0x365, 0x398, 0x3cf,
};
+// Mapping from MIDI volume level to OPL level value.
+
+static const unsigned int volume_mapping_table[] = {
+ 0x3f, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x3a,
+ 0x39, 0x38, 0x37, 0x37, 0x36, 0x35, 0x34, 0x34,
+ 0x33, 0x32, 0x32, 0x31, 0x30, 0x2f, 0x2f, 0x2e,
+ 0x2d, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27,
+ 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x22, 0x21,
+ 0x20, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c,
+ 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18, 0x17,
+ 0x17, 0x16, 0x16, 0x16, 0x16, 0x15, 0x15, 0x14,
+ 0x14, 0x13, 0x13, 0x12, 0x12, 0x12, 0x11, 0x11,
+ 0x10, 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e,
+ 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0b,
+ 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09,
+ 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07,
+ 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x04,
+ 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+};
+
static boolean music_initialised = false;
//static boolean musicpaused = false;
@@ -662,8 +683,11 @@
// TODO: Set the volume level.
- WriteRegister(OPL_REGS_LEVEL + voice->op2, 0);
+ WriteRegister(OPL_REGS_LEVEL + voice->op2,
+ volume_mapping_table[channel->volume]);
+ printf("volume = %i\n", channel->volume);
+
// Play the note.
voice->channel = channel;
@@ -694,12 +718,32 @@
static void ControllerEvent(opl_track_data_t *track, midi_event_t *event)
{
+ unsigned int controller;
+ unsigned int param;
+ opl_channel_data_t *channel;
+
printf("change controller: channel %i, %i, %i\n",
event->data.channel.channel,
event->data.channel.param1,
event->data.channel.param2);
- // TODO: Volume, pan.
+ channel = &track->channels[event->data.channel.channel];
+ controller = event->data.channel.param1;
+ param = event->data.channel.param2;
+
+ switch (controller)
+ {
+ case MIDI_CONTROLLER_MAIN_VOLUME:
+ channel->volume = param;
+ break;
+
+ case MIDI_CONTROLLER_PAN:
+ break;
+
+ default:
+ fprintf(stderr, "Unknown MIDI controller type: %i\n", controller);
+ break;
+ }
}
// Process a MIDI event from a track.
--- a/src/midifile.h
+++ b/src/midifile.h
@@ -54,6 +54,9 @@
MIDI_CONTROLLER_FOOT_CONTROL = 0x3,
MIDI_CONTROLLER_PORTAMENTO = 0x4,
MIDI_CONTROLLER_DATA_ENTRY = 0x5,
+
+ MIDI_CONTROLLER_MAIN_VOLUME = 0x7,
+ MIDI_CONTROLLER_PAN = 0xa
} midi_controller_t;
typedef enum