hrmMorph

quad morphing sine oscillator morphs both through a scaled pitch (use scaleBank module from my harmony folder) as well as harmonic overtones. -use a triangle LFO or smoothed-out LFO to control the mix-inputs->morphs through the notes/harmonics. -noteQuant and hrmQuant set the amount of pitches/harmonics that will be played when mix goes from zero to max. -hrm/noteStep sets the stepsize of each next played note/harmonic. -noteRepeat wraps the note-count, making it repeat after the set amount of steps. For the notes, you have 2 patterns which are added together before being "ranged" between minimum (zero) and maximum (noteRange). -jump sets the offset size that will be added to the note each time the repeat wraps the count. -hrm/noteRange sets the maximum range for the harmonics/notes.
Author: Remco van der Most
License: BSD
Github: sss/osc/hrmMorph.axo

Inlets

frac32buffer freq

frac32 noteMix

frac32 hrmMix

int32 pitch

int32 key

int32 scale

int32 noteStep1

int32 noteStep2

int32 noteJump1

int32 noteJump2

int32 hrmStep

int32 wavestart

int32 wavestep1

int32 wavestep2

int32 wavestep3

int32 wavestep4

Outlets

frac32buffer.bipolar sine wave

int32.bipolar nDiv

int32.bipolar hDiv

Parameters

frac32.u.map noteMix

frac32.u.map hrmMix

frac32.s.map.pitch pitch

frac32.s.map detune

int32 noteStep1

int32 noteQuant

int32 noteRepeat1

int32 jump1

int32 noteStep2

int32 noteRepeat2

int32 jump2

int32 noteRange

int32 hrmStep

int32 hrmQuant

int32 hrmRange

int32 wavestart

int32 wavestep1

int32 wavestep2

int32 wavestep3

int32 wavestep4

Attributes

objref scale

objref table

Declaration
uint32_t Phase1;
uint32_t Phase2;
int32_t P[6];
int32_t J[4];
int32_t T[4];
int64_t MIX1;
int64_t MIX2;
int32_t mix[3];

