shithub: choc

Download patch

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