diff options
author | Wohlstand <admin@wohlnet.ru> | 2020-08-30 20:20:50 +0300 |
---|---|---|
committer | Wohlstand <admin@wohlnet.ru> | 2020-08-30 20:21:33 +0300 |
commit | f8bf13beafd9f837212c08f38798a5e781d7b5e5 (patch) | |
tree | b3612fe4a178a00682fb3568deb527166f71045f /src/adlmidi_opl3.cpp | |
parent | 82fa5cb3e0859942fc6b353a3138aae8c10520a3 (diff) | |
download | libADLMIDI-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.cpp | 46 |
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; |