blepped4

triangle oscillator Bandwith limited
Author: Johannes Taelman
License: BSD
Github: sss/osc/blepped4.axo

Inlets

frac32.bipolar pitch

frac32.bipolar softsync

frac32buffer mod

frac32buffer sync

frac32buffer reverse

int32 hrm

int32 div

int32 oct

int32 wave

frac32 self

Outlets

frac32buffer.bipolar triangle wave, anti-aliased

Parameters

bool32.tgl reverse

frac32.s.map.pitch pitch

frac32.s.map.pitch softsync

frac32.s.map mod

frac32.s.map self

int32 wave

Declaration
uint32_t osc_p;
int32_t Osc_p;
uint32_t osc_r;
int32_t Osc_r;
bool strg;
uint32_t sync;
int32_t Sync;
int32_t pwmp;
int32_t hp;
int32_t bufmsk = BUFSIZE - 1;
static const int blepvoices = 8;
const int16_t *oscp[blepvoices];
int16_t *Oscp[blepvoices];
int16_t amp[blepvoices];
uint32_t nextvoice;
int32_t vgain[blepvoices];
int32_t i0;
int32_t x;
int hrm;
int Div;
int oct;
uint32_t max = (-1 << 31) + 1;

bool RV;
int32_t rev[BUFSIZE];
int32_t SNC[BUFSIZE];
int32_t in[BUFSIZE];
int32_t out[BUFSIZE];
int i;
uint32_t damp;
uint32_t v31 = (uint32_t)(1 << 30);
int32_t v13 = (1 << 13) - 1;
int32_t SIN(int32_t pitch, int32_t fm, int32_t self) {
  uint32_t freq;
  MTOFEXTENDED(pitch, freq);
  freq = freq / Div * hrm;
  freq = oct > 0 ? freq << oct : freq >> -oct;
  int32_t FM;
  int32_t fM = ___SMMUL(fm << 4, freq);
  int32_t sM = ___SMMUL(self << 4, freq);
  int j;
  for (j = 0; j < BUFSIZE; j++) {
    FM =
        ___SMMUL(in[j] << 3, fM << 2) + ___SMMUL(out[(j - 1) & bufmsk] << 3, sM)
        << 3;
    uint32_t tfreq = freq + FM;
    tfreq = rev[j] > 0 ? tfreq : -tfreq;
    sync -= ___SMMUL(sync, damp) << 1;
    if ((SNC[j] > 0) && !strg) {
      strg = 1;
      sync += Osc_p;
      Osc_p = 0;
    } else if (SNC[j] <= 0) {
      strg = 0;
    }
    Osc_p += tfreq;
    int32_t sine;
    SINE2TINTERP(Osc_p + sync, sine)
    out[j] = sine >> 5;
  }
}
int32_t TRI(int32_t pitch, int32_t fm, int32_t self) {
  int32_t freq;
  MTOFEXTENDED(pitch, freq);
  freq = freq / Div * hrm;
  freq = oct > 0 ? freq << oct : freq >> -oct;
  int32_t FM;
  int32_t fM = ___SMMUL(fm << 4, freq);
  int32_t sM = ___SMMUL(self << 4, freq);
  int j;
  const int16_t *lastblep = &blt[BLEPSIZE - 1];
  for (j = 0; j < BUFSIZE; j++) {
    FM = ___SMMUL(in[j] << 3, fM) + ___SMMUL(out[(j - 1) & bufmsk] << 3, sM)
         << 5;
    int32_t tfreq = freq + FM;
    tfreq = rev[j] > 0 ? tfreq : -tfreq;

    int i;
    uint32_t p;
    p = osc_p;
    int32_t p3 = p - 2 * tfreq;
    int32_t tri;
    if (p3 > 0) {
      tri = ((1 << 30) - (p3)) >> 4;
    } else {
      tri = (p3 + (1 << 30)) >> 4;
    }
    Sync -= ___SMMUL(Sync, damp) << 1;
    if ((SNC[j] > 0) && !strg) {
      strg = 1;
      Sync += osc_r;
      osc_r = 0;
    } else if (SNC[j] <= 0) {
      strg = 0;
    }
    osc_r += tfreq;
    osc_p = (uint32_t)osc_r + Sync;
    if ((((int32_t)osc_p) > 0) ^ (((int32_t)p) > 0)) { // dispatch
      if ((freq >> 6) > 0) {
        nextvoice = (nextvoice + 1) & (blepvoices - 1);
        int32_t x = (osc_p & 0x7FFFFFFF) / (((uint32_t)tfreq) >> 6);
        x = x > 0 ? x : -x;
        x = x & v13;
        oscp[nextvoice] = &blt[x];
        amp[nextvoice] = (((int32_t)osc_p) < 0) ? tfreq >> 16 : -(tfreq >> 16);
      }
    }
    int32_t sum = 0;
    for (i = 0; i < blepvoices; i++) { // sample
      const int16_t *t = oscp[i];
      sum += (*t) * amp[i];
      t += 64;
      if (t >= lastblep)
        t = lastblep;
      oscp[i] = t;
    }
    out[j] = tri + (sum >> 3);
  }
};

