Skip to content

Commit

Permalink
Ebb&LFO: Make clocked mode work with reset and oneshot
Browse files Browse the repository at this point in the history
  • Loading branch information
qiemem committed Sep 4, 2024
1 parent f217584 commit b79d04b
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 13 deletions.
23 changes: 15 additions & 8 deletions software/src/applets/EbbAndLfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,20 @@ class EbbAndLfo : public HemisphereApplet {
if (knob_accel > (1 << 8))
knob_accel--;

if (Clock(1)) { // reset/retrigger
bool reset = Clock(1);
if (reset) { // reset/retrigger
phase = 0;
oneshot_active = true;
}

int freq_div_mul = ratio;
pitch_mod = pitch;
bool got_clock = Clock(0);
oneshot_active |= got_clock;

// In clocked mode, Clock(0) is just used to set rate. In unclocked, it will
// start a oneshot but not restart it.
if (!clocked)
oneshot_active |= got_clock;

// handle CV inputs
slope_mod = slope * (65535 / 127);
Expand Down Expand Up @@ -74,16 +79,17 @@ class EbbAndLfo : public HemisphereApplet {

// TODO: Make oneshot and clocked mode more compatible so you can trigger a
// shot with one trig and have it synced to clock on the other trig.
if (oneshot_mode && !oneshot_active)
return;

uint32_t oldphase = phase;
if (clocked) {
phase = phase_extractor.Advance(got_clock, freq_div_mul);
phase = phase_extractor.Advance(got_clock, reset, freq_div_mul);
} else {
uint32_t phase_increment = ComputePhaseIncrement(pitch_mod);
phase += phase_increment;
}
if (oneshot_mode && !oneshot_active) {
phase = 0;
return;
}

// check for rollover and stop for one-shot mode
if (phase < oldphase && oneshot_mode) {
Expand Down Expand Up @@ -150,10 +156,11 @@ class EbbAndLfo : public HemisphereApplet {
if (i > 0)
gfxLine(i - 1, last, i, next);
last = next;
// gfxPixel(i, 50 - disp_sample.unipolar * 35 / 65536);
}
}
uint32_t p = phase / (0xffffffff / 64);

// position is first 6 bits of phase, which gives 0 through 63.
uint32_t p = phase >> 26;
gfxLine(p, 15, p, 50);

const int param_y = 55;
Expand Down
23 changes: 18 additions & 5 deletions software/src/util/util_phase_extractor.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,21 @@ class PhaseExtractor {
}

// -2 => /3, -1 => /2, 0 => 1, 1 => x2, 2 => x3, etc
uint32_t Advance(bool clock, int simple_ratio) {
return Advance(clock, {static_cast<int16_t>(max(simple_ratio + 1, 1)),
static_cast<uint16_t>(max(-simple_ratio + 1, 1))});
uint32_t Advance(bool clock, bool reset, int simple_ratio) {
return Advance(clock, reset,
{static_cast<int16_t>(max(simple_ratio + 1, 1)),
static_cast<uint16_t>(max(-simple_ratio + 1, 1))});
}

uint32_t Advance(bool clock, Ratio r) {
uint32_t Advance(bool clock, bool reset, Ratio r) {
if (reset) {
// TODO: should offset phase as well. This will support oneshot mode too.
clocks_received = ratio.den - 1;
// phase_offset = -phase;
phase = 0;
phase_offset = 0;
set_offset = true;
}
if (clock) {
next_clock_tick = predictor.Predict(ticks);
ticks = 0;
Expand All @@ -35,6 +44,8 @@ class PhaseExtractor {
// discontinuities in the phase
clocks_received = 0;
ratio = r;
if (set_offset) phase_offset = phase;
set_offset = false;
phase = 0;
}
phase_inc = 0xffffffff / (ratio.den * next_clock_tick) * ratio.num;
Expand All @@ -51,7 +62,7 @@ class PhaseExtractor {
else if (phase_inc < 0 && phase >= static_cast<uint32_t>(phase_inc))
phase = 0;
}
return phase;
return phase + phase_offset;
}

private:
Expand All @@ -62,4 +73,6 @@ class PhaseExtractor {
uint32_t ticks;
uint32_t phase;
int32_t phase_inc;
uint32_t phase_offset;
bool set_offset = false;
};

0 comments on commit b79d04b

Please sign in to comment.