2Dtablemorph

2D wavetable morph oscillator. This oscillator uses the waveformGenerator module for generating it's waveforms. With the mix-inputs/knobs, you morph through the different waveforms. -quant sets the amount of waveforms that will be morphed through when mix goes from minimum to maximum. -start sets the start-position in the table when mix is at zero -step sets the step-size through the table, skipping in-between waveforms (wrapping back to 0 when above maximum available waveforms) For easy use, use my qtsLFO4 for controlling the mix. Connect the divide-output to the D-input (divide) of the qtsLFO4. When using saw/ramp, set it to bipolar, as the input is wrapped up/back down again when the input is below 0 or above 64 (turning it into a triangle-shape)
Author: Remco van der Most
License: BSD
Github: sss/osc/2Dtablemorph.axo

Inlets

int32 step

frac32 pitch

frac32 mix1

frac32 mix2

frac32buffer FM

frac32buffer sync

Outlets

frac32buffer out

int32 divide1

int32 divide2

Parameters

frac32.s.map.pitch pitch

frac32.s.map FMW

frac32.u.map mix1

frac32.u.map mix2

int32 quant1

int32 start1

int32 step1

int32 quant2

int32 start2

int32 step2

Attributes

objref table

Declaration
int32_t i;
int strig;

uint32_t phase;
int trig;

int32_t MIX1a;
int32_t MIX1b;
int32_t MIX2a;
int32_t MIX2b;
int32_t smooth1;
int32_t smooth2;
uint32_t W[4];
uint32_t w[4];
int32_t F;
int32_t mix[2];
int32_t MX(int32_t T) {
  T = T > 0 ? T : -T;
  T = T & ((1 << 28) - 1);
  F = T > (1 << 27) ? (1 << 28) - T : T;
}

int32_t tablemix(int32_t inst, int32_t WaveA, int32_t WaveB, int32_t Mix) {
  mix[inst] = ___SMMUL(((1 << 27) - Mix) << 3, WaveA << 2) +
              ___SMMUL(Mix << 3, WaveB << 2);
}
int32_t M1step;
int32_t M1prv;
int32_t M2step;
int32_t M2prv;
int32_t out;
Control Rate
int32_t freq;
MTOFEXTENDED(param_pitch + inlet_pitch, freq)
int32_t FMW = ___SMMUL(freq << 7, param_FMW << 4);
int32_t MiX1 = param_mix1 + inlet_mix1;
MX(MiX1);
MiX1 = F;
int32_t MiX2 = param_mix2 + inlet_mix2;
MX(MiX2);
MiX2 = F;
smooth1 += (MiX1 - smooth1) >> 4;
MiX1 = smooth1;
smooth2 += (MiX2 - smooth2) >> 4;
MiX2 = smooth2;
M1step = (MiX1 - M1prv) >> 4;
int32_t MIX1b = M1prv;
M1prv = MiX1;
M2step = (MiX2 - M2prv) >> 4;
int32_t MIX2b = M2prv;
M2prv = MiX2;

outlet_divide1 = param_quant1;
outlet_divide2 = param_quant2;
int32_t step1 = inlet_step + param_step1;
int32_t step2 = inlet_step + param_step2;
Audio Rate
if ((inlet_sync > 0) && !strig) {
  strig = 1;
  phase = 0;
} else if (inlet_sync == 0) {
  strig = 0;
}
MIX1b += M1step;
MIX1a = MIX1b;
MIX2b += M2step;
MIX2a = MIX2b;

W[0] = ((MIX1a >> 4) * param_quant1) >> 23;
MIX1a = (MIX1a - (W[0] << 27) / param_quant1) * param_quant1;
W[0] += param_start1;
W[0] = W[0] * step1;
W[1] = W[0] + step1;

W[2] = ((MIX2a >> 4) * param_quant2) >> 23;
MIX2a = (MIX2a - (W[2] << 27) / param_quant2) * param_quant2;
W[2] += param_start2;
W[2] = W[2] * step2;
W[3] = W[2] + step2;

for (i = 0; i < 4; i++) {
  W[i] = (W[i] - (W[i] / attr_table.Waveforms) * attr_table.Waveforms);
  W[i] = W[i] < 0 ? W[i] + attr_table.Waveforms : W[i];
}

w[0] = W[0] + W[2];
w[1] = W[1] + W[2];
w[2] = W[0] + W[3];
w[3] = W[1] + W[3];

for (i = 0; i < 4; i++) {
  w[i] = (w[i] - (w[i] / attr_table.Waveforms) * attr_table.Waveforms);
  w[i] = w[i] < 0 ? w[i] + attr_table.Waveforms : w[i];
  w[i] = w[i] * attr_table.LENGTH;
}

phase += freq + ___SMMUL(FMW << 3, inlet_FM << 2);
uint32_t p1 = (phase >> 32 - attr_table.LENGTHPOW) & attr_table.LENGTHMASK;
int32_t out1;
int32_t out2;
int32_t out3;
int32_t out4;
out1 = attr_table.array[p1 + w[0]];
out2 = attr_table.array[p1 + w[1]];
out3 = attr_table.array[p1 + w[2]];
out4 = attr_table.array[p1 + w[3]];
tablemix(0, out1, out2, MIX1a);
tablemix(1, out3, out4, MIX1a);
tablemix(0, mix[0], mix[1], MIX2a);
out += (mix[0] - out) >> 10;
outlet_out = mix[0] - out;

Privacy

© 2024 Zrna Research