int32_t SQR(int32_t pitch, int32_t fm, int32_t self) {
  int32_t freq;
  MTOFEXTENDED(pitch, freq);
  freq = freq / Div * hrm;
  freq = oct > 0 ? freq << oct : freq >> -oct;
  int32_t FM;
  int32_t fM = ___SMMUL(fm << 4, freq);
  int32_t sM = ___SMMUL(self << 4, freq);
  int j;
  int16_t *lastblep = &blept[BLEPSIZE - 1];
  for (j = 0; j < BUFSIZE; j++) {
    FM = ___SMMUL(in[j] << 3, fM) + ___SMMUL(out[(j - 1) & bufmsk] << 3, sM)
         << 3;
    uint32_t tfreq = freq + FM;
    tfreq = rev[j] > 0 ? tfreq : -tfreq;
    // tfreq=tfreq>0?tfreq:-tfreq-1;
    // tfreq=tfreq&((1<<30)-1);
    int i;
    int p;
    p = Osc_p;
    Sync -= ___SMMUL(Sync, damp) << 1;
    if ((SNC[j] > 0) && !strg) {
      strg = 1;
      Sync += Osc_r;
      Osc_r = 0;
    } else if (SNC[j] <= 0) {
      strg = 0;
    }
    Osc_r += (tfreq << 1);
    Osc_p = Osc_r + Sync;
    int32_t sum = 0;
    if ((Osc_p > 0) && !(p > 0)) { // dispatch
      nextvoice = (nextvoice + 1) & (blepvoices - 1);
      int32_t x = Osc_p / (tfreq >> 5);
      x = x > 0 ? x : -x;
      x = x & v13;
      Oscp[nextvoice] = &blept[x];
    }
    for (i = 0; i < blepvoices; i++) { // sample
      int16_t *t = Oscp[i];
      if (i & 1)
        sum += *t;
      else
        sum -= *t;
      t += 64;
      if (t >= lastblep)
        t = lastblep;
      Oscp[i] = t;
    }
    sum -= ((((nextvoice + 1) & 1) << 1) - 1) << 13;
    out[j] = sum << 13;
  }
}

