mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-23 03:32:32 +00:00
With some fixes for scale, I think possibly this is close for melodic channels.
This commit is contained in:
parent
a7e63b61eb
commit
30ff399218
@ -403,10 +403,14 @@ void Operator::update(OperatorState &state, bool key_on, int channel_period, int
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Update the raw phase.
|
// Update the raw phase.
|
||||||
|
// TODO: if this is the real formula (i.e. a downward shift for channel_octave), this is a highly
|
||||||
|
// suboptimal way to do this. Could just keep one accumulator and shift that downward for the result.
|
||||||
const int octave_divider = 2048 >> channel_octave;
|
const int octave_divider = 2048 >> channel_octave;
|
||||||
state.divider_ %= octave_divider;
|
state.divider_ %= octave_divider;
|
||||||
state.divider_ += multipliers[frequency_multiple] * channel_period;
|
state.divider_ += channel_period;
|
||||||
state.raw_phase_ += state.divider_ / octave_divider;
|
state.raw_phase_ += multipliers[frequency_multiple] * (state.divider_ / octave_divider);
|
||||||
|
// TODO: this last step introduces aliasing, but is a quick way to verify whether the multiplier should
|
||||||
|
// be applied also to the octave.
|
||||||
|
|
||||||
// Hence calculate phase (TODO: by also taking account of vibrato).
|
// Hence calculate phase (TODO: by also taking account of vibrato).
|
||||||
constexpr int waveforms[4][4] = {
|
constexpr int waveforms[4][4] = {
|
||||||
@ -512,9 +516,9 @@ void Operator::update(OperatorState &state, bool key_on, int channel_period, int
|
|||||||
|
|
||||||
// Combine the ADSR attenuation and overall channel attenuation, clamping to the permitted range.
|
// Combine the ADSR attenuation and overall channel attenuation, clamping to the permitted range.
|
||||||
if(overrides) {
|
if(overrides) {
|
||||||
state.attenuation = state.adsr_attenuation_ + (overrides->attenuation << 6);
|
state.attenuation = state.adsr_attenuation_ + (overrides->attenuation << 4);
|
||||||
} else {
|
} else {
|
||||||
state.attenuation = state.adsr_attenuation_ + (attenuation_ << 3);
|
state.attenuation = state.adsr_attenuation_ + (attenuation_ << 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ class Operator {
|
|||||||
|
|
||||||
/// Sets this operator's waveform using the low two bits of @c value.
|
/// Sets this operator's waveform using the low two bits of @c value.
|
||||||
void set_waveform(uint8_t value) {
|
void set_waveform(uint8_t value) {
|
||||||
// waveform = Operator::Waveform(value & 3);
|
waveform = Operator::Waveform(value & 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// From the top nibble of @c value sets the AM, vibrato, hold/sustain level and keyboard sampling rate flags;
|
/// From the top nibble of @c value sets the AM, vibrato, hold/sustain level and keyboard sampling rate flags;
|
||||||
@ -204,7 +204,7 @@ class Channel {
|
|||||||
|
|
||||||
// TODO: almost everything. This is a quick test.
|
// TODO: almost everything. This is a quick test.
|
||||||
// Specifically: use lookup tables.
|
// Specifically: use lookup tables.
|
||||||
const auto modulator_level = 0.0f;//level(modulator_state_, 0.0f) * 0.25f;
|
const auto modulator_level = level(modulator_state_, 0.0f); // TODO: what's the proper scaling on this?
|
||||||
return int(level(carrier_state_, modulator_level) * 20'000.0f);
|
return int(level(carrier_state_, modulator_level) * 20'000.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,7 +218,9 @@ class Channel {
|
|||||||
const float phase = modulator_level + float(state.phase) / 1024.0f;
|
const float phase = modulator_level + float(state.phase) / 1024.0f;
|
||||||
const float phase_attenuation = logf(1.0f + sinf(float(M_PI) * 2.0f * phase));
|
const float phase_attenuation = logf(1.0f + sinf(float(M_PI) * 2.0f * phase));
|
||||||
const float total_attenuation = phase_attenuation + float(state.attenuation) / 1023.0f;
|
const float total_attenuation = phase_attenuation + float(state.attenuation) / 1023.0f;
|
||||||
return expf(total_attenuation);
|
const float result = expf(total_attenuation / 2.0f);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 'F-Num' in the spec; this plus the current octave determines channel frequency.
|
/// 'F-Num' in the spec; this plus the current octave determines channel frequency.
|
||||||
@ -334,10 +336,10 @@ struct OPLL: public OPLBase<OPLL> {
|
|||||||
int level = 0;
|
int level = 0;
|
||||||
};
|
};
|
||||||
void update_all_chanels() {
|
void update_all_chanels() {
|
||||||
// for(int c = 0; c < 6; ++ c) { // Don't do anything with channels that might be percussion for now.
|
for(int c = 0; c < 6; ++ c) { // Don't do anything with channels that might be percussion for now.
|
||||||
// channels_[c].level = (channels_[c].update() * total_volume_) >> 14;
|
channels_[c].level = (channels_[c].update() * total_volume_) >> 14;
|
||||||
// }
|
}
|
||||||
channels_[0].level = (channels_[0].update() * total_volume_) >> 14;
|
channels_[2].level = (channels_[2].update() * total_volume_) >> 14;
|
||||||
}
|
}
|
||||||
Channel channels_[9];
|
Channel channels_[9];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user