2DdualOsc

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) Or use my qSmRnd to randonly and smoothly step through the waveforms set by the quantizer. Both the internal oscillators can also choose between sine-wave or a wave from the table as their "base", non-morphing, waveform. This waveform is mixed out/in by the sinemix1/2 inlet's and knobs. The mix goes from 0 to 64 and is clipped to these values. The knobs can thus be used to offset a modulating signal. An "unlink" is provided between pitch1 and pitch2 to be able to send each oscillator its own (scaled) pitch-sequence
Author: Remco van der Most
License: BSD
Github: sss/osc/2DdualOsc.axo

Inlets

int32 waveform

int32 step

frac32buffer sync

frac32 pitch1

frac32 pitch2

frac32 FMW1

frac32 FMW2

frac32 mix1

frac32 mix2

frac32 sinemix1

frac32 sinemix2

frac32 wavemix

Outlets

frac32buffer out

int32 divide1

int32 divide2

Parameters

frac32.u.map mix1

frac32.u.map mix2

frac32.u.map wavemix

frac32.s.map.pitch pitch1

frac32.s.map.pitch pitch2

bool32.tgl HS

bool32.tgl SS

bool32.tgl unlink

bool32.tgl SW1

bool32.tgl SW2

int32 dampHS

int32 waveform

int32 W1

int32 quant1

int32 start1

int32 step1

int32 W2

int32 quant2

int32 start2

int32 step2

frac32.s.map FMW1

frac32.s.map FMW2

frac32.s.map sinemix1

frac32.s.map sinemix2

frac32.s.map AMmix

Attributes

objref table

Declaration
int32_t i;
int strig;
int Strig;
int STrig;
uint32_t phase1;
uint32_t phase2;
int trig;
int dir;
uint32_t cnt;
int32_t MIX1a;
int32_t MIX1b;
int32_t MIX2a;
int32_t MIX2b;

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 val1;
int32_t val2;
int32_t val3;
int32_t prev1;
int32_t prev2;
int32_t PREV;
uint32_t Phase2;
int32_t offset;
Init
prev1 = 0;
prev2 = 0;
dir = 1;
Control Rate
int32_t freq1;
MTOFEXTENDED(param_pitch1 + inlet_pitch1, freq1)
int32_t FMW1 = ___SMMUL(freq1 << 5, param_FMW1 + inlet_FMW1 << 3);
int32_t freq2;
MTOFEXTENDED((param_unlink > 0 ? 0 : param_pitch1 + inlet_pitch1) +
                 param_pitch2 + inlet_pitch2,
             freq2)

int32_t FMW2 = ___SMMUL(freq2 << 5, param_FMW2 + inlet_FMW2 << 3);
int32_t MiX1 = param_mix1 + inlet_mix1;
MX(MiX1);
MiX1 = F;
int32_t MiX2 = param_mix2 + inlet_mix2;
MX(MiX2);
MiX2 = F;

int32_t Q1 = param_W1 + param_waveform + inlet_waveform;
Q1 -= (Q1 / attr_table.Waveforms) * attr_table.Waveforms;
Q1 = Q1 * attr_table.LENGTH;
int32_t Q2 = param_W2 + param_waveform + inlet_waveform;
Q2 -= (Q2 / attr_table.Waveforms) * attr_table.Waveforms;
Q2 = Q2 * attr_table.LENGTH;
outlet_divide1 = param_quant1;
outlet_divide2 = param_quant2;
int32_t step1 = inlet_step + param_step1;
int32_t step2 = inlet_step + param_step2;

int32_t SiNe1 = __USAT(inlet_sinemix1 + param_sinemix1, 27);
int32_t step3 = SiNe1 - prev1 >> 4;
int32_t SINE1 = prev1;
prev1 = SiNe1;
int32_t SiNe2 = __USAT(inlet_sinemix2 + param_sinemix2, 27);
int32_t step4 = SiNe2 - prev2 >> 4;
int32_t SINE2 = prev2;
prev2 = SiNe2;

float32_t ratio = (float32_t)(attr_table.maxLvl) / 64;