int32_t SAW(int32_t pitch, int32_t fm, int32_t self) {
  int32_t freq;
  MTOFEXTENDED(pitch, freq);
  int32_t FM;
  int32_t fM = ___SMMUL(fm << 4, freq);
  int32_t sM = ___SMMUL(self << 4, freq);
  int j;
  int16_t *lastblep = &blept[BLEPSIZE - 1];
  for (j = 0; j < BUFSIZE; j++) {
    int i;
    int p;
    FM = ___SMMUL(in[j] << 3, fM) + ___SMMUL(out[(j - 1) & bufmsk] << 3, sM)
         << 3;
    uint32_t tfreq = freq + FM;
    // tfreq=tfreq>0?tfreq:-tfreq-1;
    tfreq += rev[j] > 0 ? tfreq : (uint32_t)(1 << 32) - tfreq;

    p = Osc_p;
    int32_t diff = ___SMMUL(Sync, damp) << 1;
    Sync -= diff;
    if ((SNC[j] > 0) && !strg) {
      strg = 1;
      Sync += Osc_r;
      Osc_r = 0;
    } else if (SNC[j] <= 0) {
      strg = 0;
    }
    Osc_r += tfreq;
    Osc_p = Osc_r + Sync;
    // int i1 = in[j]>>2;
    /*
    if ((i1>0)&&!(i0>0)){   // phase reset
      nextvoice = (nextvoice+1)&(blepvoices-1);
      int32_t x = 64-((-i0<<6)/(i1-i0));
      Oscp[nextvoice] = &blept[x];
      vgain[nextvoice] = vgain[nextvoice] = (((x * (tfreq>>7)) +
    (((uint32_t)p)>>1)))>>18; Osc_p = x * (tfreq>>6); } else
    */
    if ((Osc_p > 0) && !(p > 0)) { // dispatch
      nextvoice = (nextvoice + 1) & (blepvoices - 1);
      int32_t x = Osc_p / (tfreq - diff >> 6);
      x = x > 0 ? x : -x;
      if (x > v13) {
        x = 0;
      }
      Oscp[nextvoice] = &blept[x];
      vgain[nextvoice] = 1 << 13;
    }
    // i0 = i1;
    int32_t sum = 0;
    for (i = 0; i < blepvoices; i++) { // sample
      int16_t *t = Oscp[i];
      sum += (16384 - (*t)) * vgain[i];
      t += 64;
      if (t >= lastblep)
        t = lastblep;
      Oscp[i] = t;
    }
    // sum = -sum;
    uint32_t g = Osc_p;
    out[j] = (g >> 5) + sum - (1 << 26);
  }
}

