CR1

ROOT sets the base frequency from where the pitch offsets are calculated OFS sets a frequency offset to the root pitch, functioning as a frequency shifter (remember Bode?). SPREAD sets an extra offset for each next oscillator pitch (harmonic spreading). ROTATE shifts the frequencies around, following a sine pattern. Stepsize is set by primes. HIT sets attack rate D1 sets start part of the decay rate (short, spikey hits or more "Boings") D2 sets the end part of the decay rate as the decay reaches zero. Use this to shorten the sound or lengthen it (also depends on D1, which can force the decay down pretty easily) CRASH sets the FM width between the 6 internal oscillators, creating lots of extra harmoncis up to metallic noise. INFLUENCE sets the influence of the envelope. MODE (unused yet, leave this to zero!) will control several different FM routings.
Author: Remco van der Most
License: BSD
Github: sss/edrum/CR1.axo

Inlets

bool32.rising gate

frac32 root

frac32 ofs

frac32 spread

frac32 rotate

frac32 decay

frac32 crash

frac32 influence

bool32 rndFM

Outlets

frac32buffer out

Parameters

frac32.s.map.pitch root

frac32.s.map.pitch ofs

frac32.s.map spread

frac32.s.map rotate

frac32.s.map crash

frac32.s.map influence

frac32.u.map hit

frac32.s.map.kdecaytime.exp d1

frac32.s.map.kdecaytime.exp d2

int32.hradio mode

Declaration
uint32_t phase1;
uint32_t phase2;
uint32_t phase3;
uint32_t phase4;
uint32_t phase5;
uint32_t phase6;
int32_t sum;

int8_t stage1;
int8_t stage2;
int ntrig1;
int32_t val1;
int ntrig2;
int32_t val2;
int64_t ccomp;
int64_t decay;
int64_t ENV1;
int32_t Ph1;
int32_t Ph2;
int32_t Ph3;
int32_t Ph4;
int32_t Ph5;
int32_t Ph6;
int32_t FM1;
int32_t FM2;
int32_t FM3;
int32_t FM4;
int32_t FM5;
int32_t FM6;
int32_t X1;
int32_t X2;
int32_t X3;
int32_t X4;
int32_t X5;
int32_t X6;
int32_t sane[6];
int32_t sone[6];
int gtrig;
int rnd[12];
int i;
Control Rate
int32_t offset;
MTOF(param_ofs + inlet_ofs, offset)
int32_t root;
MTOF(param_root + inlet_root, root)
int32_t spread;
MTOF(param_spread + inlet_spread, spread)

int32_t t;
MTOF((1 << 27) - param_hit, t);
int32_t msine2;
int32_t msine3;
int32_t msine4;
int32_t msine5;
int32_t msine6;
SINE2TINTERP((param_rotate + inlet_rotate) << 3, msine2)
SINE2TINTERP(((param_rotate + inlet_rotate) * 17) << 2, msine3)
SINE2TINTERP(((param_rotate + inlet_rotate) * 23) << 2, msine4)
SINE2TINTERP(((param_rotate + inlet_rotate) * 29) << 2, msine5)
SINE2TINTERP(((param_rotate + inlet_rotate) * 31) << 2, msine6)
MTOF(msine2 >> 5, msine2)
MTOF(msine3 >> 5, msine3)
MTOF(msine4 >> 5, msine4)
MTOF(msine5 >> 5, msine5)
MTOF(msine6 >> 5, msine6)

if ((inlet_rndFM > 0) & (!(gtrig))) {
  gtrig = 1;
  for (i = 0; i < 12; i++) {
    rnd[i] = (int32_t)(GenerateRandomNumber() % (6));
  }
} else if (!(inlet_rndFM > 0)) {
  gtrig = 0;
}
Audio Rate
// envelope

ccomp = (1 << 31) - val1;
decay = param_d2 - param_d1 + inlet_decay;
decay = ___SMMUL(val1 >> 1, decay << 2);

if ((inlet_gate > 0) && !ntrig1) {
  ntrig1 = 1;
  stage1 = 1;
} else if (!(inlet_gate > 0)) {
  ntrig1 = 0;
}
if (stage1 == 0) {
  val1 = ___SMMUL(val1, param_d1 + decay + (1 << 18) + (1 << 16)) << 1;
} else {

  val1 = val1 + (t >> 7);
  if (val1 < 0) {
    val1 = 0x7FFFFFFF;
    stage1 = 0;
  }
}
ENV1 = val1 >> 4;

Ph1 = root + offset;
Ph2 = root - offset + spread + msine2;
Ph3 = root + offset - spread + msine3;
Ph4 = root + offset + spread * 3 + msine4;
Ph5 = root - offset - spread * 2 + msine5;
Ph6 = root - offset + spread * 5 + msine6;

int32_t crash =
    param_crash + inlet_crash +
    ___SMMUL(((1 << 27) - ENV1) << 3, (inlet_influence + param_influence) << 2);
FM1 = ___SMMUL(crash << 3, Ph1);
FM2 = ___SMMUL(crash << 3, Ph2);
FM3 = ___SMMUL(crash << 3, Ph3);
FM4 = ___SMMUL(crash << 3, Ph4);
FM5 = ___SMMUL(crash << 3, Ph5);
FM6 = ___SMMUL(crash << 3, Ph6);

// phase oscillators
phase1 += Ph1 + ___SMMUL(FM1 << 5, X1);
phase2 += Ph2 + ___SMMUL(FM2 << 5, X2);
phase3 += Ph3 + ___SMMUL(FM3 << 5, X3);
phase4 += Ph4 + ___SMMUL(FM4 << 5, X4);
phase5 += Ph5 + ___SMMUL(FM5 << 5, X5);
phase6 += Ph6 + ___SMMUL(FM6 << 5, X6);

// sine interpret
int32_t sine1;
int32_t sine2;
int32_t sine3;
int32_t sine4;
int32_t sine5;
int32_t sine6;
SINE2TINTERP(phase1, sine1)
SINE2TINTERP(phase2, sine2)
SINE2TINTERP(phase3, sine3)
SINE2TINTERP(phase4, sine4)
SINE2TINTERP(phase5, sine5)
SINE2TINTERP(phase6, sine6)
sum = (sine1 >> 8) + (sine2 >> 8) + (sine3 >> 8) + (sine4 >> 8) + (sine5 >> 8) +
      (sine6 >> 8);
outlet_out = ___SMMUL(sum << 3, ENV1 << 3);

switch (param_mode > 0 ? param_mode : 0) {
case 0:
  X1 = sine6;
  X2 = sine1;
  X3 = sine2;
  X4 = sine3;
  X5 = sine4;
  X6 = sine5;
  break;
case 1:
  sane[0] = sine1;
  sane[1] = sine2;
  sane[2] = sine3;
  sane[3] = sine4;
  sane[4] = sine5;
  sane[5] = sine6;

  sone[rnd[1]] = sane[rnd[0]];
  sone[rnd[3]] = sane[rnd[2]];
  sone[rnd[5]] = sane[rnd[4]];
  sone[rnd[7]] = sane[rnd[6]];
  sone[rnd[9]] = sane[rnd[8]];
  sone[rnd[11]] = sane[rnd[10]];

  X1 = sone[0];
  X2 = sone[1];
  X3 = sone[2];
  X4 = sone[3];
  X5 = sone[4];
  X6 = sone[5];
  break;
}

Privacy

© 2024 Zrna Research