lfoCORE

This is the "core" module for the "lfoSLAVE" module. This module contains the code, that the "lfoSLAVE" uses to calculate the LFO waveform and also calculates base/host frequency based on the "HS" trigger input. You only need this module once. The lfoSLAVE can be copied or it's code can be used in other modules. Just connect a trigger source to the input of this module to set root-rate. This way the code for all the different waveforms only has to be written once, saving memory when using multiple lfoSLAVEs. different waveforms: 0=sine 1=triangle 2=peak 3=saw 4=dip saw 5=shark saw 6=ramp 7=dip ramp 8=shark ramp 9= hump 10=dip 11=square 12=bipolar saw 13=bipolar ramp 14=collapsed sine 15=collapsed triangle
Author: Remco van der Most
License: BSD
Github: sss/lfo/lfoCORE.axo

Inlets

frac32 feed a LFO trigger/continuous signal to clock-sync the LFO.

Outlets

frac32 outputs "base frequency" detected on HS input for use with other modules

Declaration
uint32_t Phase;
uint32_t PHS;
int32_t sine;
float32_t A[4];
// int32_t p;
int S;
int ttrig;
uint32_t count;
uint32_t timer;
int32_t rate;
int i;
int rtrig;
int32_t out;
int32_t TRG;
uint32_t BASE;
int32_t SIN(uint32_t P1) {
  int32_t si;
  SINE2TINTERP(P1 - (1 << 30), si)
  return sine = si >> 4;
}
int32_t TRI(uint32_t P1) {
  int32_t temp = P1;
  temp = temp >= 0 ? temp : -temp;
  return sine = (temp - (1 << 30)) >> 3;
}
int32_t PEK(uint32_t P1) {
  uint32_t si = (uint32_t)(-(P1 >> 30)) << 31;
  SINE2TINTERP(P1 + si + (3 << 30), si)
  return sine = (si >> 4) - (1 << 27);
}
int32_t SAW(int32_t P1) { return sine = -P1 >> 4; }
int32_t RMP(int32_t P1) { return sine = P1 >> 4; }
int32_t SQR(int32_t P1) { return sine = P1 >= 0 ? (1 << 27) : -(1 << 27); }
int32_t HMP(uint32_t P1) {
  int32_t si;
  SINE2TINTERP(P1 >> 1, si)
  return sine = (si >> 3) - (1 << 27);
}
int32_t DIP(uint32_t P1) {
  int32_t si;
  SINE2TINTERP(P1 >> 1, si)
  return sine = (-si >> 3) + (1 << 27);
}
int32_t QS1(uint32_t P1) {
  int32_t si;
  SINE2TINTERP(P1 >> 2, si)
  return sine = (-si >> 3) + (1 << 27);
}
int32_t QS4(uint32_t P1) {
  int32_t si;
  SINE2TINTERP((P1 >> 2) + (1 << 30), si)
  return sine = (-si >> 3) + (1 << 27);
}
int32_t QS3(uint32_t P1) {
  int32_t si;
  SINE2TINTERP((P1 >> 2) + (2 << 30), si)
  return sine = (-si >> 3) - (1 << 27);
}
int32_t QS2(uint32_t P1) {
  int32_t si;
  SINE2TINTERP((-P1 >> 2) + (2 << 30), si)
  return sine = ((-si >> 3) - (1 << 27));
}
int32_t DSW(uint32_t P1) {
  uint32_t si = P1 > (1 << 31) ? (1 << 31) - P1 : P1;
  return sine = (si >> 4) - (1 << 27);
}
int32_t DRP(uint32_t P1) {
  P1 = -P1;
  uint32_t si = P1 > (1 << 31) ? (1 << 31) - P1 : P1;
  return sine = (si >> 4) - (1 << 27);
}
int32_t ISN(uint32_t P1) {
  int32_t si;
  SINE2TINTERP(P1, si)
  si = si >> 1;
  return sine = ((si > 0 ? si - (1 < 30) : si + (1 << 30)) >> 2) - (1 << 27);
}
int32_t ITR(uint32_t P1) {
  int32_t temp = P1;
  temp = temp >= 0 ? temp : -temp;
  temp = (temp - (1 << 30)) >> 3;
  return sine = temp > 0 ? (temp << 1) - (1 << 27) : (temp << 1) + (1 << 27);
}
int32_t mode(int mode) {
  switch (mode) {
  case 0:
    out = SIN(Phase);
    break;
  case 1:
    out = TRI(Phase);
    break;
  case 2:
    out = PEK(Phase);
    break;
  case 3:
    out = SAW(Phase);
    break;
  case 4:
    out = QS1(Phase);
    break;
  case 5:
    out = QS2(Phase);
    break;
  case 6:
    out = RMP(Phase);
    break;
  case 7:
    out = QS3(Phase);
    break;
  case 8:
    out = QS4(Phase);
    break;
  case 9:
    out = HMP(Phase);
    break;
  case 10:
    out = DIP(Phase);
    break;
  case 11:
    out = SQR(Phase);
    break;
  case 12:
    out = DSW(Phase);
    break;
  case 13:
    out = DRP(Phase);
    break;
  case 14:
    out = ISN(Phase);
    break;
  case 15:
    out = ITR(Phase);
    break;
  }
}

int32_t LFO(uint32_t phase, int32_t poff, int32_t R, int32_t snc, int32_t RATE,
            int Div, int32_t slope, int32_t wave, int32_t prec, int32_t STEP,
            bool RTRG) {
  rtrig = RTRG;
  if ((R > 0) && (snc > 0) && !rtrig) {
    rtrig = 1;
    phase = 0;
  } else if (R <= 0) {
    rtrig = 0;
  }

  S = (wave)&15;
  int32_t tmp = RATE >> 22;
  int sel;
  sel = tmp & 3;
  int oct = tmp - sel >> 2;

  prec = prec & ((1 << 28) - 1);
  prec = prec > (1 << 27) ? (1 << 28) - prec : prec;
  rate = BASE * A[sel];
  if (oct > 0) {
    rate = rate << oct;
  } else {
    rate = rate >> -oct;
  }
  int32_t trg = (phase >> 1) + (rate / Div >> 1);
  trg = trg > 0 ? trg : -trg;
  TRG = trg > (1 << 30) ? 1 : 0;
  phase += rate / Div;
  Phase = (((phase >> 1) > (1 << 30)
                ? ___SMMUL((uint32_t)(1 << 31) - (phase >> 1), slope << 1)
                : ___SMMUL(phase >> 1, slope << 1))
           << 7) +
          phase - (0 << 30) + poff;
  int32_t qnt = 1 << (prec >> 22);
  Phase = Phase / qnt * qnt;
  Phase += ___SMMUL(Phase, STEP) << 3;
  mode(S);
  PHS = phase;
};
Init
timer = (1 << 31);
count = (1 << 31);
A[0] = 1;
A[1] = (float32_t)5 / 4; //(float32_t)9/8; etc for other divisions
A[2] = (float32_t)4 / 3;
A[3] = (float32_t)3 / 2;
Control Rate
BASE = (float32_t)(1 << 29) / timer * 8;
Audio Rate
if ((inlet_HS > 0) && (!(ttrig))) {
  ttrig = 1;
  timer = count;
  count = 0;
} else if (!(inlet_HS > 0)) {
  ttrig = 0;
}
count += 1;

Privacy

© 2024 Zrna Research