int32_t sinemix(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 F;
int32_t MX(int32_t T) {
  T = T > 0 ? T : -T;
  T = T & ((1 << 28) - 1);
  F = T > (1 << 27) ? (1 << 28) - T : T;
}
Init
Phase1 = 0;
Phase2 = 0;
Control Rate
int32_t freq1;
int32_t freq2;
int key = inlet_key - 4;
key = key - (key / 12) * 12;
key = key < 0 ? key + 12 : key;
int Scale = inlet_scale;
Scale = Scale - (Scale / 46) * 46;
Scale = Scale < 0 ? Scale + 46 : Scale;

MIX1 = param_hrmMix + inlet_hrmMix;
MX(MIX1);
MIX1 = F;
MIX2 = param_noteMix + inlet_noteMix;
MX(MIX2);
MIX2 = F;

int64_t hrmQuant = param_hrmQuant;
int64_t noteQuant = param_noteQuant;

P[0] = ((((MIX1 * hrmQuant) >> 27) + 1) >> 1) << 1;
P[1] = (((MIX1 * hrmQuant) >> 28) << 1) + 1;
MIX1 = (MIX1 - (((MIX1 * hrmQuant) >> 28) << 28) / hrmQuant) * hrmQuant;
MIX1 = MIX1 > (1 << 27) ? ((1 << 28) - MIX1) : MIX1;
T[0] = P[0];
T[1] = P[1];
P[0] = P[0] * (param_hrmStep + inlet_hrmStep);
P[1] = P[1] * (param_hrmStep + inlet_hrmStep);
P[0] = P[0] - (P[0] / param_hrmRange) * param_hrmRange + 1;
P[1] = P[1] - (P[1] / param_hrmRange) * param_hrmRange + 1;

P[2] = ((((MIX2 * noteQuant) >> 27) + 1) >> 1) << 1;
P[3] = (((MIX2 * noteQuant) >> 28) << 1) + 1;
MIX2 = (MIX2 - (((MIX2 * noteQuant) >> 28) << 28) / noteQuant) * noteQuant;
MIX2 = MIX2 > (1 << 27) ? ((1 << 28) - MIX2) : MIX2;
P[4] = P[2];
P[5] = P[3];
T[2] = P[2];
T[3] = P[3];
J[0] = P[2] / param_noteRepeat1;
J[1] = P[3] / param_noteRepeat1;
J[2] = P[4] / param_noteRepeat2;
J[3] = P[5] / param_noteRepeat2;
P[4] = P[4] * (param_noteStep2 + inlet_noteStep2);
P[5] = P[5] * (param_noteStep2 + inlet_noteStep2);
P[2] = P[2] * (param_noteStep1 + inlet_noteStep1);
P[3] = P[3] * (param_noteStep1 + inlet_noteStep1);

P[2] = P[2] - (P[2] / param_noteRepeat1) * param_noteRepeat1;
P[3] = P[3] - (P[3] / param_noteRepeat1) * param_noteRepeat1;
P[4] = P[4] - (P[4] / param_noteRepeat2) * param_noteRepeat2;
P[5] = P[5] - (P[5] / param_noteRepeat2) * param_noteRepeat2;

P[2] += J[0] * (param_jump1 + inlet_noteJump1) + P[4] +
        J[2] * (param_jump2 + inlet_noteJump2);
P[3] += J[1] * (param_jump1 + inlet_noteJump1) + P[5] +
        J[3] * (param_jump2 + inlet_noteJump2);

P[2] = P[2] - (P[2] / param_noteRange) * param_noteRange;
P[3] = P[3] - (P[3] / param_noteRange) * param_noteRange;

T[0] = T[0] * (param_wavestep1 + inlet_wavestep1);
T[1] = T[1] * (param_wavestep2 + inlet_wavestep2);
T[2] = T[2] * (param_wavestep3 + inlet_wavestep3);
T[3] = T[3] * (param_wavestep4 + inlet_wavestep4);

outlet_nDiv = param_noteQuant;
outlet_hDiv = param_hrmQuant;

int32_t pitch1 = inlet_pitch + P[2];
int32_t octave1 = pitch1 / 12 - (pitch1 < 0 ? 1 : 0);
int32_t semitone1 = pitch1 - octave1 * 12;
int32_t note1 = (attr_scale.note[semitone1 + Scale * 12] + octave1 * 12 + key)
                << 21;

int32_t pitch2 = inlet_pitch + P[3];
int32_t octave2 = pitch2 / 12 - (pitch2 < 0 ? 1 : 0);
int32_t semitone2 = pitch2 - octave2 * 12;
int32_t note2 = (attr_scale.note[semitone2 + Scale * 12] + octave2 * 12 + key)
                << 21;

MTOFEXTENDED(note1 + param_pitch, freq1);
MTOFEXTENDED(note2 + param_pitch, freq2);
int32_t preset = (param_wavestart + inlet_wavestart) * 1024;
Audio Rate
Phase1 += freq1 + ___SMMUL(freq1 << 3, inlet_freq << 2);
Phase2 += freq2 + ___SMMUL(freq2 << 3, inlet_freq << 2) + (param_detune >> 10);
int32_t r1a;
int32_t r2a;
int32_t r1b;
int32_t r2b;
// SINE2TINTERP(Phase1*P[0],r1a)
// SINE2TINTERP(Phase1*P[1],r1b)
// SINE2TINTERP(Phase2*P[0],r2a)
// SINE2TINTERP(Phase2*P[1],r2b)
r1a =
    attr_table
        .array[(((Phase1 * P[0] >> 22) & 1023) + preset + (T[0] + T[2] << 10)) &
               attr_table.LENGTHMASK];
r1b =
    attr_table
        .array[(((Phase1 * P[1] >> 22) & 1023) + preset + (T[1] + T[2] << 10)) &
               attr_table.LENGTHMASK];
r2a =
    attr_table
        .array[(((Phase2 * P[0] >> 22) & 1023) + preset + (T[0] + T[3] << 10)) &
               attr_table.LENGTHMASK];
r2b =
    attr_table
        .array[(((Phase2 * P[1] >> 22) & 1023) + preset + (T[1] + T[3] << 10)) &
               attr_table.LENGTHMASK];
// sinemix(0,(r1a/P[0]),(r1b/P[1]),MIX1);
// sinemix(1,(r2a/P[0]),(r2b/P[1]),MIX1);
sinemix(0, (r1a), (r1b), MIX1);
sinemix(1, (r2a), (r2b), MIX1);
sinemix(2, mix[0], mix[1], MIX2);
outlet_wave = mix[2] * 3 >> 2;

Privacy

© 2024 Zrna Research