shithub: choc

Download patch

ref: 00480e248644aaefea6aa66658c7dea6ae637a83
parent: 6e144e809ddc94181e6309e0492d09d918dbd89a
parent: 131efd2855b2dea7a6d00761bac69111516251da
author: Fabian Greffrath <[email protected]>
date: Sat Nov 27 03:44:44 EST 2021

Merge pull request #1409 from rfomin/non_linear_vol

win midi: Non-linear volume control

--- a/src/i_winmusic.c
+++ b/src/i_winmusic.c
@@ -83,6 +83,25 @@
 
 static buffer_t buffer;
 
+static const int volume_correction[] = {
+    0,   4,   7,   11,  13,  14,  16,  18,
+    21,  22,  23,  24,  24,  24,  25,  25,
+    25,  26,  26,  27,  27,  27,  28,  28,
+    29,  29,  29,  30,  30,  31,  31,  32,
+    32,  32,  33,  33,  34,  34,  35,  35,
+    36,  37,  37,  38,  38,  39,  39,  40,
+    40,  41,  42,  42,  43,  43,  44,  45,
+    45,  46,  47,  47,  48,  49,  49,  50,
+    51,  52,  52,  53,  54,  55,  56,  56,
+    57,  58,  59,  60,  61,  62,  62,  63,
+    64,  65,  66,  67,  68,  69,  70,  71,
+    72,  73,  74,  75,  77,  78,  79,  80,
+    81,  82,  84,  85,  86,  87,  89,  90,
+    91,  92,  94,  95,  96,  98,  99,  101,
+    102, 104, 105, 107, 108, 110, 112, 113,
+    115, 117, 118, 120, 122, 123, 125, 127
+};
+
 // Message box for midiStream errors.
 
 static void MidiErrorMessageBox(DWORD dwError)
@@ -134,6 +153,8 @@
 
             volume *= volume_factor;
 
+            volume = volume_correction[volume];
+
             event->dwEvent = (event->dwEvent & 0xFF00FFFF) |
                              ((volume & 0x7F) << 16);
         }
@@ -353,21 +374,24 @@
 
 void I_WIN_SetMusicVolume(int volume)
 {
-  int i;
+    int i;
 
-  volume_factor = (float)volume / 127;
+    volume_factor = (float)volume / 127;
 
-  // Send MIDI controller events to adjust the volume.
-  for (i = 0; i < MIDI_CHANNELS_PER_TRACK; ++i)
-  {
-    int value = channel_volume[i] * volume_factor;
+    // Send MIDI controller events to adjust the volume.
+    for (i = 0; i < MIDI_CHANNELS_PER_TRACK; ++i)
+    {
+        DWORD msg = 0;
 
-    DWORD msg = MIDI_EVENT_CONTROLLER | i |
-                (MIDI_CONTROLLER_MAIN_VOLUME << 8) |
-                (value << 16);
+        int value = channel_volume[i] * volume_factor;
 
-    midiOutShortMsg((HMIDIOUT)hMidiStream, msg);
-  }
+        value = volume_correction[value];
+
+        msg = MIDI_EVENT_CONTROLLER | i | (MIDI_CONTROLLER_MAIN_VOLUME << 8) |
+              (value << 16);
+
+        midiOutShortMsg((HMIDIOUT)hMidiStream, msg);
+    }
 }
 
 void I_WIN_StopSong(void)