From f8bf13beafd9f837212c08f38798a5e781d7b5e5 Mon Sep 17 00:00:00 2001 From: Wohlstand Date: Sun, 30 Aug 2020 20:20:50 +0300 Subject: Improved an accuracy of Apogee volume model include the bug of AM instruments --- src/adlmidi_opl3.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) (limited to 'src/adlmidi_opl3.cpp') 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(::round(127.0 * ::sqrt((static_cast(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; -- cgit v1.2.3