mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Attempts to add the missing noise generators. I think I may still be astray on volumes.
This commit is contained in:
parent
2bc36a6cde
commit
9f0c8bcae7
@ -245,7 +245,10 @@ void Operator::update(
|
|||||||
|
|
||||||
// MARK: - Output Generators.
|
// MARK: - Output Generators.
|
||||||
|
|
||||||
LogSign Operator::melodic_output(OperatorState &state, const LogSign *phase_offset) {
|
// A heavy debt is owed to https://github.com/andete/ym2413/blob/master/results/rhythm/rhythm.md regarding
|
||||||
|
// the drum sound generation below.
|
||||||
|
|
||||||
|
LogSign Operator::melodic_output(const OperatorState &state, const LogSign *phase_offset) {
|
||||||
// Calculate raw attenuation level.
|
// Calculate raw attenuation level.
|
||||||
constexpr int waveforms[4][4] = {
|
constexpr int waveforms[4][4] = {
|
||||||
{1023, 1023, 1023, 1023}, // Sine: don't mask in any quadrant.
|
{1023, 1023, 1023, 1023}, // Sine: don't mask in any quadrant.
|
||||||
@ -262,33 +265,44 @@ LogSign Operator::melodic_output(OperatorState &state, const LogSign *phase_offs
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogSign Operator::snare_output(OperatorState &state) {
|
LogSign Operator::snare_output(const OperatorState &state) {
|
||||||
LogSign result;
|
LogSign result;
|
||||||
|
|
||||||
// If noise is 0, output is positive.
|
// If noise is 0, output is positive.
|
||||||
// If noise is 1, output is negative.
|
// If noise is 1, output is negative.
|
||||||
// If (noise ^ sign) is 0, output is 0. Otherwise it is max.
|
// If (noise ^ sign) is 0, output is 0. Otherwise it is max.
|
||||||
// const int angle = ((state.lfsr_ << 10) ^ (state.raw_phase_ >> 12)) & 0x100;
|
|
||||||
//
|
|
||||||
// result = negative_log_sin((state.raw_phase_ >> 11) &;
|
|
||||||
// constexpr int masks[] = {~0, 0};
|
|
||||||
// result += masks[state.lfsr_
|
|
||||||
|
|
||||||
const int sign = (state.raw_phase_ >> 11) & 0x200;
|
const int sign = (state.raw_phase_ >> 11) & 0x200;
|
||||||
const int level = ((state.raw_phase_ >> 20) & 1) ^ state.lfsr_;
|
const int level = ((state.raw_phase_ >> 20) & 1) ^ state.lfsr_;
|
||||||
result = negative_log_sin(sign + (level << 8));
|
result = negative_log_sin(sign + (level << 8));
|
||||||
|
|
||||||
// if((state.raw_phase_ >> 11) & 0x200) {
|
result += state.key_level_scaling_;
|
||||||
// // Result is -max if LFSR is 0, otherwise -0.
|
result += state.channel_adsr_attenuation_;
|
||||||
// result = negative_log_sin(512 + ((state.lfsr_^1) << 8));
|
return result;
|
||||||
// } else {
|
}
|
||||||
// // Result is +max if LFSR is 1, otherwise +0.
|
|
||||||
// result = negative_log_sin(state.lfsr_ << 8);
|
LogSign Operator::cymbal_output(const OperatorState &state, const OperatorState &modulator) {
|
||||||
// }
|
const int output =
|
||||||
|
((state.raw_phase_ >> 16) ^ (state.raw_phase_ >> 14)) &
|
||||||
|
((modulator.raw_phase_ >> 18) ^ (modulator.raw_phase_ >> 13)) &
|
||||||
// printf("%d %d: %d/%d\n", state.lfsr_, (state.raw_phase_ >> 11) & 1023, result.log, result.sign);
|
((state.raw_phase_ >> 16) ^ (modulator.raw_phase_ >> 14));
|
||||||
|
|
||||||
|
constexpr int angles[] = {256, 768};
|
||||||
|
LogSign result = negative_log_sin(angles[output & 1]);
|
||||||
|
|
||||||
|
result += state.key_level_scaling_;
|
||||||
|
result += state.channel_adsr_attenuation_;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogSign Operator::high_hat_output(const OperatorState &state, const OperatorState &modulator) {
|
||||||
|
const int output =
|
||||||
|
((state.raw_phase_ >> 16) ^ (state.raw_phase_ >> 14)) &
|
||||||
|
((modulator.raw_phase_ >> 18) ^ (modulator.raw_phase_ >> 13)) &
|
||||||
|
((state.raw_phase_ >> 16) ^ (modulator.raw_phase_ >> 14));
|
||||||
|
|
||||||
|
constexpr int angles[] = {0x234, 0xd0, 0x2d0, 0x34};
|
||||||
|
LogSign result = negative_log_sin(angles[(output & 1) | (state.lfsr_ << 1)]);
|
||||||
|
|
||||||
result += state.key_level_scaling_;
|
result += state.key_level_scaling_;
|
||||||
result += state.channel_adsr_attenuation_;
|
result += state.channel_adsr_attenuation_;
|
||||||
return result;
|
return result;
|
||||||
|
@ -94,8 +94,19 @@ class Operator {
|
|||||||
/// @returns @c true if this channel currently has a non-zero output; @c false otherwise.
|
/// @returns @c true if this channel currently has a non-zero output; @c false otherwise.
|
||||||
bool is_audible(OperatorState &state, OperatorOverrides *overrides = nullptr);
|
bool is_audible(OperatorState &state, OperatorOverrides *overrides = nullptr);
|
||||||
|
|
||||||
LogSign melodic_output(OperatorState &state, const LogSign *phase_offset = nullptr);
|
/// Provides ordinary melodic output, optionally with modulation.
|
||||||
LogSign snare_output(OperatorState &state);
|
LogSign melodic_output(const OperatorState &state, const LogSign *phase_offset = nullptr);
|
||||||
|
|
||||||
|
/// Provides snare drum output, which is a function of phase and the captured LFSR level.
|
||||||
|
LogSign snare_output(const OperatorState &state);
|
||||||
|
|
||||||
|
/// Provides cymbal output, which is a function of the phase given by @c state, ordinarily the carrier of channel 8,
|
||||||
|
/// and the phase of @c modulator, which is ordinarily the modulator of channel 7.
|
||||||
|
LogSign cymbal_output(const OperatorState &state, const OperatorState &modulator);
|
||||||
|
|
||||||
|
/// Provides high-hat output, which is a function of the phase given by @c state, ordinarily the carrier of channel 8,
|
||||||
|
/// and the phase of @c modulator, which is ordinarily the modulator of channel 7.
|
||||||
|
LogSign high_hat_output(const OperatorState &state, const OperatorState &modulator);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// If true then an amplitude modulation of "3.7Hz" is applied,
|
/// If true then an amplitude modulation of "3.7Hz" is applied,
|
||||||
|
Loading…
Reference in New Issue
Block a user