1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-25 18:30:21 +00:00

Adds vibrato.

This would complete melodic output, subject to bug fixes.
This commit is contained in:
Thomas Harte 2020-04-24 18:02:41 -04:00
parent 9e3614066a
commit 983c32bf75
3 changed files with 29 additions and 22 deletions

View File

@ -7,3 +7,22 @@
//
#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;
}

View File

@ -21,31 +21,14 @@ class LowFrequencyOscillator {
public:
/// Current attenuation due to tremolo / amplitude modulation, between 0 and 26.
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;
/// A counter of the number of operator update cycles (i.e. input clock / 72) since an arbitrary time.
int counter = 0;
/// Updates the oscillator outputs
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;
void update();
};
}

View File

@ -81,11 +81,16 @@ void Operator::update(
constexpr int multipliers[] = {
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.
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] = {
{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.