ruby

An emulation of the eurorack rubicon oscillator with some extra waveforms and options INPUTS: pitch: well.. it's the pitch.. freq: linear thru-zero highpass-filtered FM audio input. FMS: select waveform for internal frequency modulation intFMW: adds to the width of the internal linear thru-zero FM. extFMW: connect an envelope of LFO to open up the external FM. HSon: switches hardsync to on when it receives a high gate. waveA: select waveform for osc 1 waveB: select waveform for osc 2 mix: select waveform for controlling the crossfade between osc 1 and osc2 EXTRA CONTROLS: sub: transposes the sub oscillator 1 octave FMW: controls the frequency modulation width-offset for the internal FM extFMW: controls the width of the incoming k-rate envelope/LFO on the extFMW input FMS: same as input waveA: same as input waveB: same as input mix: same as input pw: sets pulse width of pulse-waveform(9) LP: sets lowpass frequency HP: sets highpass frequency Hsync: manual control for syncing the oscillator to the "freq" input DISPLAYS the displays show the waveforms that are selected.
Author: Remco van der Most
License: BSD
Github: sss/osc/ruby.axo

Inlets

bool32 HSon

frac32 pitch

frac32 intLFM

frac32 extLFM

frac32 intEFM

frac32 extEFM

frac32buffer symmetry

frac32buffer phase increment

frac32buffer expFM

frac32buffer PWM

frac32buffer hsync

int32 lFMS

int32 eFMS

int32 waveA

int32 waveB

int32 mix

int32 tableform1

int32 tableform2

Outlets

frac32buffer out

Parameters

frac32.s.map.pitch pitch

frac32.s.map.pitch LP

frac32.s.map.pitch HP

frac32.s.map symmetry

frac32.s.map LFM

frac32.s.map extLFM

frac32.s.map EFM

frac32.s.map extEFM

frac32.s.map pw

int32.hradio sub

int32 lFMS

int32 eFMS

int32 waveA

int32 waveB

int32 mix

int32 tableform1

int32 tableform2

bool32.tgl Hsync

frac32.u.map digitalrate

Attributes

objref table

Displays

bool32 sine0

bool32 halfsine1

bool32 doublesine2

bool32 triangle3

bool32 saw4

bool32 doublesaw5

bool32 doubleshark6

bool32 doublefin7

bool32 square8

bool32 pulse9

bool32 sub10

bool32 table11

bool32 table12

bool32 white13

bool32 pink14

bool32 diginoise15

bool32 pulsenoise16

bool32 SHnoise17

bool32 SHdigital18

bool32 mixOut19

bool32 filtered20

Declaration
static const int noct = 7;
int32_t obuf[noct];
int32_t sum;
uint32_t seed;
int index;
const int8_t *dyadictree(void) {
  static const int8_t dtree[] = {
      0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1,
      0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2,
      0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1,
      0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3,
      0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1,
      0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, -1};
  return dtree;
}

uint32_t phase;
uint32_t Phase;
int32_t wave[21];
int select[21];
int i;
int32_t FM;
int32_t HP;
int32_t LP;
int32_t mix;
int htrig;
int32_t fmw1;
int32_t fmw2;
int32_t intFMW;
int32_t INTFMW;
int32_t rate;
int32_t cnt;
int ptrig;
int32_t symmetry;
Init
Phase = 0;

int i;
for (i = 0; i < noct; i++)
  obuf[i] = 0;