int32_t PWM(int32_t pitch, int32_t pm, int32_t self) {
  uint32_t tfreq;
  MTOFEXTENDED(pitch, tfreq);
  tfreq = tfreq / Div * hrm;
  tfreq = oct > 0 ? tfreq << oct : tfreq >> -oct;
  int32_t sM = ___SMMUL(self << 4, tfreq);
  int j;
  int16_t *lastblep = &blept[BLEPSIZE - 1];
  for (j = 0; j < BUFSIZE; j++) {
    uint32_t freq = tfreq + (___SMMUL(out[(j - 1) & bufmsk] << 3, sM) << 3);
    freq = rev[j] > 0 ? freq : -freq;
    int32_t PWM = pm + in[j];
    int32_t TMO = __SSAT(PWM, 28);
    PWM = TMO + (TMO - PWM);
    int i;
    int p;
    p = Osc_p;
    Sync -= ___SMMUL(Sync, damp) << 1;
    if ((SNC[j] > 0) && !strg) {
      strg = 1;
      Sync += Osc_r;
      Osc_r = 0;
    } else if (SNC[j] <= 0) {
      strg = 0;
    }
    Osc_r += freq;
    Osc_p = Osc_r + Sync;
    int32_t sum = 0;
    if (((int32_t)Osc_p) >= ((int32_t)(Osc_p - pwmp))) {
      if ((Osc_p > 0) && !(p > 0)) { // dispatch
        nextvoice = (nextvoice + 1) & (blepvoices - 1);
        int32_t x = 0;
        if (freq >> 24)
          x = Osc_p / (freq >> 6);
        else if (freq)
          x = (Osc_p << 6) / freq;
        x = x > 0 ? x : -x;
        x = x & v13;
        Oscp[nextvoice] = &blept[x];
        pwmp = ((1 << 27) + PWM) << 4;
      }
      if (((Osc_p - pwmp) > 0) && !((p - pwmp) > 0)) { // dispatch
        nextvoice = (nextvoice + 1) & (blepvoices - 1);
        uint32_t x = 0;
        if (freq >> 24)
          x = (Osc_p - pwmp) / (freq >> 6);
        else if (freq)
          x = ((Osc_p - pwmp) << 6) / (freq);
        x = x > 0 ? x : -x;
        x = x & v13;
        Oscp[nextvoice] = &blept[x];
      }
    } else {
      if (((Osc_p - pwmp) > 0) && !((p - pwmp) > 0)) { // dispatch
        nextvoice = (nextvoice + 1) & (blepvoices - 1);
        uint32_t x = 0;
        if (freq >> 24)
          x = (Osc_p - pwmp) / (freq >> 6);
        else if (freq)
          x = ((Osc_p - pwmp) << 6) / (freq);
        x = x > 0 ? x : -x;
        x = x & v13;
        Oscp[nextvoice] = &blept[x];
      }
      if ((Osc_p > 0) && !(p > 0)) { // dispatch
        nextvoice = (nextvoice + 1) & (blepvoices - 1);
        int32_t x = 0;
        if (freq >> 24)
          x = Osc_p / (freq >> 6);
        else if (freq)
          x = (Osc_p << 6) / freq;
        x = x > 0 ? x : -x;
        x = x & v13;
        Oscp[nextvoice] = &blept[x];
        pwmp = ((1 << 27) + PWM) << 4;
      }
    }
    for (i = 0; i < blepvoices; i++) { // sample
      int16_t *t = Oscp[i];
      if (i & 1)
        sum += *t;
      else
        sum -= *t;
      t += 64;
      if (t >= lastblep)
        t = lastblep;
      Oscp[i] = t;
    }
    sum -= ((((nextvoice + 1) & 1) << 1) - 1) << 13;
    out[j] = sum << 13;
  }
}
Init
int j;
for (j = 0; j < blepvoices; j++) {
  oscp[j] = &blt[BLEPSIZE - 1];
  Oscp[j] = &blept[BLEPSIZE - 1];
  amp[j] = 0;
  i0 = 0;
}
nextvoice = 0;
Control Rate
for (i = 0; i < BUFSIZE; i++) {
  in[i] = inlet_mod[i];
  SNC[i] = inlet_sync[i];
  if (param_reverse > 0) {
    rev[i] = inlet_reverse[i] < 0 ? -1 : 1;
  } else {
    rev[i] = 1;
  }
}
MTOFEXTENDED(param_softsync + inlet_softsync, damp)
damp = damp >> 2;
hrm = inlet_hrm;
Div = inlet_div;
oct = inlet_oct;
hrm = hrm > 0 ? hrm : 1 - hrm;
Div = Div > 0 ? Div : 1 - Div;
int32_t wave = inlet_wave + param_wave;
wave = wave - wave / 5 * 5;
wave += wave < 0 ? 5 : 0;
int32_t self = param_self + inlet_self;
if (wave == 0) {
  SIN(inlet_pitch + param_pitch, param_mod, self);
}
if (wave == 1) {
  TRI(inlet_pitch + param_pitch, param_mod, self);
}
if (wave == 2) {
  SAW(inlet_pitch + param_pitch, param_mod, self);
}
if (wave == 3) {
  SQR(inlet_pitch + param_pitch, param_mod, self);
}
if (wave == 4) {
  PWM(inlet_pitch + param_pitch, param_mod, self);
}
for (i = 0; i < BUFSIZE; i++) {
  hp += out[i] - hp >> 10;
  out[i] -= hp;
  outlet_wave[i] = out[i];
}

Privacy

© 2024 Zrna Research