tabletrain

This module uses the wavetables created with the wavetableGenerator and guitartable modules. "mixWave" morphs through different waveforms. "stepWave" and "startWave" set the stepsize and startposition of the morph within the available waveforms in the table. "quant" sets the amount of waveforms that will be morphed through when mixWave goes from zero to max (returns to start-wave when at max. so can be driven with a saw-LFO). Next to "low-frequency" "mixWave" morphing, there is also a high-frequency morph, controlled by the phase-position of the oscillator. The phase is used to morph from one wave to the next, taking a new "goal" waveform when phase restarts. This way up to 64 waveforms can be played consecutively. "train" sets the amount of waveforms that will be played. "harm" multiplies the phase that is used for the train-morphing. Setting these two to different values will create frequency-ratios based on root frequency. "mult" multiplies the phase with the "train" value, keeping the rootnote the same when changing the amount of train-waveforms.
Author: Remco van der Most
License: BSD
Github: sss/osc/tabletrain.axo

Inlets

frac32 pitch

frac32 mixWave

frac32 stepWave

frac32 startWave

frac32 stepTrain

int32 harm

int32 train

Outlets

frac32buffer out

int32 div

Parameters

int32 harm

int32 preset

int32 train

int32 stepTrain

frac32.u.map mixWave

frac32.u.map stepWave

frac32.u.map startWave

frac32.u.map quant

frac32.s.map.pitch pitch

bool32.tgl mult

Attributes

objref table

Declaration
uint32_t phase;
int32_t tmp_r;
int32_t osc(uint32_t PHASE, uint32_t PRESET) {
  uint32_t tmp_di = (PHASE >> 32 - attr_table.LENGTHPOW);
  uint32_t tmp_w1 = (PHASE << (attr_table.LENGTHPOW)) >> 2;
  uint32_t tmp_w2 = (1 << 30) - tmp_w1;
  int32_t tmp_a1 = attr_table.array[(tmp_di & attr_table.LENGTHMASK) + PRESET];
  int32_t tmp_a2 =
      attr_table.array[((tmp_di + 1) & attr_table.LENGTHMASK) + PRESET];
  tmp_r = ___SMMUL(tmp_a1 << 2, tmp_w1);
  tmp_r = ___SMMLA(tmp_a2 << 2, tmp_w2, tmp_r);
}
uint32_t prev;
uint32_t Preset1;
uint32_t Preset2;
uint32_t PReset1;
uint32_t PReset2;
uint32_t Preset3;
uint32_t Preset4;
uint32_t preset;
uint32_t W[2];
int i;
int32_t mix;
int32_t tablemix(int32_t WaveA, int32_t WaveB, int32_t Mix) {
  mix = ___SMMUL(((1 << 27) - Mix) << 3, WaveA << 2) +
        ___SMMUL(Mix << 3, WaveB << 2);
}
Control Rate
int32_t freq;
MTOFEXTENDED(param_pitch + inlet_pitch, freq)

int harm = param_harm + inlet_harm;

int32_t quant1 = (param_quant >> 21) + 1;
int32_t MIX1a = inlet_mixWave + param_mixWave;
MIX1a = MIX1a & ((1 << 27) - 1);

float32_t step = ((float32_t)(attr_table.Waveforms)) / (quant1) *
                 ((inlet_stepWave + param_stepWave) / (1 << 21));
outlet_div = quant1;
int start =
    ___SMMUL(param_startWave + inlet_startWave << 3, attr_table.Waveforms << 2);
W[0] = ((MIX1a >> 4) * quant1) >> 23;
MIX1a = (MIX1a - (W[0] << 27) / quant1) * quant1;
W[1] = W[0] * step + start + step;
W[0] = W[0] * step + start;

for (i = 0; i < 2; 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];
}
int32_t train = param_train + inlet_train;
harm = param_mult > 0 ? harm *train : harm;
Audio Rate
phase += freq;
uint32_t Phase = phase * harm;
if (prev > Phase) {
  preset += 1;
  preset = preset - preset / train * train;
  PReset1 = preset;
  PReset2 = PReset1 + 1;
  PReset2 = PReset2 - PReset2 / train * train;
  PReset1 = param_preset + PReset1 * param_stepTrain;
  PReset2 = param_preset + PReset2 * param_stepTrain;
}

Preset3 = PReset1 + W[1];
Preset4 = PReset2 + W[1];
Preset1 = PReset1 + W[0];
Preset2 = PReset2 + W[0];
Preset1 = Preset1 - Preset1 / attr_table.Waveforms * attr_table.Waveforms;
Preset1 = Preset1 * attr_table.LENGTH;
Preset2 = Preset2 - Preset2 / attr_table.Waveforms * attr_table.Waveforms;
Preset2 = Preset2 * attr_table.LENGTH;
Preset3 = Preset3 - Preset3 / attr_table.Waveforms * attr_table.Waveforms;
Preset3 = Preset3 * attr_table.LENGTH;
Preset4 = Preset4 - Preset4 / attr_table.Waveforms * attr_table.Waveforms;
Preset4 = Preset4 * attr_table.LENGTH;
osc(phase, Preset1);
int32_t out1 = tmp_r;
osc(phase, Preset2);
int32_t out2 = tmp_r;
out1 = ___SMMUL((1 << 30) - (Phase >> 2), out1 << 2) +
       ___SMMUL(Phase >> 2, out2 << 2);
osc(phase, Preset3);
out2 = tmp_r;
osc(phase, Preset4);
out2 = ___SMMUL((1 << 30) - (Phase >> 2), out2 << 2) +
       ___SMMUL(Phase >> 2, tmp_r << 2);
tablemix(out1, out2, MIX1a);
outlet_out = mix;
prev = Phase;

Privacy

© 2024 Zrna Research