aboutsummaryrefslogtreecommitdiff
path: root/src/adlmidi_opl3.cpp
diff options
context:
space:
mode:
authorWohlstand <admin@wohlnet.ru>2020-08-30 20:20:50 +0300
committerWohlstand <admin@wohlnet.ru>2020-08-30 20:21:33 +0300
commitf8bf13beafd9f837212c08f38798a5e781d7b5e5 (patch)
treeb3612fe4a178a00682fb3568deb527166f71045f /src/adlmidi_opl3.cpp
parent82fa5cb3e0859942fc6b353a3138aae8c10520a3 (diff)
downloadlibADLMIDI-f8bf13beafd9f837212c08f38798a5e781d7b5e5.tar.gz
libADLMIDI-f8bf13beafd9f837212c08f38798a5e781d7b5e5.tar.bz2
libADLMIDI-f8bf13beafd9f837212c08f38798a5e781d7b5e5.zip
Improved an accuracy of Apogee volume model
include the bug of AM instruments
Diffstat (limited to 'src/adlmidi_opl3.cpp')
-rw-r--r--src/adlmidi_opl3.cpp46
1 files changed, 43 insertions, 3 deletions
diff --git a/src/adlmidi_opl3.cpp b/src/adlmidi_opl3.cpp
index 27baa22..d0f3953 100644
--- a/src/adlmidi_opl3.cpp
+++ b/src/adlmidi_opl3.cpp
@@ -501,7 +501,8 @@ void OPL3::touchNote(size_t c,
uint_fast32_t modulator;
uint_fast32_t carrier;
- uint_fast32_t volume;
+ uint_fast32_t volume = 0;
+ uint_fast32_t midiVolume = 0;
bool do_modulator;
bool do_carrier;
@@ -521,6 +522,8 @@ void OPL3::touchNote(size_t c,
};
+ // ------ Mix volumes and compute average ------
+
switch(m_volumeScale)
{
default:
@@ -570,8 +573,8 @@ void OPL3::touchNote(size_t c,
case Synth::VOLUME_APOGEE:
{
- volume = (channelVolume * channelExpression * m_masterVolume / 16129);
- volume = ((64 * (velocity + 0x80)) * volume) >> 15;
+ volume = 0;
+ midiVolume = (channelVolume * channelExpression * m_masterVolume / 16129);
}
break;
@@ -586,6 +589,9 @@ void OPL3::touchNote(size_t c,
if(volume > 63)
volume = 63;
+ if(midiVolume > 127)
+ midiVolume = 127;
+
if(m_channelCategory[c] == ChanCat_Regular ||
m_channelCategory[c] == ChanCat_Rhythm_Bass)
@@ -614,10 +620,44 @@ void OPL3::touchNote(size_t c,
}
+
+ // ------ Compute the total level register output data ------
+
if(m_musicMode == MODE_RSXX)
{
tlCar -= volume / 2;
}
+ else if(m_volumeScale == Synth::VOLUME_APOGEE && mode <= 1)
+ {
+ // volume = ((64 * (velocity + 0x80)) * volume) >> 15;
+ do_modulator = do_ops[mode][ 0 ] || m_scaleModulators;
+
+ tlCar = 63 - tlCar;
+
+ tlCar *= velocity + 0x80;
+ tlCar = (midiVolume * tlCar) >> 15;
+ tlCar = tlCar ^ 63;
+
+ if(do_modulator)
+ {
+ tlMod = 63 - tlMod;
+ tlMod *= velocity + 0x80;
+ // NOTE: Here is a bug of Apogee Sound System that makes modulator
+ // to not work properly on AM instruments
+ // The fix of this bug is just replacing of tlCar with tmMod
+ // in this formula
+ tlMod = (midiVolume * tlCar) >> 15;
+
+ tlMod ^= 63;
+ }
+
+ if(brightness != 127)
+ {
+ brightness = static_cast<uint8_t>(::round(127.0 * ::sqrt((static_cast<double>(brightness)) * (1.0 / 127.0))) / 2.0);
+ if(!do_modulator)
+ tlMod = 63 - brightness + (brightness * tlMod) / 63;
+ }
+ }
else if(m_volumeScale == Synth::VOLUME_DMX && mode <= 1)
{
do_modulator = do_ops[mode][ 0 ] || m_scaleModulators;