modstation

mod of an object by dr.j added an envelope as sixth option. removed some other stuff.
Author: Robert Schirmer
License: BSD
Github: rbrt/lfo/modstation.axo

Inlets

int32.bipolar Waveform, added to wave parameter

bool32.rising Reset phase

bool32.risingfalling gate

frac32.positive attack

frac32.positive decay

frac32.bipolar Pitch input

Outlets

frac32 Output

bool32 state

Parameters

frac32.s.map.lfopitch Pitch

bool32.tgl Unipolar output

int32 1-5 = tri, sine, saw+, saw-, square

frac32.u.map attack

frac32.u.map decay

Attributes

spinner ascale

spinner dscale

Declaration
uint32_t phase;
int32_t old_reset;

__attribute__((always_inline)) __STATIC_INLINE int32_t ___ABS(int32_t op1) {
  int32_t result;
  __ASM volatile("movs  %0, %1\n"
                 "it    mi\n"
                 "rsbmi %0, %0, #0"
                 : "=r"(result)
                 : "r"(op1));
  return (result);
};

int32_t val;
Init
phase = 0;
old_reset = 0;
Control Rate
if (inlet_reset && !old_reset) {
  phase = 0;
} else {
  int32_t pitch;
  pitch = param_pitch + inlet_pitch;
  if (pitch > 0x07FFFFFF)
    pitch = 0x07FFFFFF;
  // pitch = __SSAT( pitch, 28 );
  MTOFEXTENDED(pitch, pitch);
  phase += pitch >> 2;
}
old_reset = inlet_reset;

uint32_t phase1 = phase;

switch (param_wave + inlet_wave) {
default:
case 1:
  // Sine
  SINE2TINTERP(phase1, outlet_out)
  outlet_out = (outlet_out >> 5) + (1 << 26);
  break;
case 2:
  // Triangle
  outlet_out = (phase1 >> 4) - (1 << 27);
  outlet_out = (1 << 27) - ___ABS(outlet_out);
  break;
case 3:
  // Saw rising
  outlet_out = (phase1 >> 5);
  break;
case 4:
  // Saw falling
  outlet_out = (1 << 27) - (phase1 >> 5);
  break;
case 5:
  // Square
  outlet_out = ((phase1 >> 5) > (1 << 26)) ? 0 : (1 << 27) - 1;
  break;
case 6:
  // linear envelope
  if (inlet_gate > 0) {
    int32_t t;
    MTOF(-(inlet_attack + param_attack), t);
    val += (inlet_attack + param_attack) ? t >> attr_ascale : 1 << 27;
  } else {
    int32_t t;
    MTOF(-(inlet_decay + param_decay), t);
    val -= t >> attr_dscale;
  }
  val = __USAT(val, 27);
  outlet_out = val;
  outlet_state = val;
  break;
}

if (!param_unipolar) {
  outlet_out = (outlet_out << 1) - (1 << 27);
}

outlet_out = __SSAT(___SMMUL((1 << 27) << 3, outlet_out << 2), 28);

Privacy

© 2024 Zrna Research