diff --git a/Components/OPL2/Implementation/Channel.cpp b/Components/OPL2/Implementation/Channel.cpp index d2d84e612..e85823852 100644 --- a/Components/OPL2/Implementation/Channel.cpp +++ b/Components/OPL2/Implementation/Channel.cpp @@ -47,6 +47,11 @@ int Channel::update_melodic(const LowFrequencyOscillator &oscillator, Operator * } } +int Channel::update_tom_tom(const LowFrequencyOscillator &oscillator, Operator *modulator, bool force_key_on, OperatorOverrides *modulator_overrides) { + modulator->update(modulator_state_, nullptr, oscillator, key_on_ || force_key_on, period_ << frequency_shift_, octave_, modulator_overrides); + return modulator_state_.level(); +} + bool Channel::is_audible(Operator *carrier, OperatorOverrides *carrier_overrides) { return carrier->is_audible(carrier_state_, carrier_overrides); } diff --git a/Components/OPL2/Implementation/Channel.hpp b/Components/OPL2/Implementation/Channel.hpp index 4f45e7c37..e0a1ea0a0 100644 --- a/Components/OPL2/Implementation/Channel.hpp +++ b/Components/OPL2/Implementation/Channel.hpp @@ -42,6 +42,9 @@ class Channel { /// Updates this channel, using the operators for melodic output. int update_melodic(const LowFrequencyOscillator &oscillator, Operator *modulator, Operator *carrier, bool force_key_on = false, OperatorOverrides *modulator_overrides = nullptr, OperatorOverrides *carrier_overrides = nullptr); + /// Updates this channel's modulator state, to produce a tom tom. + int update_tom_tom(const LowFrequencyOscillator &oscillator, Operator *modulator, bool force_key_on, OperatorOverrides *modulator_overrides = nullptr); + /// Updates this channel, using the carrier to produce a snare drum and the modulator to produce a tom tom. int update_snare_tom_tom(const LowFrequencyOscillator &oscillator, Operator *modulator, Operator *carrier, OperatorOverrides *modulator_overrides = nullptr, OperatorOverrides *carrier_overrides = nullptr); diff --git a/Components/OPL2/Implementation/Operator.cpp b/Components/OPL2/Implementation/Operator.cpp index 048340022..f490af4a7 100644 --- a/Components/OPL2/Implementation/Operator.cpp +++ b/Components/OPL2/Implementation/Operator.cpp @@ -74,8 +74,12 @@ void Operator::update_adsr( if(!key_on) { state.adsr_phase_ = OperatorState::ADSRPhase::Release; } else if(!state.last_key_on_) { +// printf("---\n"); state.adsr_phase_ = OperatorState::ADSRPhase::Attack; state.attack_time_ = 0; + + // TODO: should this happen only if current ADSR attenuation is 511? +// state.raw_phase_ = 0; } state.last_key_on_ = key_on; @@ -162,6 +166,10 @@ void Operator::update_adsr( break; } ++state.attack_time_; + +// if(key_on) { +// printf("%d\n", state.adsr_attenuation_); +// } } void Operator::update( diff --git a/Components/OPL2/OPL2.cpp b/Components/OPL2/OPL2.cpp index 68cecbb00..aa376215f 100644 --- a/Components/OPL2/OPL2.cpp +++ b/Components/OPL2/OPL2.cpp @@ -139,6 +139,8 @@ void OPLL::write_register(uint8_t address, uint8_t value) { // Register 0xe is a cut-down version of the OPLL's register 0xbd. if(address == 0xe) { depth_rhythm_control_ = value & 0x3f; +// if(depth_rhythm_control_ & 0x04) +// printf("%02x\n", depth_rhythm_control_); return; } @@ -216,12 +218,13 @@ void OPLL::update_all_chanels() { output_levels_[2] = output_levels_[15] = (channels_[6].update_bass(oscillator_, &operators_[32], depth_rhythm_control_ & 0x10) * total_volume_) >> 12; + // Use the modulator from channel 7 for the tom tom. + output_levels_[1] = output_levels_[14] = + (channels_[7].update_tom_tom(oscillator_, &operators_[34], depth_rhythm_control_ & 0x04) * total_volume_) >> 12; + // TODO: snare. output_levels_[6] = output_levels_[16] = 0; - // TODO: tom tom. - output_levels_[1] = output_levels_[14] = 0; - // TODO: cymbal. output_levels_[7] = output_levels_[17] = 0; @@ -229,9 +232,9 @@ void OPLL::update_all_chanels() { output_levels_[0] = output_levels_[13] = 0; } else { // Not in rhythm mode; channels 7, 8 and 9 are melodic. - for(int c = 7; c < 9; ++ c) { - channel_levels[c] = (channels_[c].update_melodic(oscillator_) * total_volume_) >> 12; - } +// for(int c = 7; c < 9; ++ c) { +// channel_levels[c] = (channels_[c].update_melodic(oscillator_) * total_volume_) >> 12; +// } output_levels_[0] = output_levels_[1] = output_levels_[2] = output_levels_[6] = output_levels_[7] = output_levels_[8] = @@ -244,7 +247,10 @@ void OPLL::update_all_chanels() { // Test! // for(int c = 0; c < 18; ++c) { -// if(c != 2 && c != 15) output_levels_[c] = 0; +//// if(c != 1 && c != 14 && c != 2 && c != 15) +//// output_levels_[c] = 0; +// if(c != 1 && c != 14) +// output_levels_[c] = 0; // } // channels_[2].level = (channels_[2].update() * total_volume_) >> 14; diff --git a/Components/OPL2/OPL2.hpp b/Components/OPL2/OPL2.hpp index 7dbd7d7fd..14a8420e5 100644 --- a/Components/OPL2/OPL2.hpp +++ b/Components/OPL2/OPL2.hpp @@ -103,6 +103,11 @@ struct OPLL: public OPLBase { return Yamaha::OPL::Channel::update_melodic(oscillator, bass, bass + 1, key_on, nullptr, &overrides); } + int update_tom_tom(const LowFrequencyOscillator &oscillator, Operator *bass, bool key_on) { + // TODO: should overrides be applied here? + return Yamaha::OPL::Channel::update_tom_tom(oscillator, bass, key_on, &overrides); + } + bool is_audible() { return Yamaha::OPL::Channel::is_audible(modulator + 1, &overrides); }