multiWave

multi waveform oscilator: sine, triangle, saw, square each waveform (except sine) is able to change its shape (e.g. square = pwm).
Author: Beat Rossmy
License: BSD
Github: beat/osc/multiWave.axo

Inlets

frac32buffer phase increment

bool32.rising reset phase

int32.positive wave select

frac32.bipolar pitch

frac32.bipolar wave shaper

Outlets

frac32buffer.bipolar output

Parameters

int32.vradio sine, triangle, saw, square

frac32.s.map.pitch pitch

frac32.u.map changes shape of the selected waveform

frac32.u.map amount of shape

Declaration
static uint8_t const sin = 0;
static uint8_t const tri = 1;
static uint8_t const saw = 2;
static uint8_t const pwm = 3;

uint32_t phase;
int32_t phasor;
int32_t phaseCounter;
uint32_t r;
int32_t a;
int32_t b;
Init
phase = 0;
phasor = 0;
phaseCounter = 0;

r = 1;
a = 0;
b = 0;
Control Rate
uint32_t freq;
MTOFEXTENDED(param_pitch + inlet_pitch, freq);

int32_t shape;
shape = __USAT(param_shape + (___SMMUL(param_amount, inlet_shape) << 1), 27);

int32_t waveform;
waveform = (param_waveform + (inlet_wave >> 4)) % 4;
Audio Rate
/* reset phase if retriggered */
if (inlet_reset && r) {
  phase = 0;
  phaseCounter = 0;
  r = 0;
} else {
  if (!inlet_reset)
    r = 1;
  phase += (freq >> 0) + inlet_freq;
  /* if new phasor value is smaller then last one -> increment phaseCounter */
  a = phase >> 5;
  /* first or second phase cycle */
  if (a < phasor) {
    phaseCounter++;
    if (phaseCounter == 2)
      phaseCounter = 0;
  }
  /* set new phasor value */
  phasor = a;
}

/* calculate waveforms based on phasor value */
switch (waveform) {
case sin:
  /* phasor to sine */
  SINE2TINTERP(phasor << 5, a) /* calculate sine wave via function */
  outlet_out = (a >> 4);
  break;

case tri:
  /* phasor to triangle */
  b = (phasor > 0x07FFFFFF / 4)
          ? phasor - 0x07FFFFFF / 4
          : phasor +
                0x07FFFFFF / 4 * 3; /* phase shift to correct wave startpoint*/
  a = (b - (1 << 26))
      << 1; /* phasor to sawUp (bipolar) -> -a = sawDown (bipolar) */
  a = (a > 0) ? a : -a; /* merge sawUp and sawDown to triangle -> unipolar */
  a = (a - (1 << 26)) << 1; /* unipolar to bipolar */
  b = 0x07FFFFFF - (shape / 10 * 8);
  a = (a > b || a < -b) ? -a + ((a > 0) ? 2 : -2) * b
                        : a; /* param_shape threshold for wavefolding */
  outlet_out = a;
  break;

case saw:
  /* phasor to saw */
  b = (phasor > 0x07FFFFFF / 2)
          ? phasor - 0x07FFFFFF / 2
          : phasor + 0x07FFFFFF / 2; /* phase shift to correct wave startpoint*/
  a = (b - (1 << 26)) << 1;          /* phasor to sawUp (bipolar) */
  outlet_out = (phaseCounter == 1 && (phasor > 0x07FFFFFF / 2 - shape / 2 &&
                                      phasor < 0x07FFFFFF / 2 + shape / 2))
                   ? -a
                   : a;
  break;

case pwm:
  /* phasor to pulse width */
  outlet_out = (phasor >= 0x07FFFFFF / 2 + shape / 2)
                   ? -0x08000000
                   : 0x07FFFFFF; /* pulse width depending on shape value*/
  break;
}

Privacy

© 2024 Zrna Research