diff --git a/Components/OPL2/Implementation/EnvelopeGenerator.hpp b/Components/OPL2/Implementation/EnvelopeGenerator.hpp index af721781b..ae34aa62c 100644 --- a/Components/OPL2/Implementation/EnvelopeGenerator.hpp +++ b/Components/OPL2/Implementation/EnvelopeGenerator.hpp @@ -79,10 +79,10 @@ template class EnvelopeGenerator } /*! - @returns The current attenuation from this envelope generator. + @returns The current attenuation from this envelope generator. This is independent of the envelope precision. */ int attenuation() const { - return attenuation_ + tremolo_; + return (attenuation_ + tremolo_) << 3; } /*! diff --git a/Components/OPL2/OPLL.cpp b/Components/OPL2/OPLL.cpp index 937b410cf..b18ddde0e 100644 --- a/Components/OPL2/OPLL.cpp +++ b/Components/OPL2/OPLL.cpp @@ -298,10 +298,11 @@ void OPLL::update_all_channels() { int OPLL::melodic_output(int channel) { - // TODO: key-rate scaling. - // TODO: proper scales of all attenuations below. + // TODO: verify attenuation scales. auto modulation = WaveformGenerator::wave(channels_[channel].modulator_waveform, phase_generators_[channel + 9].phase()); - modulation += envelope_generators_[channel + 9].attenuation() + channels_[channel].modulator_attenuation; + modulation += envelope_generators_[channel + 9].attenuation() + (channels_[channel].modulator_attenuation << 5) + key_level_scalers_[channel + 9].attenuation(); - return WaveformGenerator::wave(channels_[channel].carrier_waveform, phase_generators_[channel].scaled_phase(), modulation).level() + channels_[channel].attenuation; + auto carrier = WaveformGenerator::wave(channels_[channel].carrier_waveform, phase_generators_[channel].scaled_phase(), modulation); + carrier += envelope_generators_[channel].attenuation() + (channels_[channel].attenuation << 7) + key_level_scalers_[channel].attenuation(); + return carrier.level(); }