index = 0;
sum = 0;
seed = 0x830af41e + GenerateRandomNumber();
Control Rate
int waveA = __USAT(param_waveA + inlet_waveA, 8);
int waveB = __USAT(param_waveB + inlet_waveB, 8);
int MIX = __USAT(param_mix + inlet_mix, 8);
int FmS = __USAT(param_lFMS + inlet_lFMS, 8);
int fMS = __USAT(param_eFMS + inlet_eFMS, 8);
waveA = waveA - (waveA / 19) * 19;
waveB = waveB - (waveB / 19) * 19;
MIX = MIX - (MIX / 19) * 19;
FmS = FmS - (FmS / 21) * 21;
fMS = fMS - (fMS / 21) * 21;
waveA = waveA > 0 ? waveA : -waveA;
waveB = waveB > 0 ? waveB : -waveB;
MIX = MIX > 0 ? MIX : -MIX;
FmS = FmS > 0 ? FmS : -FmS;
fMS = fMS > 0 ? fMS : -fMS;

for (i = 0; i < 21; i++) {
  select[i] =
      ((waveA == i) + (waveB == i) + (MIX == i) + (FmS == i)) > 0 ? 1 : 0;
}

int32_t lp;
MTOF(param_LP, lp);

int32_t hp;
MTOF(param_HP, hp);

fmw1 = ___SMMUL(param_extLFM << 3, inlet_extLFM << 2);
INTFMW = param_LFM + inlet_intLFM;

disp_sine0 = select[0];
disp_halfsine1 = select[1];
disp_doublesine2 = select[2];
disp_triangle3 = select[3];
disp_saw4 = select[4];
disp_doublesaw5 = select[5];
disp_doubleshark6 = select[6];
disp_doublefin7 = select[7];
disp_square8 = select[8];
disp_pulse9 = select[9];
disp_sub10 = select[10];
disp_table11 = select[11];
disp_table12 = select[12];
disp_white13 = select[13];
disp_pink14 = select[14];
disp_diginoise15 = select[15];
disp_pulsenoise16 = select[16];
disp_SHnoise17 = select[17];
disp_SHdigital18 = select[18];
disp_mixOut19 = select[19];
disp_filtered20 = select[20];

int16_t tableform1 = (inlet_tableform1 + param_tableform1) & 1023;
int16_t tableform2 = (inlet_tableform2 + param_tableform2) & 1023;

int32_t rate = (1 << 27) - param_digitalrate;
rate = rate < 0 ? 0 : rate;
rate = ___SMMUL(rate << 3, rate << 2);
rate = ___SMMUL(rate << 3, rate << 2);
rate = rate >> 20;
Audio Rate
if (param_Hsync + inlet_HSon > 0) {
  if ((inlet_hsync > 0) && !htrig) {
    htrig = 1;
    phase = 0;
  } else if (inlet_hsync < 0) {
    htrig = 0;
  }
}

uint32_t freq;
MTOFEXTENDED(param_pitch + inlet_pitch +
                 ___SMMUL(param_extEFM << 3, inlet_expFM << 2) +
                 ___SMMUL(param_EFM << 3, wave[fMS] << 2),
             freq);
freq = (freq >> (1 + param_sub));

symmetry = param_symmetry + inlet_symmetry;
int32_t pw = (param_pw + inlet_PWM) << 4;
fmw2 = fmw2 + (((fmw1)-fmw2) >> 6);
intFMW = intFMW + (((INTFMW)-intFMW) >> 6);
int32_t Fm;
Fm = ___SMMUL(fmw2 << 4, inlet_linFM << 3) +
     ___SMMUL(intFMW << 4, (wave[FmS]) << 3);
FM = FM + ((Fm - FM) >> 9);
phase +=
    ___SMMUL(freq << 3, symmetry << 2) + ___SMMUL(freq << 3, (FM - Fm) << 2);

if (select[10] > 0) {
  int32_t sub = (phase + (1 << 29));
  sub = sub > 0 ? (1 << 26) : -(1 << 26);
  wave[10] = sub;
}

Phase = phase << (1 + param_sub);
int32_t Sphase = Phase + (1 << 30);
int32_t doublesaw;
doublesaw = Phase << 1;

if (select[0] > 0) {
  int32_t sine;
  SINE2TINTERP(Phase, sine)
  sine = sine >> 5;
  wave[0] = sine;
}

