ref: 10ccadee87aee30e07b66606d9d155f8cc9d7a77
parent: 0e83eb0e72e9f68e0a20a8fdd81ec31d9f2c3cd3
parent: 816f94a8220b1fe3315a64faca855dcf90c44c6b
author: Simon Howard <fraggle+github@gmail.com>
date: Mon Oct 5 06:33:08 EDT 2015
Merge pull request #618 from khokh2001/opl-volume-fix opl: DMX MIDI channel volume calculation fix.
--- a/src/i_oplmusic.c
+++ b/src/i_oplmusic.c
@@ -85,6 +85,7 @@
// Volume level
int volume;
+ int volume_base;
// Pan
@@ -311,6 +312,7 @@
static boolean music_initialized = false;
//static boolean musicpaused = false;
+static int start_music_volume;
static int current_music_volume;
// GENMIDI lump instrument data:
@@ -572,8 +574,7 @@
// Multiply note volume and channel volume to get the actual volume.
- midi_volume = 2 * (volume_mapping_table[(voice->channel->volume
- * current_music_volume) / 127] + 1);
+ midi_volume = 2 * (volume_mapping_table[voice->channel->volume] + 1);
full_volume = (volume_mapping_table[voice->note_volume] * midi_volume)
>> 9;
@@ -645,12 +646,20 @@
}
}
+static void SetChannelVolume(opl_channel_data_t *channel, unsigned int volume,
+ boolean clip_start);
+
// Set music volume (0 - 127)
static void I_OPL_SetMusicVolume(int volume)
{
- unsigned int i;
+ unsigned int i, j;
+ if (current_music_volume == volume)
+ {
+ return;
+ }
+
// Internal state variable.
current_music_volume = volume;
@@ -657,11 +666,20 @@
// Update the volume of all voices.
- for (i = 0; i < num_opl_voices; ++i)
+ for (i = 0; i < num_tracks; ++i)
{
- if (voices[i].channel != NULL)
+ for (j = 0; j < MIDI_CHANNELS_PER_TRACK; ++j)
{
- SetVoiceVolume(&voices[i], voices[i].note_volume);
+ if (j == 9)
+ {
+ SetChannelVolume(&tracks[i].channels[j],
+ volume, false);
+ }
+ else
+ {
+ SetChannelVolume(&tracks[i].channels[j],
+ tracks[i].channels[j].volume_base, false);
+ }
}
}
}
@@ -1117,10 +1135,23 @@
// channel, and change the instrument.
}
-static void SetChannelVolume(opl_channel_data_t *channel, unsigned int volume)
+static void SetChannelVolume(opl_channel_data_t *channel, unsigned int volume,
+ boolean clip_start)
{
unsigned int i;
+ channel->volume_base = volume;
+
+ if (volume > current_music_volume)
+ {
+ volume = current_music_volume;
+ }
+
+ if (clip_start && volume > start_music_volume)
+ {
+ volume = start_music_volume;
+ }
+
channel->volume = volume;
// Update all voices that this channel is using.
@@ -1232,7 +1263,7 @@
switch (controller)
{
case MIDI_CONTROLLER_MAIN_VOLUME:
- SetChannelVolume(channel, param);
+ SetChannelVolume(channel, param, true);
break;
case MIDI_CONTROLLER_PAN:
@@ -1379,6 +1410,10 @@
running_tracks = num_tracks;
+ start_music_volume = current_music_volume;
+
+ I_SetMusicVolume(current_music_volume);
+
for (i = 0; i < num_tracks; ++i)
{
MIDI_RestartIterator(tracks[i].iter);
@@ -1453,7 +1488,8 @@
// TODO: Work out sensible defaults?
channel->instrument = &main_instrs[0];
- channel->volume = 127;
+ channel->volume = current_music_volume;
+ channel->volume_base = 127;
channel->pan = 0x30;
channel->bend = 0;
}
@@ -1506,6 +1542,8 @@
// TODO: this is wrong
us_per_beat = 500 * 1000;
+
+ start_music_volume = current_music_volume;
for (i = 0; i < num_tracks; ++i)
{