aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md3
-rw-r--r--src/adlmidi_opl3.cpp46
2 files changed, 45 insertions, 4 deletions
diff --git a/README.md b/README.md
index 2733f97..21bb6ed 100644
--- a/README.md
+++ b/README.md
@@ -184,8 +184,9 @@ To build that example you will need to have installed SDL2 library.
* Reworked rhythm-mode percussions system, WOPL banks with rhythm-mode percussions
* Added Public Domain Opal OPL3 emulator made by Reality (a team who originally made the Reality Adlib Tracker) (Thanks to [Jean Pierre Cimalando](https://github.com/jpcima) for a work!)
* Added LGPL licensed JavaOPL3 emulator made by Robson Cozendey in Java and later rewritten into C++ for GZDoom (Thanks to [Jean Pierre Cimalando](https://github.com/jpcima) for a work!)
- * Fixed an accuracy of the DMX volume model
+ * Fixed an accuracy of the DMX volume model, include the buggy AM intepretation
* Fully rewritten an embedded banks database
+ * Improved an accuracy of Apogee volume model, include the bug of AM instruments
## 1.4.0 2018-10-01
* Implemented a full support for Portamento! (Thanks to [Jean Pierre Cimalando](https://github.com/jpcima) for a work!)
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;