if (select[1] > 0) {
  int32_t sine;
  SINE2TINTERP((Sphase) >> 1, sine)
  sine = sine >> 5;
  wave[1] = sine;
}

if (select[2] > 0) {
  int32_t sine;
  SINE2TINTERP(Phase << 1, sine)
  sine = sine >> 5;
  wave[2] = sine;
}

if (select[9] > 0) {
  int32_t pulse;
  pulse = Sphase > (pw) ? (1 << 26) : -(1 << 26);
  wave[9] = pulse;
}

if (select[8] > 0) {
  int32_t square;
  square = Sphase > 0 ? (1 << 26) : -(1 << 26);
  wave[8] = square;
}

if (select[4] > 0) {
  int32_t saw = (Sphase + (1 << 31)) >> 5;
  wave[4] = saw;
}

if (select[6] > 0) {
  int32_t doublesharks =
      (doublesaw > 0 ? (1 << 31) - doublesaw : doublesaw) >> 5;
  wave[6] = doublesharks;
}

if (select[7] > 0) {
  int32_t doublefin = (doublesaw > 0 ? doublesaw : (1 << 31) - doublesaw) >> 5;
  wave[7] = doublefin;
}

if (select[5] > 0) {
  doublesaw = doublesaw >> 5;
  wave[5] = doublesaw;
}

if (select[3] > 0) {
  int32_t tri;
  tri = Sphase > 0 ? Sphase : -Sphase;
  tri = (tri - (1 << 30)) >> 4;
  wave[3] = tri;
}

if (select[11] > 0) {
  int32_t table;
  table = attr_table.array[(((Phase >> 22) & 1023) + (tableform1 << 10)) &
                           attr_table.LENGTHMASK];
  wave[11] = table;
}

if (select[12] > 0) {
  int32_t table;
  table = attr_table.array[(((Phase >> 22) & 1023) + (tableform2 << 10)) &
                           attr_table.LENGTHMASK];
  wave[12] = table;
}

if (select[13] > 0) {
  wave[13] = (int32_t)(GenerateRandomNumber()) >> 5;
}

if (select[14] > 0) {
  int o = dyadictree()[index++];
  if (o == -1) {
    index = 0;
  } else {
    sum -= obuf[o];
    seed = (seed * 196314165) + 907633515;
    obuf[o] = ((int32_t)seed) >> 7;
    sum += obuf[o];
  }
  seed = (seed * 196314165) + 907633515;
  wave[14] = sum + (((int32_t)seed) >> 7);
}

if (select[15] > 0) {
  cnt += 1;
  cnt = cnt > rate ? 0 : cnt;
  if (cnt == 0) {
    wave[15] = (int32_t)(GenerateRandomNumber()) >> 5;
  }
}

if (select[16] > 0) {
  cnt += 1;
  cnt = cnt > rate ? 0 : cnt;
  if (cnt == 0) {
    wave[16] = (int32_t)(GenerateRandomNumber()) > pw ? (1 << 26) : -(1 << 26);
  }
}

if ((Sphase > (1 << 30)) && (!(ptrig))) {
  ptrig = 1;
  if (select[17] > 0) {
    wave[17] = (int32_t)(GenerateRandomNumber()) >> 5;
  }
  if (select[18] > 0) {
    wave[18] = (int32_t)(GenerateRandomNumber()) > pw ? (1 << 26) : -(1 << 26);
  }
} else if (Sphase < (1 << 30)) {
  ptrig = 0;
}

mix = ___SMMUL(wave[waveA] << 3, (wave[MIX] + (1 << 26)) << 2) +
      ___SMMUL(wave[waveB] << 3, ((1 << 27) - (wave[MIX] + (1 << 26))) << 2);
wave[19] = mix;
HP = ___SMMLA((mix - HP) << 1, hp, HP);
LP = ___SMMLA((mix - HP - LP) << 1, lp, LP);

wave[20] = LP;
outlet_out = LP;

Privacy

© 2024 Zrna Research