foxygit / doom Log in
commit 1d045ed19c58abff063ac69db24a2e73d62ef530
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Sun Aug 30 22:03:20 2009 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Sun Aug 30 22:03:20 2009 +0000

    Initial, broken, volume level setting.

    Subversion-branch: /branches/opl-branch
    Subversion-revision: 1644
---
 src/i_oplmusic.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++--
 src/midifile.h   |  3 +++
 2 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/src/i_oplmusic.c b/src/i_oplmusic.c
index 3d9a2649..7a619c5d 100644
--- a/src/i_oplmusic.c
+++ b/src/i_oplmusic.c
@@ -160,6 +160,27 @@ static const unsigned int note_frequencies[] = {
     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,7 +683,10 @@ static void NoteOnEvent(opl_track_data_t *track, midi_event_t *event)

     // 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.

@@ -694,12 +718,32 @@ static void ProgramChangeEvent(opl_track_data_t *track, midi_event_t *event)

 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.
diff --git a/src/midifile.h b/src/midifile.h
index a1ab4976..faef549c 100644
--- a/src/midifile.h
+++ b/src/midifile.h
@@ -54,6 +54,9 @@ typedef enum
     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