mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-13 07:30:21 +00:00
Adds vibrato.
This would complete melodic output, subject to bug fixes.
This commit is contained in:
parent
9e3614066a
commit
983c32bf75
@ -7,3 +7,22 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "LowFrequencyOscillator.hpp"
|
#include "LowFrequencyOscillator.hpp"
|
||||||
|
|
||||||
|
using namespace Yamaha::OPL;
|
||||||
|
|
||||||
|
void LowFrequencyOscillator::update() {
|
||||||
|
++counter;
|
||||||
|
|
||||||
|
// This produces output of:
|
||||||
|
//
|
||||||
|
// four instances of 0, four instances of 1... _three_ instances of 26,
|
||||||
|
// four instances of 25, four instances of 24... _three_ instances of 0.
|
||||||
|
//
|
||||||
|
// ... advancing once every 64th update.
|
||||||
|
const int tremolo_index = (counter >> 6) % 210;
|
||||||
|
const int tremolo_levels[2] = {tremolo_index >> 2, 52 - ((tremolo_index+1) >> 2)};
|
||||||
|
tremolo = tremolo_levels[tremolo_index / 107];
|
||||||
|
|
||||||
|
// Vibrato is relatively simple: it's just three bits from the counter.
|
||||||
|
vibrato = (counter >> 10) & 7;
|
||||||
|
}
|
||||||
|
@ -21,31 +21,14 @@ class LowFrequencyOscillator {
|
|||||||
public:
|
public:
|
||||||
/// Current attenuation due to tremolo / amplitude modulation, between 0 and 26.
|
/// Current attenuation due to tremolo / amplitude modulation, between 0 and 26.
|
||||||
int tremolo = 0;
|
int tremolo = 0;
|
||||||
/// TODO
|
/// A number between 0 and 7 indicating the current vibrato offset; this should be combined by operators
|
||||||
|
/// with their frequency number to get the actual vibrato.
|
||||||
int vibrato = 0;
|
int vibrato = 0;
|
||||||
/// A counter of the number of operator update cycles (i.e. input clock / 72) since an arbitrary time.
|
/// A counter of the number of operator update cycles (i.e. input clock / 72) since an arbitrary time.
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
|
|
||||||
/// Updates the oscillator outputs
|
/// Updates the oscillator outputs
|
||||||
void update() {
|
void update();
|
||||||
++counter;
|
|
||||||
|
|
||||||
// Update tremolo.
|
|
||||||
++tremolo_phase_;
|
|
||||||
|
|
||||||
// This produces output of:
|
|
||||||
//
|
|
||||||
// four instances of 0, four instances of 1... _three_ instances of 26,
|
|
||||||
// four instances of 25, four instances of 24... _three_ instances of 0.
|
|
||||||
//
|
|
||||||
// ... advancing once every 64th update.
|
|
||||||
const int tremolo_index = (tremolo_phase_ >> 6) % 210;
|
|
||||||
const int tremolo_levels[2] = {tremolo_index >> 2, 52 - ((tremolo_index+1) >> 2)};
|
|
||||||
tremolo = tremolo_levels[tremolo_index / 107];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int tremolo_phase_ = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -81,11 +81,16 @@ void Operator::update(
|
|||||||
constexpr int multipliers[] = {
|
constexpr int multipliers[] = {
|
||||||
1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 24, 24, 30, 30
|
1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 24, 24, 30, 30
|
||||||
};
|
};
|
||||||
|
const int top_freq = channel_period >> 7;
|
||||||
|
assert(top_freq < 8);
|
||||||
|
constexpr int vibrato_shifts[8] = {3, 1, 0, 1, 3, 1, 0, 1};
|
||||||
|
constexpr int vibrato_signs[2] = {1, -1};
|
||||||
|
const int vibrato = (top_freq >> vibrato_shifts[oscillator.vibrato]) * vibrato_signs[oscillator.vibrato >> 2] * int(apply_vibrato_);
|
||||||
|
|
||||||
// Update the raw phase.
|
// Update the raw phase.
|
||||||
state.raw_phase_ += multipliers[frequency_multiple_] * channel_period << channel_octave;
|
state.raw_phase_ += multipliers[frequency_multiple_] * (channel_period + vibrato) << channel_octave;
|
||||||
|
|
||||||
// Hence calculate phase (TODO: by also taking account of vibrato).
|
// Hence calculate phase.
|
||||||
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.
|
||||||
{511, 511, 0, 0}, // Half sine: keep the first half intact, lock to 0 in the second half.
|
{511, 511, 0, 0}, // Half sine: keep the first half intact, lock to 0 in the second half.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user