MIX1a = MiX1;
MIX2a = MiX2;

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

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

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

int32_t wavemix = param_wavemix + inlet_wavemix;
MX(wavemix);
wavemix = F;
Audio Rate
SINE1 += step3;
SINE2 += step4;
if ((inlet_sync > 0) && !strig) {
  strig = 1;
  phase1 = 0;
  phase2 = 0;
} else if (inlet_sync < 0) {
  strig = 0;
}

if ((phase1 < (1 << 31)) && !STrig) {
  STrig = 1;
  if (param_HS > 0) {
    offset = (Phase2) - (0 << 31);
  }
  if (param_SS > 0) {
    dir = -dir;
  }
} else if ((phase1 > (1 << 31)) && STrig) {
  STrig = 0;
  if (param_SS > 0) {
    dir = -dir;
  }
}

val3 += offset - val3 >> param_dampHS;

phase1 += freq1 + ___SMMUL(FMW1 << 3, mix[1] << 2);
uint32_t p1 = (phase1 >> 32 - attr_table.LENGTHPOW);
uint32_t Mit = ((phase1 << attr_table.LENGTHPOW) >> 2) & 0x3FFFFFFF;
phase2 += (freq2 + ___SMMUL(FMW2 << 3, mix[0] << 2)) * dir;
Phase2 = phase2 - val3;
uint32_t p2 = (Phase2 >> 32 - attr_table.LENGTHPOW);
uint32_t MiT = ((Phase2 << attr_table.LENGTHPOW) >> 2) & 0x3FFFFFFF;
int32_t out1;
int32_t out2;
int32_t out3;
int32_t out4;
out1 = ___SMMUL(attr_table.array[p1 + W[0]] << 2, (1 << 30) - Mit);
out1 += ___SMMUL(
    attr_table.array[((p1 + 1) & attr_table.LENGTHMASK) + W[0]] << 2, Mit);
out2 = ___SMMUL(attr_table.array[p1 + W[1]] << 2, (1 << 30) - Mit);
out2 += ___SMMUL(
    attr_table.array[((p1 + 1) & attr_table.LENGTHMASK) + W[1]] << 2, Mit);
out3 = ___SMMUL(attr_table.array[p2 + W[2]] << 2, (1 << 30) - MiT);
out3 += ___SMMUL(
    attr_table.array[((p2 + 1) & attr_table.LENGTHMASK) + W[2]] << 2, MiT);
out4 = ___SMMUL(attr_table.array[p2 + W[3]] << 2, (1 << 30) - MiT);
out4 += ___SMMUL(
    attr_table.array[((p2 + 1) & attr_table.LENGTHMASK) + W[3]] << 2, MiT);

tablemix(0, out1, out2, MIX1a);
tablemix(1, out3, out4, MIX2a);

int32_t sine1;
int32_t sine2;
if (param_SW1 == 0) {
  SINE2TINTERP(phase1, sine1);
  sine1 = sine1 * ratio;
} else {
  sine1 = attr_table.array[p1 + Q1] << 4;
}
if (param_SW2 == 0) {
  SINE2TINTERP(phase2, sine2);
  sine2 = sine2 * ratio;
} else {
  sine2 = attr_table.array[p2 + Q2] << 4;
}

mix[0] = ___SMMUL(mix[0] << 2, SINE1 << 2) + ___SMMUL(sine1, (1 << 27) - SINE1);
mix[1] = ___SMMUL(mix[1] << 2, SINE2 << 2) +
         ___SMMUL((sine2)*ratio, (1 << 27) - SINE2);
val1 += (mix[0] - val1) >> 9;
val2 += (mix[1] - val2) >> 9;
mix[0] = mix[0] - val1;
mix[1] = mix[1] - val2;
int32_t AM = ___SMMUL(mix[0] << 3, mix[1] << 3);

outlet_out = ___SMMUL(mix[0] << 3, (1 << 27) - wavemix << 3) +
             ___SMMUL(mix[1] << 3, wavemix << 3) +
             ___SMMUL(AM << 3, param_AMmix << 3);

Privacy

© 2024 Zrna Research