tempoSyncedLFO

Tempo Synced LFO with multiple waveforms out Automatically syncs tempo to the incoming clock on sync-input. Tempo can be multiplied and divided by integers to keep a tight ratio and can also be shifted up/down up to 8 octaves. phase controls all the waveforms (there is only one phase actually) PW only controls pulsewidth of the pulse waveform (not bandlimited) when syncReset is on, LFO will be synced to phase position set by phase parameter and phase input at regular intervals. A trigger at the "reverse" input will reverse the play direction. Another click will revert it back to normal play direction. Reset will hard-reset the phase of the LFO
Author: Remco van der Most
License: BSD
Github: sss/lfo/tempoSyncedLFO.axo

Inlets

int32.positive divide

int32.bipolar octave

frac32 phase

frac32 PW

bool32.rising sync

bool32.rising reverse

bool32.rising reset

int32 multiply

Outlets

frac32 sine

frac32 cosine

frac32 triangle

frac32 cotriangle

frac32 saw

frac32 ramp

frac32 square

frac32 pulse

Parameters

int32 multiply

int32 divide

int32 octave

frac32.u.map phase

frac32.s.map PW

bool32.tgl syncRst

Declaration
uint64_t timer;
uint64_t held;
uint64_t hold;
int ttrig;
int rtrig;
int strig;
int64_t phase;
int32_t count;
int64_t dovide;
int32_t moltiply;
int8_t reverse;
Init
reverse = 1;
Control Rate
int32_t multiply = inlet_multiply + param_multiply;
int32_t divide = inlet_divide + param_divide;
int32_t octave = inlet_octave + param_octave;
int32_t pulse = ((inlet_PW + param_PW) << 5) >> 5;
if ((inlet_reverse > 0) && !strig) {
  strig = 1;
  reverse = reverse > 0 ? 0 : 1;
} else if (inlet_reverse <= 0) {
  strig = 0;
}

if ((inlet_reset > 0) && !rtrig) {
  rtrig = 1;
  phase = 0;
} else if (inlet_reset <= 0) {
  rtrig = 0;
}

if ((inlet_sync > 0) && !ttrig) {
  ttrig = 1;
  held = timer;
  count += 1;
  timer = 0;
  if ((count >= dovide) && param_syncRst) {
    phase = 0;

    count = 0;
  }
} else if (inlet_sync < 1) {
  ttrig = 0;
}
timer += 1;
dovide = divide << (-octave < 0 ? 0 : -octave);
moltiply = multiply << (octave > 0 ? octave : 0);
if (reverse > 0) {
  phase += 1 * moltiply;
  phase = phase - (phase / (held * dovide)) * (held * dovide);
} else {
  phase -= 1 * moltiply;
  phase = phase == 0 ? held * dovide - 1 : phase;
}

hold = ((phase) << 32) / (held * dovide);
int32_t sine;
int32_t cosine;
int32_t Phase = inlet_phase + param_phase;
SINE2TINTERP(hold + (Phase << 5), sine)
SINE2TINTERP(hold + (Phase << 5) + (1 << 30), cosine)
outlet_sine = sine >> 4;
outlet_cosine = cosine >> 4;
int32_t hald = (((hold + (1 << 30)) >> 3) + (Phase << 2)) & ((1 << 29) - 1);
hold = ((hold >> 3) + (Phase << 2)) & ((1 << 29) - 1);
outlet_triangle = ((hald > (1 << 28) ? (2 << 28) - hald : hald) - (1 << 27));
outlet_cotriangle = -((hold > (1 << 28) ? (2 << 28) - hold : hold) - (1 << 27));
outlet_saw = (hold >> 1) - (1 << 27);
outlet_ramp = -outlet_saw;
outlet_square = outlet_sine > 0 ? (1 << 27) : -(1 << 27);
outlet_pulse = outlet_saw > pulse ? (1 << 27) : -(1 << 27);

Privacy

© 2024 Zrna Research