guitarOsc

"guitarOsc" -features pulsewidth, start-shift (start) and pick-up (mod) modulation, all extern controllable. (though these are all only approximations, reshaping the wavetable) below the continuous controls, we got "fixed" controls, even though you could change them live, this will create a bleep as it has to recalculate the waveform. -damp: dampening-factor for each next added harmonic corresponding to harmonic number. -harmonics: how many harmonics will be generated for the wavetable (low numbers reduce recalculation time!) -jump: "jump" size for next added harmonic, skipping harmonics in-between -max: sets maximum harmonic number that can be added, wraps when above the max. -position: sets the read-out position of the guitar-element -strike: sets the position where the string is struck
Author: Remco van der Most
License: BSD
Github: sss/osc/guitarOsc.axo

Inlets

frac32.bipolar pitch

frac32 pwm

frac32 mod

frac32 start

Outlets

frac32buffer.bipolar sine wave

Parameters

frac32.s.map.pitch pitch

frac32.u.map pwm

frac32.u.map mod

frac32.u.map start

frac32.u.map position

frac32.u.map strike

int32 damp

int32 harmonics

int32 jump

int32 max

Declaration
uint32_t phase;
int i;
int j;
int32_t sum;
int32_t r;
int32_t posWidth;
int32_t position;
int32_t prev;
int32_t array[2048];
int ctrig;
int create;
int32_t Pos;
int k;
int32_t start;
float32_t A;
float32_t B;
uint32_t PM;
Init
phase = 0;

for (i; i < 2048; i++) {
  array[i] = 0;
}
Control Rate
int32_t update = param_position + param_strike + param_damp + param_harmonics +
                 param_jump + param_max;

if ((!(prev == (update))) && !create) {
  create = 1;
  Pos = param_position;
  start = param_strike;
  for (i = 0; i < 2048; i++) {
    array[i] = 0;
  }
  for (j = 0; j < param_harmonics; j++) {
    k = (j * param_jump - (j * param_jump / param_max) * param_max);
    position = ((j + 1) * Pos << 4);
    SINE2TINTERP(position, posWidth)
    for (i = 0; i < 2048; i++) {
      SINE2TINTERP((i << 21) * (k + 1) - (start << 3) * (k + 1), r)
      array[i] += ___SMMUL(r >> 3, posWidth >> 3) / (1 + k * param_damp);
    }
  }
} else if (prev == (update)) {
  create = 0;
}

prev = update;

int32_t freq;
MTOFEXTENDED(param_pitch + inlet_pitch, freq)
PM = param_pwm + inlet_pwm;
PM = PM > 0 ? PM : -PM;
PM = PM & ((1 << 28) - 1);
PM = PM > (1 << 27) ? (2 << 27) - PM : PM;
PM = __USAT(PM + 1, 27) << 4;
A = ((float32_t)(1 << 31)) / ((float32_t)(PM << 1));
B = ((float32_t)(1 << 31)) / ((float32_t)(((1 << 31) - PM) << 1));
PM = PM << 1;
int32_t mod1 = param_mod + inlet_mod;
mod1 = mod1 > 0 ? mod1 : -mod1;
mod1 = mod1 & ((1 << 28) - 1);
mod1 = mod1 > (1 << 27) ? (2 << 27) - mod1 : mod1;
mod1 = mod1 << 4;
int32_t mod2;
mod2 = mod1 * 3;

int32_t Start = param_start + inlet_start;
Start = Start > 0 ? Start : -Start;
Start = Start & ((1 << 28) - 1);
Start = Start > (1 << 27) ? (2 << 27) - Start : Start;
Audio Rate
uint32_t Phase;
phase += freq;

uint32_t PHase = phase;
if (phase < (1 << 31)) {
  PHase = ___SMMUL(phase, Start << 4) << 2;
} else {
  PHase = (___SMMUL(phase, ((1 << 27) - Start) << 4) << 2);
}

if (PHase < PM) {
  Phase = (1 << 31) + ((int32_t)(PHase * A)) + mod1;
}
if (PHase >= PM) {
  Phase = ((uint32_t)((PHase - PM) * B - (1 << 31))) + mod1 + (1 << 31);
}

outlet_wave = array[(Phase >> 21) & 2047];

Privacy

© 2024 Zrna Research